LyoKICogUGVyZm9ybWFuY2UgZXZlbnRzIGNvcmUgY29kZToKICoKICogIENvcHlyaWdodCAoQykgMjAwOCBUaG9tYXMgR2xlaXhuZXIgPHRnbHhAbGludXRyb25peC5kZT4KICogIENvcHlyaWdodCAoQykgMjAwOC0yMDA5IFJlZCBIYXQsIEluYy4sIEluZ28gTW9sbmFyCiAqICBDb3B5cmlnaHQgKEMpIDIwMDgtMjAwOSBSZWQgSGF0LCBJbmMuLCBQZXRlciBaaWpsc3RyYSA8cHppamxzdHJAcmVkaGF0LmNvbT4KICogIENvcHlyaWdodCAgqSAgMjAwOSBQYXVsIE1hY2tlcnJhcywgSUJNIENvcnAuIDxwYXVsdXNAYXUxLmlibS5jb20+CiAqCiAqIEZvciBsaWNlbnNpbmcgZGV0YWlscyBzZWUga2VybmVsLWJhc2UvQ09QWUlORwogKi8KCiNpbmNsdWRlIDxsaW51eC9mcy5oPgojaW5jbHVkZSA8bGludXgvbW0uaD4KI2luY2x1ZGUgPGxpbnV4L2NwdS5oPgojaW5jbHVkZSA8bGludXgvc21wLmg+CiNpbmNsdWRlIDxsaW51eC9pZHIuaD4KI2luY2x1ZGUgPGxpbnV4L2ZpbGUuaD4KI2luY2x1ZGUgPGxpbnV4L3BvbGwuaD4KI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KI2luY2x1ZGUgPGxpbnV4L2hhc2guaD4KI2luY2x1ZGUgPGxpbnV4L3N5c2ZzLmg+CiNpbmNsdWRlIDxsaW51eC9kY2FjaGUuaD4KI2luY2x1ZGUgPGxpbnV4L3BlcmNwdS5oPgojaW5jbHVkZSA8bGludXgvcHRyYWNlLmg+CiNpbmNsdWRlIDxsaW51eC9yZWJvb3QuaD4KI2luY2x1ZGUgPGxpbnV4L3Ztc3RhdC5oPgojaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+CiNpbmNsdWRlIDxsaW51eC92bWFsbG9jLmg+CiNpbmNsdWRlIDxsaW51eC9oYXJkaXJxLmg+CiNpbmNsdWRlIDxsaW51eC9yY3VsaXN0Lmg+CiNpbmNsdWRlIDxsaW51eC91YWNjZXNzLmg+CiNpbmNsdWRlIDxsaW51eC9zeXNjYWxscy5oPgojaW5jbHVkZSA8bGludXgvYW5vbl9pbm9kZXMuaD4KI2luY2x1ZGUgPGxpbnV4L2tlcm5lbF9zdGF0Lmg+CiNpbmNsdWRlIDxsaW51eC9wZXJmX2V2ZW50Lmg+CiNpbmNsdWRlIDxsaW51eC9mdHJhY2VfZXZlbnQuaD4KI2luY2x1ZGUgPGxpbnV4L2h3X2JyZWFrcG9pbnQuaD4KCiNpbmNsdWRlIDxhc20vaXJxX3JlZ3MuaD4KCnN0cnVjdCByZW1vdGVfZnVuY3Rpb25fY2FsbCB7CglzdHJ1Y3QgdGFza19zdHJ1Y3QgKnA7CglpbnQgKCpmdW5jKSh2b2lkICppbmZvKTsKCXZvaWQgKmluZm87CglpbnQgcmV0Owp9OwoKc3RhdGljIHZvaWQgcmVtb3RlX2Z1bmN0aW9uKHZvaWQgKmRhdGEpCnsKCXN0cnVjdCByZW1vdGVfZnVuY3Rpb25fY2FsbCAqdGZjID0gZGF0YTsKCXN0cnVjdCB0YXNrX3N0cnVjdCAqcCA9IHRmYy0+cDsKCglpZiAocCkgewoJCXRmYy0+cmV0ID0gLUVBR0FJTjsKCQlpZiAodGFza19jcHUocCkgIT0gc21wX3Byb2Nlc3Nvcl9pZCgpIHx8ICF0YXNrX2N1cnIocCkpCgkJCXJldHVybjsKCX0KCgl0ZmMtPnJldCA9IHRmYy0+ZnVuYyh0ZmMtPmluZm8pOwp9CgovKioKICogdGFza19mdW5jdGlvbl9jYWxsIC0gY2FsbCBhIGZ1bmN0aW9uIG9uIHRoZSBjcHUgb24gd2hpY2ggYSB0YXNrIHJ1bnMKICogQHA6CQl0aGUgdGFzayB0byBldmFsdWF0ZQogKiBAZnVuYzoJdGhlIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZAogKiBAaW5mbzoJdGhlIGZ1bmN0aW9uIGNhbGwgYXJndW1lbnQKICoKICogQ2FsbHMgdGhlIGZ1bmN0aW9uIEBmdW5jIHdoZW4gdGhlIHRhc2sgaXMgY3VycmVudGx5IHJ1bm5pbmcuIFRoaXMgbWlnaHQKICogYmUgb24gdGhlIGN1cnJlbnQgQ1BVLCB3aGljaCBqdXN0IGNhbGxzIHRoZSBmdW5jdGlvbiBkaXJlY3RseQogKgogKiByZXR1cm5zOiBAZnVuYyByZXR1cm4gdmFsdWUsIG9yCiAqCSAgICAtRVNSQ0ggIC0gd2hlbiB0aGUgcHJvY2VzcyBpc24ndCBydW5uaW5nCiAqCSAgICAtRUFHQUlOIC0gd2hlbiB0aGUgcHJvY2VzcyBtb3ZlZCBhd2F5CiAqLwpzdGF0aWMgaW50CnRhc2tfZnVuY3Rpb25fY2FsbChzdHJ1Y3QgdGFza19zdHJ1Y3QgKnAsIGludCAoKmZ1bmMpICh2b2lkICppbmZvKSwgdm9pZCAqaW5mbykKewoJc3RydWN0IHJlbW90ZV9mdW5jdGlvbl9jYWxsIGRhdGEgPSB7CgkJLnAgPSBwLAoJCS5mdW5jID0gZnVuYywKCQkuaW5mbyA9IGluZm8sCgkJLnJldCA9IC1FU1JDSCwgLyogTm8gc3VjaCAocnVubmluZykgcHJvY2VzcyAqLwoJfTsKCglpZiAodGFza19jdXJyKHApKQoJCXNtcF9jYWxsX2Z1bmN0aW9uX3NpbmdsZSh0YXNrX2NwdShwKSwgcmVtb3RlX2Z1bmN0aW9uLCAmZGF0YSwgMSk7CgoJcmV0dXJuIGRhdGEucmV0Owp9CgovKioKICogY3B1X2Z1bmN0aW9uX2NhbGwgLSBjYWxsIGEgZnVuY3Rpb24gb24gdGhlIGNwdQogKiBAZnVuYzoJdGhlIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZAogKiBAaW5mbzoJdGhlIGZ1bmN0aW9uIGNhbGwgYXJndW1lbnQKICoKICogQ2FsbHMgdGhlIGZ1bmN0aW9uIEBmdW5jIG9uIHRoZSByZW1vdGUgY3B1LgogKgogKiByZXR1cm5zOiBAZnVuYyByZXR1cm4gdmFsdWUgb3IgLUVOWElPIHdoZW4gdGhlIGNwdSBpcyBvZmZsaW5lCiAqLwpzdGF0aWMgaW50IGNwdV9mdW5jdGlvbl9jYWxsKGludCBjcHUsIGludCAoKmZ1bmMpICh2b2lkICppbmZvKSwgdm9pZCAqaW5mbykKewoJc3RydWN0IHJlbW90ZV9mdW5jdGlvbl9jYWxsIGRhdGEgPSB7CgkJLnAgPSBOVUxMLAoJCS5mdW5jID0gZnVuYywKCQkuaW5mbyA9IGluZm8sCgkJLnJldCA9IC1FTlhJTywgLyogTm8gc3VjaCBDUFUgKi8KCX07CgoJc21wX2NhbGxfZnVuY3Rpb25fc2luZ2xlKGNwdSwgcmVtb3RlX2Z1bmN0aW9uLCAmZGF0YSwgMSk7CgoJcmV0dXJuIGRhdGEucmV0Owp9CgplbnVtIGV2ZW50X3R5cGVfdCB7CglFVkVOVF9GTEVYSUJMRSA9IDB4MSwKCUVWRU5UX1BJTk5FRCA9IDB4MiwKCUVWRU5UX0FMTCA9IEVWRU5UX0ZMRVhJQkxFIHwgRVZFTlRfUElOTkVELAp9OwoKYXRvbWljX3QgcGVyZl90YXNrX2V2ZW50cyBfX3JlYWRfbW9zdGx5OwpzdGF0aWMgYXRvbWljX3QgbnJfbW1hcF9ldmVudHMgX19yZWFkX21vc3RseTsKc3RhdGljIGF0b21pY190IG5yX2NvbW1fZXZlbnRzIF9fcmVhZF9tb3N0bHk7CnN0YXRpYyBhdG9taWNfdCBucl90YXNrX2V2ZW50cyBfX3JlYWRfbW9zdGx5OwoKc3RhdGljIExJU1RfSEVBRChwbXVzKTsKc3RhdGljIERFRklORV9NVVRFWChwbXVzX2xvY2spOwpzdGF0aWMgc3RydWN0IHNyY3Vfc3RydWN0IHBtdXNfc3JjdTsKCi8qCiAqIHBlcmYgZXZlbnQgcGFyYW5vaWEgbGV2ZWw6CiAqICAtMSAtIG5vdCBwYXJhbm9pZCBhdCBhbGwKICogICAwIC0gZGlzYWxsb3cgcmF3IHRyYWNlcG9pbnQgYWNjZXNzIGZvciB1bnByaXYKICogICAxIC0gZGlzYWxsb3cgY3B1IGV2ZW50cyBmb3IgdW5wcml2CiAqICAgMiAtIGRpc2FsbG93IGtlcm5lbCBwcm9maWxpbmcgZm9yIHVucHJpdgogKi8KaW50IHN5c2N0bF9wZXJmX2V2ZW50X3BhcmFub2lkIF9fcmVhZF9tb3N0bHkgPSAxOwoKaW50IHN5c2N0bF9wZXJmX2V2ZW50X21sb2NrIF9fcmVhZF9tb3N0bHkgPSA1MTI7IC8qICdmcmVlJyBrYiBwZXIgdXNlciAqLwoKLyoKICogbWF4IHBlcmYgZXZlbnQgc2FtcGxlIHJhdGUKICovCmludCBzeXNjdGxfcGVyZl9ldmVudF9zYW1wbGVfcmF0ZSBfX3JlYWRfbW9zdGx5ID0gMTAwMDAwOwoKc3RhdGljIGF0b21pYzY0X3QgcGVyZl9ldmVudF9pZDsKCnN0YXRpYyB2b2lkIGNwdV9jdHhfc2NoZWRfb3V0KHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgsCgkJCSAgICAgIGVudW0gZXZlbnRfdHlwZV90IGV2ZW50X3R5cGUpOwoKc3RhdGljIHZvaWQgY3B1X2N0eF9zY2hlZF9pbihzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4LAoJCQkgICAgIGVudW0gZXZlbnRfdHlwZV90IGV2ZW50X3R5cGUpOwoKdm9pZCBfX3dlYWsgcGVyZl9ldmVudF9wcmludF9kZWJ1Zyh2b2lkKQl7IH0KCmV4dGVybiBfX3dlYWsgY29uc3QgY2hhciAqcGVyZl9wbXVfbmFtZSh2b2lkKQp7CglyZXR1cm4gInBtdSI7Cn0KCnN0YXRpYyBpbmxpbmUgdTY0IHBlcmZfY2xvY2sodm9pZCkKewoJcmV0dXJuIGxvY2FsX2Nsb2NrKCk7Cn0KCnZvaWQgcGVyZl9wbXVfZGlzYWJsZShzdHJ1Y3QgcG11ICpwbXUpCnsKCWludCAqY291bnQgPSB0aGlzX2NwdV9wdHIocG11LT5wbXVfZGlzYWJsZV9jb3VudCk7CglpZiAoISgqY291bnQpKyspCgkJcG11LT5wbXVfZGlzYWJsZShwbXUpOwp9Cgp2b2lkIHBlcmZfcG11X2VuYWJsZShzdHJ1Y3QgcG11ICpwbXUpCnsKCWludCAqY291bnQgPSB0aGlzX2NwdV9wdHIocG11LT5wbXVfZGlzYWJsZV9jb3VudCk7CglpZiAoIS0tKCpjb3VudCkpCgkJcG11LT5wbXVfZW5hYmxlKHBtdSk7Cn0KCnN0YXRpYyBERUZJTkVfUEVSX0NQVShzdHJ1Y3QgbGlzdF9oZWFkLCByb3RhdGlvbl9saXN0KTsKCi8qCiAqIHBlcmZfcG11X3JvdGF0ZV9zdGFydCgpIGFuZCBwZXJmX3JvdGF0ZV9jb250ZXh0KCkgYXJlIGZ1bGx5IHNlcmlhbGl6ZWQKICogYmVjYXVzZSB0aGV5J3JlIHN0cmljdGx5IGNwdSBhZmZpbmUgYW5kIHJvdGF0ZV9zdGFydCBpcyBjYWxsZWQgd2l0aCBJUlFzCiAqIGRpc2FibGVkLCB3aGlsZSByb3RhdGVfY29udGV4dCBpcyBjYWxsZWQgZnJvbSBJUlEgY29udGV4dC4KICovCnN0YXRpYyB2b2lkIHBlcmZfcG11X3JvdGF0ZV9zdGFydChzdHJ1Y3QgcG11ICpwbXUpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHggPSB0aGlzX2NwdV9wdHIocG11LT5wbXVfY3B1X2NvbnRleHQpOwoJc3RydWN0IGxpc3RfaGVhZCAqaGVhZCA9ICZfX2dldF9jcHVfdmFyKHJvdGF0aW9uX2xpc3QpOwoKCVdBUk5fT04oIWlycXNfZGlzYWJsZWQoKSk7CgoJaWYgKGxpc3RfZW1wdHkoJmNwdWN0eC0+cm90YXRpb25fbGlzdCkpCgkJbGlzdF9hZGQoJmNwdWN0eC0+cm90YXRpb25fbGlzdCwgaGVhZCk7Cn0KCnN0YXRpYyB2b2lkIGdldF9jdHgoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglXQVJOX09OKCFhdG9taWNfaW5jX25vdF96ZXJvKCZjdHgtPnJlZmNvdW50KSk7Cn0KCnN0YXRpYyB2b2lkIGZyZWVfY3R4KHN0cnVjdCByY3VfaGVhZCAqaGVhZCkKewoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4OwoKCWN0eCA9IGNvbnRhaW5lcl9vZihoZWFkLCBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0LCByY3VfaGVhZCk7CglrZnJlZShjdHgpOwp9CgpzdGF0aWMgdm9pZCBwdXRfY3R4KHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCkKewoJaWYgKGF0b21pY19kZWNfYW5kX3Rlc3QoJmN0eC0+cmVmY291bnQpKSB7CgkJaWYgKGN0eC0+cGFyZW50X2N0eCkKCQkJcHV0X2N0eChjdHgtPnBhcmVudF9jdHgpOwoJCWlmIChjdHgtPnRhc2spCgkJCXB1dF90YXNrX3N0cnVjdChjdHgtPnRhc2spOwoJCWNhbGxfcmN1KCZjdHgtPnJjdV9oZWFkLCBmcmVlX2N0eCk7Cgl9Cn0KCnN0YXRpYyB2b2lkIHVuY2xvbmVfY3R4KHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCkKewoJaWYgKGN0eC0+cGFyZW50X2N0eCkgewoJCXB1dF9jdHgoY3R4LT5wYXJlbnRfY3R4KTsKCQljdHgtPnBhcmVudF9jdHggPSBOVUxMOwoJfQp9CgpzdGF0aWMgdTMyIHBlcmZfZXZlbnRfcGlkKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgc3RydWN0IHRhc2tfc3RydWN0ICpwKQp7CgkvKgoJICogb25seSB0b3AgbGV2ZWwgZXZlbnRzIGhhdmUgdGhlIHBpZCBuYW1lc3BhY2UgdGhleSB3ZXJlIGNyZWF0ZWQgaW4KCSAqLwoJaWYgKGV2ZW50LT5wYXJlbnQpCgkJZXZlbnQgPSBldmVudC0+cGFyZW50OwoKCXJldHVybiB0YXNrX3RnaWRfbnJfbnMocCwgZXZlbnQtPm5zKTsKfQoKc3RhdGljIHUzMiBwZXJmX2V2ZW50X3RpZChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIHN0cnVjdCB0YXNrX3N0cnVjdCAqcCkKewoJLyoKCSAqIG9ubHkgdG9wIGxldmVsIGV2ZW50cyBoYXZlIHRoZSBwaWQgbmFtZXNwYWNlIHRoZXkgd2VyZSBjcmVhdGVkIGluCgkgKi8KCWlmIChldmVudC0+cGFyZW50KQoJCWV2ZW50ID0gZXZlbnQtPnBhcmVudDsKCglyZXR1cm4gdGFza19waWRfbnJfbnMocCwgZXZlbnQtPm5zKTsKfQoKLyoKICogSWYgd2UgaW5oZXJpdCBldmVudHMgd2Ugd2FudCB0byByZXR1cm4gdGhlIHBhcmVudCBldmVudCBpZAogKiB0byB1c2Vyc3BhY2UuCiAqLwpzdGF0aWMgdTY0IHByaW1hcnlfZXZlbnRfaWQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7Cgl1NjQgaWQgPSBldmVudC0+aWQ7CgoJaWYgKGV2ZW50LT5wYXJlbnQpCgkJaWQgPSBldmVudC0+cGFyZW50LT5pZDsKCglyZXR1cm4gaWQ7Cn0KCi8qCiAqIEdldCB0aGUgcGVyZl9ldmVudF9jb250ZXh0IGZvciBhIHRhc2sgYW5kIGxvY2sgaXQuCiAqIFRoaXMgaGFzIHRvIGNvcGUgd2l0aCB3aXRoIHRoZSBmYWN0IHRoYXQgdW50aWwgaXQgaXMgbG9ja2VkLAogKiB0aGUgY29udGV4dCBjb3VsZCBnZXQgbW92ZWQgdG8gYW5vdGhlciB0YXNrLgogKi8Kc3RhdGljIHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKgpwZXJmX2xvY2tfdGFza19jb250ZXh0KHN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzaywgaW50IGN0eG4sIHVuc2lnbmVkIGxvbmcgKmZsYWdzKQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHg7CgoJcmN1X3JlYWRfbG9jaygpOwpyZXRyeToKCWN0eCA9IHJjdV9kZXJlZmVyZW5jZSh0YXNrLT5wZXJmX2V2ZW50X2N0eHBbY3R4bl0pOwoJaWYgKGN0eCkgewoJCS8qCgkJICogSWYgdGhpcyBjb250ZXh0IGlzIGEgY2xvbmUgb2YgYW5vdGhlciwgaXQgbWlnaHQKCQkgKiBnZXQgc3dhcHBlZCBmb3IgYW5vdGhlciB1bmRlcm5lYXRoIHVzIGJ5CgkJICogcGVyZl9ldmVudF90YXNrX3NjaGVkX291dCwgdGhvdWdoIHRoZQoJCSAqIHJjdV9yZWFkX2xvY2soKSBwcm90ZWN0cyB1cyBmcm9tIGFueSBjb250ZXh0CgkJICogZ2V0dGluZyBmcmVlZC4gIExvY2sgdGhlIGNvbnRleHQgYW5kIGNoZWNrIGlmIGl0CgkJICogZ290IHN3YXBwZWQgYmVmb3JlIHdlIGNvdWxkIGdldCB0aGUgbG9jaywgYW5kIHJldHJ5CgkJICogaWYgc28uICBJZiB3ZSBsb2NrZWQgdGhlIHJpZ2h0IGNvbnRleHQsIHRoZW4gaXQKCQkgKiBjYW4ndCBnZXQgc3dhcHBlZCBvbiB1cyBhbnkgbW9yZS4KCQkgKi8KCQlyYXdfc3Bpbl9sb2NrX2lycXNhdmUoJmN0eC0+bG9jaywgKmZsYWdzKTsKCQlpZiAoY3R4ICE9IHJjdV9kZXJlZmVyZW5jZSh0YXNrLT5wZXJmX2V2ZW50X2N0eHBbY3R4bl0pKSB7CgkJCXJhd19zcGluX3VubG9ja19pcnFyZXN0b3JlKCZjdHgtPmxvY2ssICpmbGFncyk7CgkJCWdvdG8gcmV0cnk7CgkJfQoKCQlpZiAoIWF0b21pY19pbmNfbm90X3plcm8oJmN0eC0+cmVmY291bnQpKSB7CgkJCXJhd19zcGluX3VubG9ja19pcnFyZXN0b3JlKCZjdHgtPmxvY2ssICpmbGFncyk7CgkJCWN0eCA9IE5VTEw7CgkJfQoJfQoJcmN1X3JlYWRfdW5sb2NrKCk7CglyZXR1cm4gY3R4Owp9CgovKgogKiBHZXQgdGhlIGNvbnRleHQgZm9yIGEgdGFzayBhbmQgaW5jcmVtZW50IGl0cyBwaW5fY291bnQgc28gaXQKICogY2FuJ3QgZ2V0IHN3YXBwZWQgdG8gYW5vdGhlciB0YXNrLiAgVGhpcyBhbHNvIGluY3JlbWVudHMgaXRzCiAqIHJlZmVyZW5jZSBjb3VudCBzbyB0aGF0IHRoZSBjb250ZXh0IGNhbid0IGdldCBmcmVlZC4KICovCnN0YXRpYyBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICoKcGVyZl9waW5fdGFza19jb250ZXh0KHN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzaywgaW50IGN0eG4pCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eDsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJY3R4ID0gcGVyZl9sb2NrX3Rhc2tfY29udGV4dCh0YXNrLCBjdHhuLCAmZmxhZ3MpOwoJaWYgKGN0eCkgewoJCSsrY3R4LT5waW5fY291bnQ7CgkJcmF3X3NwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmN0eC0+bG9jaywgZmxhZ3MpOwoJfQoJcmV0dXJuIGN0eDsKfQoKc3RhdGljIHZvaWQgcGVyZl91bnBpbl9jb250ZXh0KHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCkKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglyYXdfc3Bpbl9sb2NrX2lycXNhdmUoJmN0eC0+bG9jaywgZmxhZ3MpOwoJLS1jdHgtPnBpbl9jb3VudDsKCXJhd19zcGluX3VubG9ja19pcnFyZXN0b3JlKCZjdHgtPmxvY2ssIGZsYWdzKTsKfQoKLyoKICogVXBkYXRlIHRoZSByZWNvcmQgb2YgdGhlIGN1cnJlbnQgdGltZSBpbiBhIGNvbnRleHQuCiAqLwpzdGF0aWMgdm9pZCB1cGRhdGVfY29udGV4dF90aW1lKHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCkKewoJdTY0IG5vdyA9IHBlcmZfY2xvY2soKTsKCgljdHgtPnRpbWUgKz0gbm93IC0gY3R4LT50aW1lc3RhbXA7CgljdHgtPnRpbWVzdGFtcCA9IG5vdzsKfQoKc3RhdGljIHU2NCBwZXJmX2V2ZW50X3RpbWUoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSBldmVudC0+Y3R4OwoJcmV0dXJuIGN0eCA/IGN0eC0+dGltZSA6IDA7Cn0KCi8qCiAqIFVwZGF0ZSB0aGUgdG90YWxfdGltZV9lbmFibGVkIGFuZCB0b3RhbF90aW1lX3J1bm5pbmcgZmllbGRzIGZvciBhIGV2ZW50LgogKi8Kc3RhdGljIHZvaWQgdXBkYXRlX2V2ZW50X3RpbWVzKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4ID0gZXZlbnQtPmN0eDsKCXU2NCBydW5fZW5kOwoKCWlmIChldmVudC0+c3RhdGUgPCBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFIHx8CgkgICAgZXZlbnQtPmdyb3VwX2xlYWRlci0+c3RhdGUgPCBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFKQoJCXJldHVybjsKCglpZiAoY3R4LT5pc19hY3RpdmUpCgkJcnVuX2VuZCA9IHBlcmZfZXZlbnRfdGltZShldmVudCk7CgllbHNlCgkJcnVuX2VuZCA9IGV2ZW50LT50c3RhbXBfc3RvcHBlZDsKCglldmVudC0+dG90YWxfdGltZV9lbmFibGVkID0gcnVuX2VuZCAtIGV2ZW50LT50c3RhbXBfZW5hYmxlZDsKCglpZiAoZXZlbnQtPnN0YXRlID09IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUpCgkJcnVuX2VuZCA9IGV2ZW50LT50c3RhbXBfc3RvcHBlZDsKCWVsc2UKCQlydW5fZW5kID0gcGVyZl9ldmVudF90aW1lKGV2ZW50KTsKCglldmVudC0+dG90YWxfdGltZV9ydW5uaW5nID0gcnVuX2VuZCAtIGV2ZW50LT50c3RhbXBfcnVubmluZzsKfQoKLyoKICogVXBkYXRlIHRvdGFsX3RpbWVfZW5hYmxlZCBhbmQgdG90YWxfdGltZV9ydW5uaW5nIGZvciBhbGwgZXZlbnRzIGluIGEgZ3JvdXAuCiAqLwpzdGF0aWMgdm9pZCB1cGRhdGVfZ3JvdXBfdGltZXMoc3RydWN0IHBlcmZfZXZlbnQgKmxlYWRlcikKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoKCXVwZGF0ZV9ldmVudF90aW1lcyhsZWFkZXIpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShldmVudCwgJmxlYWRlci0+c2libGluZ19saXN0LCBncm91cF9lbnRyeSkKCQl1cGRhdGVfZXZlbnRfdGltZXMoZXZlbnQpOwp9CgpzdGF0aWMgc3RydWN0IGxpc3RfaGVhZCAqCmN0eF9ncm91cF9saXN0KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglpZiAoZXZlbnQtPmF0dHIucGlubmVkKQoJCXJldHVybiAmY3R4LT5waW5uZWRfZ3JvdXBzOwoJZWxzZQoJCXJldHVybiAmY3R4LT5mbGV4aWJsZV9ncm91cHM7Cn0KCi8qCiAqIEFkZCBhIGV2ZW50IGZyb20gdGhlIGxpc3RzIGZvciBpdHMgY29udGV4dC4KICogTXVzdCBiZSBjYWxsZWQgd2l0aCBjdHgtPm11dGV4IGFuZCBjdHgtPmxvY2sgaGVsZC4KICovCnN0YXRpYyB2b2lkCmxpc3RfYWRkX2V2ZW50KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglXQVJOX09OX09OQ0UoZXZlbnQtPmF0dGFjaF9zdGF0ZSAmIFBFUkZfQVRUQUNIX0NPTlRFWFQpOwoJZXZlbnQtPmF0dGFjaF9zdGF0ZSB8PSBQRVJGX0FUVEFDSF9DT05URVhUOwoKCS8qCgkgKiBJZiB3ZSdyZSBhIHN0YW5kIGFsb25lIGV2ZW50IG9yIGdyb3VwIGxlYWRlciwgd2UgZ28gdG8gdGhlIGNvbnRleHQKCSAqIGxpc3QsIGdyb3VwIGV2ZW50cyBhcmUga2VwdCBhdHRhY2hlZCB0byB0aGUgZ3JvdXAgc28gdGhhdAoJICogcGVyZl9ncm91cF9kZXRhY2ggY2FuLCBhdCBhbGwgdGltZXMsIGxvY2F0ZSBhbGwgc2libGluZ3MuCgkgKi8KCWlmIChldmVudC0+Z3JvdXBfbGVhZGVyID09IGV2ZW50KSB7CgkJc3RydWN0IGxpc3RfaGVhZCAqbGlzdDsKCgkJaWYgKGlzX3NvZnR3YXJlX2V2ZW50KGV2ZW50KSkKCQkJZXZlbnQtPmdyb3VwX2ZsYWdzIHw9IFBFUkZfR1JPVVBfU09GVFdBUkU7CgoJCWxpc3QgPSBjdHhfZ3JvdXBfbGlzdChldmVudCwgY3R4KTsKCQlsaXN0X2FkZF90YWlsKCZldmVudC0+Z3JvdXBfZW50cnksIGxpc3QpOwoJfQoKCWxpc3RfYWRkX3JjdSgmZXZlbnQtPmV2ZW50X2VudHJ5LCAmY3R4LT5ldmVudF9saXN0KTsKCWlmICghY3R4LT5ucl9ldmVudHMpCgkJcGVyZl9wbXVfcm90YXRlX3N0YXJ0KGN0eC0+cG11KTsKCWN0eC0+bnJfZXZlbnRzKys7CglpZiAoZXZlbnQtPmF0dHIuaW5oZXJpdF9zdGF0KQoJCWN0eC0+bnJfc3RhdCsrOwp9CgovKgogKiBDYWxsZWQgYXQgcGVyZl9ldmVudCBjcmVhdGlvbiBhbmQgd2hlbiBldmVudHMgYXJlIGF0dGFjaGVkL2RldGFjaGVkIGZyb20gYQogKiBncm91cC4KICovCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfX3JlYWRfc2l6ZShzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCWludCBlbnRyeSA9IHNpemVvZih1NjQpOyAvKiB2YWx1ZSAqLwoJaW50IHNpemUgPSAwOwoJaW50IG5yID0gMTsKCglpZiAoZXZlbnQtPmF0dHIucmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9UT1RBTF9USU1FX0VOQUJMRUQpCgkJc2l6ZSArPSBzaXplb2YodTY0KTsKCglpZiAoZXZlbnQtPmF0dHIucmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9UT1RBTF9USU1FX1JVTk5JTkcpCgkJc2l6ZSArPSBzaXplb2YodTY0KTsKCglpZiAoZXZlbnQtPmF0dHIucmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9JRCkKCQllbnRyeSArPSBzaXplb2YodTY0KTsKCglpZiAoZXZlbnQtPmF0dHIucmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9HUk9VUCkgewoJCW5yICs9IGV2ZW50LT5ncm91cF9sZWFkZXItPm5yX3NpYmxpbmdzOwoJCXNpemUgKz0gc2l6ZW9mKHU2NCk7Cgl9CgoJc2l6ZSArPSBlbnRyeSAqIG5yOwoJZXZlbnQtPnJlYWRfc2l6ZSA9IHNpemU7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfX2hlYWRlcl9zaXplKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgKmRhdGE7Cgl1NjQgc2FtcGxlX3R5cGUgPSBldmVudC0+YXR0ci5zYW1wbGVfdHlwZTsKCXUxNiBzaXplID0gMDsKCglwZXJmX2V2ZW50X19yZWFkX3NpemUoZXZlbnQpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0lQKQoJCXNpemUgKz0gc2l6ZW9mKGRhdGEtPmlwKTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9BRERSKQoJCXNpemUgKz0gc2l6ZW9mKGRhdGEtPmFkZHIpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1BFUklPRCkKCQlzaXplICs9IHNpemVvZihkYXRhLT5wZXJpb2QpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1JFQUQpCgkJc2l6ZSArPSBldmVudC0+cmVhZF9zaXplOwoKCWV2ZW50LT5oZWFkZXJfc2l6ZSA9IHNpemU7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfX2lkX2hlYWRlcl9zaXplKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgKmRhdGE7Cgl1NjQgc2FtcGxlX3R5cGUgPSBldmVudC0+YXR0ci5zYW1wbGVfdHlwZTsKCXUxNiBzaXplID0gMDsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9USUQpCgkJc2l6ZSArPSBzaXplb2YoZGF0YS0+dGlkX2VudHJ5KTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9USU1FKQoJCXNpemUgKz0gc2l6ZW9mKGRhdGEtPnRpbWUpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0lEKQoJCXNpemUgKz0gc2l6ZW9mKGRhdGEtPmlkKTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9TVFJFQU1fSUQpCgkJc2l6ZSArPSBzaXplb2YoZGF0YS0+c3RyZWFtX2lkKTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9DUFUpCgkJc2l6ZSArPSBzaXplb2YoZGF0YS0+Y3B1X2VudHJ5KTsKCglldmVudC0+aWRfaGVhZGVyX3NpemUgPSBzaXplOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2dyb3VwX2F0dGFjaChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpncm91cF9sZWFkZXIgPSBldmVudC0+Z3JvdXBfbGVhZGVyLCAqcG9zOwoKCS8qCgkgKiBXZSBjYW4gaGF2ZSBkb3VibGUgYXR0YWNoIGR1ZSB0byBncm91cCBtb3ZlbWVudCBpbiBwZXJmX2V2ZW50X29wZW4uCgkgKi8KCWlmIChldmVudC0+YXR0YWNoX3N0YXRlICYgUEVSRl9BVFRBQ0hfR1JPVVApCgkJcmV0dXJuOwoKCWV2ZW50LT5hdHRhY2hfc3RhdGUgfD0gUEVSRl9BVFRBQ0hfR1JPVVA7CgoJaWYgKGdyb3VwX2xlYWRlciA9PSBldmVudCkKCQlyZXR1cm47CgoJaWYgKGdyb3VwX2xlYWRlci0+Z3JvdXBfZmxhZ3MgJiBQRVJGX0dST1VQX1NPRlRXQVJFICYmCgkJCSFpc19zb2Z0d2FyZV9ldmVudChldmVudCkpCgkJZ3JvdXBfbGVhZGVyLT5ncm91cF9mbGFncyAmPSB+UEVSRl9HUk9VUF9TT0ZUV0FSRTsKCglsaXN0X2FkZF90YWlsKCZldmVudC0+Z3JvdXBfZW50cnksICZncm91cF9sZWFkZXItPnNpYmxpbmdfbGlzdCk7Cglncm91cF9sZWFkZXItPm5yX3NpYmxpbmdzKys7CgoJcGVyZl9ldmVudF9faGVhZGVyX3NpemUoZ3JvdXBfbGVhZGVyKTsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5KHBvcywgJmdyb3VwX2xlYWRlci0+c2libGluZ19saXN0LCBncm91cF9lbnRyeSkKCQlwZXJmX2V2ZW50X19oZWFkZXJfc2l6ZShwb3MpOwp9CgovKgogKiBSZW1vdmUgYSBldmVudCBmcm9tIHRoZSBsaXN0cyBmb3IgaXRzIGNvbnRleHQuCiAqIE11c3QgYmUgY2FsbGVkIHdpdGggY3R4LT5tdXRleCBhbmQgY3R4LT5sb2NrIGhlbGQuCiAqLwpzdGF0aWMgdm9pZApsaXN0X2RlbF9ldmVudChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCkKewoJLyoKCSAqIFdlIGNhbiBoYXZlIGRvdWJsZSBkZXRhY2ggZHVlIHRvIGV4aXQvaG90LXVucGx1ZyArIGNsb3NlLgoJICovCglpZiAoIShldmVudC0+YXR0YWNoX3N0YXRlICYgUEVSRl9BVFRBQ0hfQ09OVEVYVCkpCgkJcmV0dXJuOwoKCWV2ZW50LT5hdHRhY2hfc3RhdGUgJj0gflBFUkZfQVRUQUNIX0NPTlRFWFQ7CgoJY3R4LT5ucl9ldmVudHMtLTsKCWlmIChldmVudC0+YXR0ci5pbmhlcml0X3N0YXQpCgkJY3R4LT5ucl9zdGF0LS07CgoJbGlzdF9kZWxfcmN1KCZldmVudC0+ZXZlbnRfZW50cnkpOwoKCWlmIChldmVudC0+Z3JvdXBfbGVhZGVyID09IGV2ZW50KQoJCWxpc3RfZGVsX2luaXQoJmV2ZW50LT5ncm91cF9lbnRyeSk7CgoJdXBkYXRlX2dyb3VwX3RpbWVzKGV2ZW50KTsKCgkvKgoJICogSWYgZXZlbnQgd2FzIGluIGVycm9yIHN0YXRlLCB0aGVuIGtlZXAgaXQKCSAqIHRoYXQgd2F5LCBvdGhlcndpc2UgYm9ndXMgY291bnRzIHdpbGwgYmUKCSAqIHJldHVybmVkIG9uIHJlYWQoKS4gVGhlIG9ubHkgd2F5IHRvIGdldCBvdXQKCSAqIG9mIGVycm9yIHN0YXRlIGlzIGJ5IGV4cGxpY2l0IHJlLWVuYWJsaW5nCgkgKiBvZiB0aGUgZXZlbnQKCSAqLwoJaWYgKGV2ZW50LT5zdGF0ZSA+IFBFUkZfRVZFTlRfU1RBVEVfT0ZGKQoJCWV2ZW50LT5zdGF0ZSA9IFBFUkZfRVZFTlRfU1RBVEVfT0ZGOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2dyb3VwX2RldGFjaChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpzaWJsaW5nLCAqdG1wOwoJc3RydWN0IGxpc3RfaGVhZCAqbGlzdCA9IE5VTEw7CgoJLyoKCSAqIFdlIGNhbiBoYXZlIGRvdWJsZSBkZXRhY2ggZHVlIHRvIGV4aXQvaG90LXVucGx1ZyArIGNsb3NlLgoJICovCglpZiAoIShldmVudC0+YXR0YWNoX3N0YXRlICYgUEVSRl9BVFRBQ0hfR1JPVVApKQoJCXJldHVybjsKCglldmVudC0+YXR0YWNoX3N0YXRlICY9IH5QRVJGX0FUVEFDSF9HUk9VUDsKCgkvKgoJICogSWYgdGhpcyBpcyBhIHNpYmxpbmcsIHJlbW92ZSBpdCBmcm9tIGl0cyBncm91cC4KCSAqLwoJaWYgKGV2ZW50LT5ncm91cF9sZWFkZXIgIT0gZXZlbnQpIHsKCQlsaXN0X2RlbF9pbml0KCZldmVudC0+Z3JvdXBfZW50cnkpOwoJCWV2ZW50LT5ncm91cF9sZWFkZXItPm5yX3NpYmxpbmdzLS07CgkJZ290byBvdXQ7Cgl9CgoJaWYgKCFsaXN0X2VtcHR5KCZldmVudC0+Z3JvdXBfZW50cnkpKQoJCWxpc3QgPSAmZXZlbnQtPmdyb3VwX2VudHJ5OwoKCS8qCgkgKiBJZiB0aGlzIHdhcyBhIGdyb3VwIGV2ZW50IHdpdGggc2libGluZyBldmVudHMgdGhlbgoJICogdXBncmFkZSB0aGUgc2libGluZ3MgdG8gc2luZ2xldG9uIGV2ZW50cyBieSBhZGRpbmcgdGhlbQoJICogdG8gd2hhdGV2ZXIgbGlzdCB3ZSBhcmUgb24uCgkgKi8KCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShzaWJsaW5nLCB0bXAsICZldmVudC0+c2libGluZ19saXN0LCBncm91cF9lbnRyeSkgewoJCWlmIChsaXN0KQoJCQlsaXN0X21vdmVfdGFpbCgmc2libGluZy0+Z3JvdXBfZW50cnksIGxpc3QpOwoJCXNpYmxpbmctPmdyb3VwX2xlYWRlciA9IHNpYmxpbmc7CgoJCS8qIEluaGVyaXQgZ3JvdXAgZmxhZ3MgZnJvbSB0aGUgcHJldmlvdXMgbGVhZGVyICovCgkJc2libGluZy0+Z3JvdXBfZmxhZ3MgPSBldmVudC0+Z3JvdXBfZmxhZ3M7Cgl9CgpvdXQ6CglwZXJmX2V2ZW50X19oZWFkZXJfc2l6ZShldmVudC0+Z3JvdXBfbGVhZGVyKTsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5KHRtcCwgJmV2ZW50LT5ncm91cF9sZWFkZXItPnNpYmxpbmdfbGlzdCwgZ3JvdXBfZW50cnkpCgkJcGVyZl9ldmVudF9faGVhZGVyX3NpemUodG1wKTsKfQoKc3RhdGljIGlubGluZSBpbnQKZXZlbnRfZmlsdGVyX21hdGNoKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJcmV0dXJuIGV2ZW50LT5jcHUgPT0gLTEgfHwgZXZlbnQtPmNwdSA9PSBzbXBfcHJvY2Vzc29yX2lkKCk7Cn0KCnN0YXRpYyB2b2lkCmV2ZW50X3NjaGVkX291dChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJICBzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4LAoJCSAgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7Cgl1NjQgdHN0YW1wID0gcGVyZl9ldmVudF90aW1lKGV2ZW50KTsKCXU2NCBkZWx0YTsKCS8qCgkgKiBBbiBldmVudCB3aGljaCBjb3VsZCBub3QgYmUgYWN0aXZhdGVkIGJlY2F1c2Ugb2YKCSAqIGZpbHRlciBtaXNtYXRjaCBzdGlsbCBuZWVkcyB0byBoYXZlIGl0cyB0aW1pbmdzCgkgKiBtYWludGFpbmVkLCBvdGhlcndpc2UgYm9ndXMgaW5mb3JtYXRpb24gaXMgcmV0dXJuCgkgKiB2aWEgcmVhZCgpIGZvciB0aW1lX2VuYWJsZWQsIHRpbWVfcnVubmluZzoKCSAqLwoJaWYgKGV2ZW50LT5zdGF0ZSA9PSBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFCgkgICAgJiYgIWV2ZW50X2ZpbHRlcl9tYXRjaChldmVudCkpIHsKCQlkZWx0YSA9IGN0eC0+dGltZSAtIGV2ZW50LT50c3RhbXBfc3RvcHBlZDsKCQlldmVudC0+dHN0YW1wX3J1bm5pbmcgKz0gZGVsdGE7CgkJZXZlbnQtPnRzdGFtcF9zdG9wcGVkID0gdHN0YW1wOwoJfQoKCWlmIChldmVudC0+c3RhdGUgIT0gUEVSRl9FVkVOVF9TVEFURV9BQ1RJVkUpCgkJcmV0dXJuOwoKCWV2ZW50LT5zdGF0ZSA9IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkU7CglpZiAoZXZlbnQtPnBlbmRpbmdfZGlzYWJsZSkgewoJCWV2ZW50LT5wZW5kaW5nX2Rpc2FibGUgPSAwOwoJCWV2ZW50LT5zdGF0ZSA9IFBFUkZfRVZFTlRfU1RBVEVfT0ZGOwoJfQoJZXZlbnQtPnRzdGFtcF9zdG9wcGVkID0gdHN0YW1wOwoJZXZlbnQtPnBtdS0+ZGVsKGV2ZW50LCAwKTsKCWV2ZW50LT5vbmNwdSA9IC0xOwoKCWlmICghaXNfc29mdHdhcmVfZXZlbnQoZXZlbnQpKQoJCWNwdWN0eC0+YWN0aXZlX29uY3B1LS07CgljdHgtPm5yX2FjdGl2ZS0tOwoJaWYgKGV2ZW50LT5hdHRyLmV4Y2x1c2l2ZSB8fCAhY3B1Y3R4LT5hY3RpdmVfb25jcHUpCgkJY3B1Y3R4LT5leGNsdXNpdmUgPSAwOwp9CgpzdGF0aWMgdm9pZApncm91cF9zY2hlZF9vdXQoc3RydWN0IHBlcmZfZXZlbnQgKmdyb3VwX2V2ZW50LAoJCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgsCgkJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQ7CglpbnQgc3RhdGUgPSBncm91cF9ldmVudC0+c3RhdGU7CgoJZXZlbnRfc2NoZWRfb3V0KGdyb3VwX2V2ZW50LCBjcHVjdHgsIGN0eCk7CgoJLyoKCSAqIFNjaGVkdWxlIG91dCBzaWJsaW5ncyAoaWYgYW55KToKCSAqLwoJbGlzdF9mb3JfZWFjaF9lbnRyeShldmVudCwgJmdyb3VwX2V2ZW50LT5zaWJsaW5nX2xpc3QsIGdyb3VwX2VudHJ5KQoJCWV2ZW50X3NjaGVkX291dChldmVudCwgY3B1Y3R4LCBjdHgpOwoKCWlmIChzdGF0ZSA9PSBQRVJGX0VWRU5UX1NUQVRFX0FDVElWRSAmJiBncm91cF9ldmVudC0+YXR0ci5leGNsdXNpdmUpCgkJY3B1Y3R4LT5leGNsdXNpdmUgPSAwOwp9CgpzdGF0aWMgaW5saW5lIHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICoKX19nZXRfY3B1X2NvbnRleHQoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglyZXR1cm4gdGhpc19jcHVfcHRyKGN0eC0+cG11LT5wbXVfY3B1X2NvbnRleHQpOwp9CgovKgogKiBDcm9zcyBDUFUgY2FsbCB0byByZW1vdmUgYSBwZXJmb3JtYW5jZSBldmVudAogKgogKiBXZSBkaXNhYmxlIHRoZSBldmVudCBvbiB0aGUgaGFyZHdhcmUgbGV2ZWwgZmlyc3QuIEFmdGVyIHRoYXQgd2UKICogcmVtb3ZlIGl0IGZyb20gdGhlIGNvbnRleHQgbGlzdC4KICovCnN0YXRpYyBpbnQgX19wZXJmX3JlbW92ZV9mcm9tX2NvbnRleHQodm9pZCAqaW5mbykKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50ID0gaW5mbzsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IGV2ZW50LT5jdHg7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4ID0gX19nZXRfY3B1X2NvbnRleHQoY3R4KTsKCglyYXdfc3Bpbl9sb2NrKCZjdHgtPmxvY2spOwoJZXZlbnRfc2NoZWRfb3V0KGV2ZW50LCBjcHVjdHgsIGN0eCk7CglsaXN0X2RlbF9ldmVudChldmVudCwgY3R4KTsKCXJhd19zcGluX3VubG9jaygmY3R4LT5sb2NrKTsKCglyZXR1cm4gMDsKfQoKCi8qCiAqIFJlbW92ZSB0aGUgZXZlbnQgZnJvbSBhIHRhc2sncyAob3IgYSBDUFUncykgbGlzdCBvZiBldmVudHMuCiAqCiAqIENQVSBldmVudHMgYXJlIHJlbW92ZWQgd2l0aCBhIHNtcCBjYWxsLiBGb3IgdGFzayBldmVudHMgd2Ugb25seQogKiBjYWxsIHdoZW4gdGhlIHRhc2sgaXMgb24gYSBDUFUuCiAqCiAqIElmIGV2ZW50LT5jdHggaXMgYSBjbG9uZWQgY29udGV4dCwgY2FsbGVycyBtdXN0IG1ha2Ugc3VyZSB0aGF0CiAqIGV2ZXJ5IHRhc2sgc3RydWN0IHRoYXQgZXZlbnQtPmN0eC0+dGFzayBjb3VsZCBwb3NzaWJseSBwb2ludCB0bwogKiByZW1haW5zIHZhbGlkLiAgVGhpcyBpcyBPSyB3aGVuIGNhbGxlZCBmcm9tIHBlcmZfcmVsZWFzZSBzaW5jZQogKiB0aGF0IG9ubHkgY2FsbHMgdXMgb24gdGhlIHRvcC1sZXZlbCBjb250ZXh0LCB3aGljaCBjYW4ndCBiZSBhIGNsb25lLgogKiBXaGVuIGNhbGxlZCBmcm9tIHBlcmZfZXZlbnRfZXhpdF90YXNrLCBpdCdzIE9LIGJlY2F1c2UgdGhlCiAqIGNvbnRleHQgaGFzIGJlZW4gZGV0YWNoZWQgZnJvbSBpdHMgdGFzay4KICovCnN0YXRpYyB2b2lkIHBlcmZfcmVtb3ZlX2Zyb21fY29udGV4dChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IGV2ZW50LT5jdHg7CglzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2sgPSBjdHgtPnRhc2s7CgoJbG9ja2RlcF9hc3NlcnRfaGVsZCgmY3R4LT5tdXRleCk7CgoJaWYgKCF0YXNrKSB7CgkJLyoKCQkgKiBQZXIgY3B1IGV2ZW50cyBhcmUgcmVtb3ZlZCB2aWEgYW4gc21wIGNhbGwgYW5kCgkJICogdGhlIHJlbW92YWwgaXMgYWx3YXlzIHN1Y2Nlc3NmdWwuCgkJICovCgkJY3B1X2Z1bmN0aW9uX2NhbGwoZXZlbnQtPmNwdSwgX19wZXJmX3JlbW92ZV9mcm9tX2NvbnRleHQsIGV2ZW50KTsKCQlyZXR1cm47Cgl9CgpyZXRyeToKCWlmICghdGFza19mdW5jdGlvbl9jYWxsKHRhc2ssIF9fcGVyZl9yZW1vdmVfZnJvbV9jb250ZXh0LCBldmVudCkpCgkJcmV0dXJuOwoKCXJhd19zcGluX2xvY2tfaXJxKCZjdHgtPmxvY2spOwoJLyoKCSAqIElmIHdlIGZhaWxlZCB0byBmaW5kIGEgcnVubmluZyB0YXNrLCBidXQgZmluZCB0aGUgY29udGV4dCBhY3RpdmUgbm93CgkgKiB0aGF0IHdlJ3ZlIGFjcXVpcmVkIHRoZSBjdHgtPmxvY2ssIHJldHJ5LgoJICovCglpZiAoY3R4LT5pc19hY3RpdmUpIHsKCQlyYXdfc3Bpbl91bmxvY2tfaXJxKCZjdHgtPmxvY2spOwoJCWdvdG8gcmV0cnk7Cgl9CgoJLyoKCSAqIFNpbmNlIHRoZSB0YXNrIGlzbid0IHJ1bm5pbmcsIGl0cyBzYWZlIHRvIHJlbW92ZSB0aGUgZXZlbnQsIHVzCgkgKiBob2xkaW5nIHRoZSBjdHgtPmxvY2sgZW5zdXJlcyB0aGUgdGFzayB3b24ndCBnZXQgc2NoZWR1bGVkIGluLgoJICovCglsaXN0X2RlbF9ldmVudChldmVudCwgY3R4KTsKCXJhd19zcGluX3VubG9ja19pcnEoJmN0eC0+bG9jayk7Cn0KCi8qCiAqIENyb3NzIENQVSBjYWxsIHRvIGRpc2FibGUgYSBwZXJmb3JtYW5jZSBldmVudAogKi8Kc3RhdGljIGludCBfX3BlcmZfZXZlbnRfZGlzYWJsZSh2b2lkICppbmZvKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQgPSBpbmZvOwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4ID0gZXZlbnQtPmN0eDsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHggPSBfX2dldF9jcHVfY29udGV4dChjdHgpOwoKCS8qCgkgKiBJZiB0aGlzIGlzIGEgcGVyLXRhc2sgZXZlbnQsIG5lZWQgdG8gY2hlY2sgd2hldGhlciB0aGlzCgkgKiBldmVudCdzIHRhc2sgaXMgdGhlIGN1cnJlbnQgdGFzayBvbiB0aGlzIGNwdS4KCSAqCgkgKiBDYW4gdHJpZ2dlciBkdWUgdG8gY29uY3VycmVudCBwZXJmX2V2ZW50X2NvbnRleHRfc2NoZWRfb3V0KCkKCSAqIGZsaXBwaW5nIGNvbnRleHRzIGFyb3VuZC4KCSAqLwoJaWYgKGN0eC0+dGFzayAmJiBjcHVjdHgtPnRhc2tfY3R4ICE9IGN0eCkKCQlyZXR1cm4gLUVJTlZBTDsKCglyYXdfc3Bpbl9sb2NrKCZjdHgtPmxvY2spOwoKCS8qCgkgKiBJZiB0aGUgZXZlbnQgaXMgb24sIHR1cm4gaXQgb2ZmLgoJICogSWYgaXQgaXMgaW4gZXJyb3Igc3RhdGUsIGxlYXZlIGl0IGluIGVycm9yIHN0YXRlLgoJICovCglpZiAoZXZlbnQtPnN0YXRlID49IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUpIHsKCQl1cGRhdGVfY29udGV4dF90aW1lKGN0eCk7CgkJdXBkYXRlX2dyb3VwX3RpbWVzKGV2ZW50KTsKCQlpZiAoZXZlbnQgPT0gZXZlbnQtPmdyb3VwX2xlYWRlcikKCQkJZ3JvdXBfc2NoZWRfb3V0KGV2ZW50LCBjcHVjdHgsIGN0eCk7CgkJZWxzZQoJCQlldmVudF9zY2hlZF9vdXQoZXZlbnQsIGNwdWN0eCwgY3R4KTsKCQlldmVudC0+c3RhdGUgPSBQRVJGX0VWRU5UX1NUQVRFX09GRjsKCX0KCglyYXdfc3Bpbl91bmxvY2soJmN0eC0+bG9jayk7CgoJcmV0dXJuIDA7Cn0KCi8qCiAqIERpc2FibGUgYSBldmVudC4KICoKICogSWYgZXZlbnQtPmN0eCBpcyBhIGNsb25lZCBjb250ZXh0LCBjYWxsZXJzIG11c3QgbWFrZSBzdXJlIHRoYXQKICogZXZlcnkgdGFzayBzdHJ1Y3QgdGhhdCBldmVudC0+Y3R4LT50YXNrIGNvdWxkIHBvc3NpYmx5IHBvaW50IHRvCiAqIHJlbWFpbnMgdmFsaWQuICBUaGlzIGNvbmRpdGlvbiBpcyBzYXRpc2lmZWQgd2hlbiBjYWxsZWQgdGhyb3VnaAogKiBwZXJmX2V2ZW50X2Zvcl9lYWNoX2NoaWxkIG9yIHBlcmZfZXZlbnRfZm9yX2VhY2ggYmVjYXVzZSB0aGV5CiAqIGhvbGQgdGhlIHRvcC1sZXZlbCBldmVudCdzIGNoaWxkX211dGV4LCBzbyBhbnkgZGVzY2VuZGFudCB0aGF0CiAqIGdvZXMgdG8gZXhpdCB3aWxsIGJsb2NrIGluIHN5bmNfY2hpbGRfZXZlbnQuCiAqIFdoZW4gY2FsbGVkIGZyb20gcGVyZl9wZW5kaW5nX2V2ZW50IGl0J3MgT0sgYmVjYXVzZSBldmVudC0+Y3R4CiAqIGlzIHRoZSBjdXJyZW50IGNvbnRleHQgb24gdGhpcyBDUFUgYW5kIHByZWVtcHRpb24gaXMgZGlzYWJsZWQsCiAqIGhlbmNlIHdlIGNhbid0IGdldCBpbnRvIHBlcmZfZXZlbnRfdGFza19zY2hlZF9vdXQgZm9yIHRoaXMgY29udGV4dC4KICovCnZvaWQgcGVyZl9ldmVudF9kaXNhYmxlKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4ID0gZXZlbnQtPmN0eDsKCXN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzayA9IGN0eC0+dGFzazsKCglpZiAoIXRhc2spIHsKCQkvKgoJCSAqIERpc2FibGUgdGhlIGV2ZW50IG9uIHRoZSBjcHUgdGhhdCBpdCdzIG9uCgkJICovCgkJY3B1X2Z1bmN0aW9uX2NhbGwoZXZlbnQtPmNwdSwgX19wZXJmX2V2ZW50X2Rpc2FibGUsIGV2ZW50KTsKCQlyZXR1cm47Cgl9CgpyZXRyeToKCWlmICghdGFza19mdW5jdGlvbl9jYWxsKHRhc2ssIF9fcGVyZl9ldmVudF9kaXNhYmxlLCBldmVudCkpCgkJcmV0dXJuOwoKCXJhd19zcGluX2xvY2tfaXJxKCZjdHgtPmxvY2spOwoJLyoKCSAqIElmIHRoZSBldmVudCBpcyBzdGlsbCBhY3RpdmUsIHdlIG5lZWQgdG8gcmV0cnkgdGhlIGNyb3NzLWNhbGwuCgkgKi8KCWlmIChldmVudC0+c3RhdGUgPT0gUEVSRl9FVkVOVF9TVEFURV9BQ1RJVkUpIHsKCQlyYXdfc3Bpbl91bmxvY2tfaXJxKCZjdHgtPmxvY2spOwoJCS8qCgkJICogUmVsb2FkIHRoZSB0YXNrIHBvaW50ZXIsIGl0IG1pZ2h0IGhhdmUgYmVlbiBjaGFuZ2VkIGJ5CgkJICogYSBjb25jdXJyZW50IHBlcmZfZXZlbnRfY29udGV4dF9zY2hlZF9vdXQoKS4KCQkgKi8KCQl0YXNrID0gY3R4LT50YXNrOwoJCWdvdG8gcmV0cnk7Cgl9CgoJLyoKCSAqIFNpbmNlIHdlIGhhdmUgdGhlIGxvY2sgdGhpcyBjb250ZXh0IGNhbid0IGJlIHNjaGVkdWxlZAoJICogaW4sIHNvIHdlIGNhbiBjaGFuZ2UgdGhlIHN0YXRlIHNhZmVseS4KCSAqLwoJaWYgKGV2ZW50LT5zdGF0ZSA9PSBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFKSB7CgkJdXBkYXRlX2dyb3VwX3RpbWVzKGV2ZW50KTsKCQlldmVudC0+c3RhdGUgPSBQRVJGX0VWRU5UX1NUQVRFX09GRjsKCX0KCXJhd19zcGluX3VubG9ja19pcnEoJmN0eC0+bG9jayk7Cn0KCiNkZWZpbmUgTUFYX0lOVEVSUlVQVFMgKH4wVUxMKQoKc3RhdGljIHZvaWQgcGVyZl9sb2dfdGhyb3R0bGUoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBpbnQgZW5hYmxlKTsKCnN0YXRpYyBpbnQKZXZlbnRfc2NoZWRfaW4oc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCSBzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4LAoJCSBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgpCnsKCXU2NCB0c3RhbXAgPSBwZXJmX2V2ZW50X3RpbWUoZXZlbnQpOwoKCWlmIChldmVudC0+c3RhdGUgPD0gUEVSRl9FVkVOVF9TVEFURV9PRkYpCgkJcmV0dXJuIDA7CgoJZXZlbnQtPnN0YXRlID0gUEVSRl9FVkVOVF9TVEFURV9BQ1RJVkU7CglldmVudC0+b25jcHUgPSBzbXBfcHJvY2Vzc29yX2lkKCk7CgoJLyoKCSAqIFVudGhyb3R0bGUgZXZlbnRzLCBzaW5jZSB3ZSBzY2hlZHVsZWQgd2UgbWlnaHQgaGF2ZSBtaXNzZWQgc2V2ZXJhbAoJICogdGlja3MgYWxyZWFkeSwgYWxzbyBmb3IgYSBoZWF2aWx5IHNjaGVkdWxpbmcgdGFzayB0aGVyZSBpcyBsaXR0bGUKCSAqIGd1YXJhbnRlZSBpdCdsbCBnZXQgYSB0aWNrIGluIGEgdGltZWx5IG1hbm5lci4KCSAqLwoJaWYgKHVubGlrZWx5KGV2ZW50LT5ody5pbnRlcnJ1cHRzID09IE1BWF9JTlRFUlJVUFRTKSkgewoJCXBlcmZfbG9nX3Rocm90dGxlKGV2ZW50LCAxKTsKCQlldmVudC0+aHcuaW50ZXJydXB0cyA9IDA7Cgl9CgoJLyoKCSAqIFRoZSBuZXcgc3RhdGUgbXVzdCBiZSB2aXNpYmxlIGJlZm9yZSB3ZSB0dXJuIGl0IG9uIGluIHRoZSBoYXJkd2FyZToKCSAqLwoJc21wX3dtYigpOwoKCWlmIChldmVudC0+cG11LT5hZGQoZXZlbnQsIFBFUkZfRUZfU1RBUlQpKSB7CgkJZXZlbnQtPnN0YXRlID0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRTsKCQlldmVudC0+b25jcHUgPSAtMTsKCQlyZXR1cm4gLUVBR0FJTjsKCX0KCglldmVudC0+dHN0YW1wX3J1bm5pbmcgKz0gdHN0YW1wIC0gZXZlbnQtPnRzdGFtcF9zdG9wcGVkOwoKCWV2ZW50LT5zaGFkb3dfY3R4X3RpbWUgPSB0c3RhbXAgLSBjdHgtPnRpbWVzdGFtcDsKCglpZiAoIWlzX3NvZnR3YXJlX2V2ZW50KGV2ZW50KSkKCQljcHVjdHgtPmFjdGl2ZV9vbmNwdSsrOwoJY3R4LT5ucl9hY3RpdmUrKzsKCglpZiAoZXZlbnQtPmF0dHIuZXhjbHVzaXZlKQoJCWNwdWN0eC0+ZXhjbHVzaXZlID0gMTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIGludApncm91cF9zY2hlZF9pbihzdHJ1Y3QgcGVyZl9ldmVudCAqZ3JvdXBfZXZlbnQsCgkgICAgICAgc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCwKCSAgICAgICBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgKnBhcnRpYWxfZ3JvdXAgPSBOVUxMOwoJc3RydWN0IHBtdSAqcG11ID0gZ3JvdXBfZXZlbnQtPnBtdTsKCXU2NCBub3cgPSBjdHgtPnRpbWU7Cglib29sIHNpbXVsYXRlID0gZmFsc2U7CgoJaWYgKGdyb3VwX2V2ZW50LT5zdGF0ZSA9PSBQRVJGX0VWRU5UX1NUQVRFX09GRikKCQlyZXR1cm4gMDsKCglwbXUtPnN0YXJ0X3R4bihwbXUpOwoKCWlmIChldmVudF9zY2hlZF9pbihncm91cF9ldmVudCwgY3B1Y3R4LCBjdHgpKSB7CgkJcG11LT5jYW5jZWxfdHhuKHBtdSk7CgkJcmV0dXJuIC1FQUdBSU47Cgl9CgoJLyoKCSAqIFNjaGVkdWxlIGluIHNpYmxpbmdzIGFzIG9uZSBncm91cCAoaWYgYW55KToKCSAqLwoJbGlzdF9mb3JfZWFjaF9lbnRyeShldmVudCwgJmdyb3VwX2V2ZW50LT5zaWJsaW5nX2xpc3QsIGdyb3VwX2VudHJ5KSB7CgkJaWYgKGV2ZW50X3NjaGVkX2luKGV2ZW50LCBjcHVjdHgsIGN0eCkpIHsKCQkJcGFydGlhbF9ncm91cCA9IGV2ZW50OwoJCQlnb3RvIGdyb3VwX2Vycm9yOwoJCX0KCX0KCglpZiAoIXBtdS0+Y29tbWl0X3R4bihwbXUpKQoJCXJldHVybiAwOwoKZ3JvdXBfZXJyb3I6CgkvKgoJICogR3JvdXBzIGNhbiBiZSBzY2hlZHVsZWQgaW4gYXMgb25lIHVuaXQgb25seSwgc28gdW5kbyBhbnkKCSAqIHBhcnRpYWwgZ3JvdXAgYmVmb3JlIHJldHVybmluZzoKCSAqIFRoZSBldmVudHMgdXAgdG8gdGhlIGZhaWxlZCBldmVudCBhcmUgc2NoZWR1bGVkIG91dCBub3JtYWxseSwKCSAqIHRzdGFtcF9zdG9wcGVkIHdpbGwgYmUgdXBkYXRlZC4KCSAqCgkgKiBUaGUgZmFpbGVkIGV2ZW50cyBhbmQgdGhlIHJlbWFpbmluZyBzaWJsaW5ncyBuZWVkIHRvIGhhdmUKCSAqIHRoZWlyIHRpbWluZ3MgdXBkYXRlZCBhcyBpZiB0aGV5IGhhZCBnb25lIHRocnUgZXZlbnRfc2NoZWRfaW4oKQoJICogYW5kIGV2ZW50X3NjaGVkX291dCgpLiBUaGlzIGlzIHJlcXVpcmVkIHRvIGdldCBjb25zaXN0ZW50IHRpbWluZ3MKCSAqIGFjcm9zcyB0aGUgZ3JvdXAuIFRoaXMgYWxzbyB0YWtlcyBjYXJlIG9mIHRoZSBjYXNlIHdoZXJlIHRoZSBncm91cAoJICogY291bGQgbmV2ZXIgYmUgc2NoZWR1bGVkIGJ5IGVuc3VyaW5nIHRzdGFtcF9zdG9wcGVkIGlzIHNldCB0byBtYXJrCgkgKiB0aGUgdGltZSB0aGUgZXZlbnQgd2FzIGFjdHVhbGx5IHN0b3BwZWQsIHN1Y2ggdGhhdCB0aW1lIGRlbHRhCgkgKiBjYWxjdWxhdGlvbiBpbiB1cGRhdGVfZXZlbnRfdGltZXMoKSBpcyBjb3JyZWN0LgoJICovCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGV2ZW50LCAmZ3JvdXBfZXZlbnQtPnNpYmxpbmdfbGlzdCwgZ3JvdXBfZW50cnkpIHsKCQlpZiAoZXZlbnQgPT0gcGFydGlhbF9ncm91cCkKCQkJc2ltdWxhdGUgPSB0cnVlOwoKCQlpZiAoc2ltdWxhdGUpIHsKCQkJZXZlbnQtPnRzdGFtcF9ydW5uaW5nICs9IG5vdyAtIGV2ZW50LT50c3RhbXBfc3RvcHBlZDsKCQkJZXZlbnQtPnRzdGFtcF9zdG9wcGVkID0gbm93OwoJCX0gZWxzZSB7CgkJCWV2ZW50X3NjaGVkX291dChldmVudCwgY3B1Y3R4LCBjdHgpOwoJCX0KCX0KCWV2ZW50X3NjaGVkX291dChncm91cF9ldmVudCwgY3B1Y3R4LCBjdHgpOwoKCXBtdS0+Y2FuY2VsX3R4bihwbXUpOwoKCXJldHVybiAtRUFHQUlOOwp9CgovKgogKiBXb3JrIG91dCB3aGV0aGVyIHdlIGNhbiBwdXQgdGhpcyBldmVudCBncm91cCBvbiB0aGUgQ1BVIG5vdy4KICovCnN0YXRpYyBpbnQgZ3JvdXBfY2FuX2dvX29uKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJICAgc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCwKCQkJICAgaW50IGNhbl9hZGRfaHcpCnsKCS8qCgkgKiBHcm91cHMgY29uc2lzdGluZyBlbnRpcmVseSBvZiBzb2Z0d2FyZSBldmVudHMgY2FuIGFsd2F5cyBnbyBvbi4KCSAqLwoJaWYgKGV2ZW50LT5ncm91cF9mbGFncyAmIFBFUkZfR1JPVVBfU09GVFdBUkUpCgkJcmV0dXJuIDE7CgkvKgoJICogSWYgYW4gZXhjbHVzaXZlIGdyb3VwIGlzIGFscmVhZHkgb24sIG5vIG90aGVyIGhhcmR3YXJlCgkgKiBldmVudHMgY2FuIGdvIG9uLgoJICovCglpZiAoY3B1Y3R4LT5leGNsdXNpdmUpCgkJcmV0dXJuIDA7CgkvKgoJICogSWYgdGhpcyBncm91cCBpcyBleGNsdXNpdmUgYW5kIHRoZXJlIGFyZSBhbHJlYWR5CgkgKiBldmVudHMgb24gdGhlIENQVSwgaXQgY2FuJ3QgZ28gb24uCgkgKi8KCWlmIChldmVudC0+YXR0ci5leGNsdXNpdmUgJiYgY3B1Y3R4LT5hY3RpdmVfb25jcHUpCgkJcmV0dXJuIDA7CgkvKgoJICogT3RoZXJ3aXNlLCB0cnkgdG8gYWRkIGl0IGlmIGFsbCBwcmV2aW91cyBncm91cHMgd2VyZSBhYmxlCgkgKiB0byBnbyBvbi4KCSAqLwoJcmV0dXJuIGNhbl9hZGRfaHc7Cn0KCnN0YXRpYyB2b2lkIGFkZF9ldmVudF90b19jdHgoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkgICAgICAgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7Cgl1NjQgdHN0YW1wID0gcGVyZl9ldmVudF90aW1lKGV2ZW50KTsKCglsaXN0X2FkZF9ldmVudChldmVudCwgY3R4KTsKCXBlcmZfZ3JvdXBfYXR0YWNoKGV2ZW50KTsKCWV2ZW50LT50c3RhbXBfZW5hYmxlZCA9IHRzdGFtcDsKCWV2ZW50LT50c3RhbXBfcnVubmluZyA9IHRzdGFtcDsKCWV2ZW50LT50c3RhbXBfc3RvcHBlZCA9IHRzdGFtcDsKfQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9jb250ZXh0X3NjaGVkX2luKHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCk7CgovKgogKiBDcm9zcyBDUFUgY2FsbCB0byBpbnN0YWxsIGFuZCBlbmFibGUgYSBwZXJmb3JtYW5jZSBldmVudAogKgogKiBNdXN0IGJlIGNhbGxlZCB3aXRoIGN0eC0+bXV0ZXggaGVsZAogKi8Kc3RhdGljIGludCAgX19wZXJmX2luc3RhbGxfaW5fY29udGV4dCh2b2lkICppbmZvKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQgPSBpbmZvOwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4ID0gZXZlbnQtPmN0eDsKCXN0cnVjdCBwZXJmX2V2ZW50ICpsZWFkZXIgPSBldmVudC0+Z3JvdXBfbGVhZGVyOwoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCA9IF9fZ2V0X2NwdV9jb250ZXh0KGN0eCk7CglpbnQgZXJyOwoKCS8qCgkgKiBJbiBjYXNlIHdlJ3JlIGluc3RhbGxpbmcgYSBuZXcgY29udGV4dCB0byBhbiBhbHJlYWR5IHJ1bm5pbmcgdGFzaywKCSAqIGNvdWxkIGFsc28gaGFwcGVuIGJlZm9yZSBwZXJmX2V2ZW50X3Rhc2tfc2NoZWRfaW4oKSBvbiBhcmNoaXRlY3R1cmVzCgkgKiB3aGljaCBkbyBjb250ZXh0IHN3aXRjaGVzIHdpdGggSVJRcyBlbmFibGVkLgoJICovCglpZiAoY3R4LT50YXNrICYmICFjcHVjdHgtPnRhc2tfY3R4KQoJCXBlcmZfZXZlbnRfY29udGV4dF9zY2hlZF9pbihjdHgpOwoKCXJhd19zcGluX2xvY2soJmN0eC0+bG9jayk7CgljdHgtPmlzX2FjdGl2ZSA9IDE7Cgl1cGRhdGVfY29udGV4dF90aW1lKGN0eCk7CgoJYWRkX2V2ZW50X3RvX2N0eChldmVudCwgY3R4KTsKCglpZiAoIWV2ZW50X2ZpbHRlcl9tYXRjaChldmVudCkpCgkJZ290byB1bmxvY2s7CgoJLyoKCSAqIERvbid0IHB1dCB0aGUgZXZlbnQgb24gaWYgaXQgaXMgZGlzYWJsZWQgb3IgaWYKCSAqIGl0IGlzIGluIGEgZ3JvdXAgYW5kIHRoZSBncm91cCBpc24ndCBvbi4KCSAqLwoJaWYgKGV2ZW50LT5zdGF0ZSAhPSBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFIHx8CgkgICAgKGxlYWRlciAhPSBldmVudCAmJiBsZWFkZXItPnN0YXRlICE9IFBFUkZfRVZFTlRfU1RBVEVfQUNUSVZFKSkKCQlnb3RvIHVubG9jazsKCgkvKgoJICogQW4gZXhjbHVzaXZlIGV2ZW50IGNhbid0IGdvIG9uIGlmIHRoZXJlIGFyZSBhbHJlYWR5IGFjdGl2ZQoJICogaGFyZHdhcmUgZXZlbnRzLCBhbmQgbm8gaGFyZHdhcmUgZXZlbnQgY2FuIGdvIG9uIGlmIHRoZXJlCgkgKiBpcyBhbHJlYWR5IGFuIGV4Y2x1c2l2ZSBldmVudCBvbi4KCSAqLwoJaWYgKCFncm91cF9jYW5fZ29fb24oZXZlbnQsIGNwdWN0eCwgMSkpCgkJZXJyID0gLUVFWElTVDsKCWVsc2UKCQllcnIgPSBldmVudF9zY2hlZF9pbihldmVudCwgY3B1Y3R4LCBjdHgpOwoKCWlmIChlcnIpIHsKCQkvKgoJCSAqIFRoaXMgZXZlbnQgY291bGRuJ3QgZ28gb24uICBJZiBpdCBpcyBpbiBhIGdyb3VwCgkJICogdGhlbiB3ZSBoYXZlIHRvIHB1bGwgdGhlIHdob2xlIGdyb3VwIG9mZi4KCQkgKiBJZiB0aGUgZXZlbnQgZ3JvdXAgaXMgcGlubmVkIHRoZW4gcHV0IGl0IGluIGVycm9yIHN0YXRlLgoJCSAqLwoJCWlmIChsZWFkZXIgIT0gZXZlbnQpCgkJCWdyb3VwX3NjaGVkX291dChsZWFkZXIsIGNwdWN0eCwgY3R4KTsKCQlpZiAobGVhZGVyLT5hdHRyLnBpbm5lZCkgewoJCQl1cGRhdGVfZ3JvdXBfdGltZXMobGVhZGVyKTsKCQkJbGVhZGVyLT5zdGF0ZSA9IFBFUkZfRVZFTlRfU1RBVEVfRVJST1I7CgkJfQoJfQoKdW5sb2NrOgoJcmF3X3NwaW5fdW5sb2NrKCZjdHgtPmxvY2spOwoKCXJldHVybiAwOwp9CgovKgogKiBBdHRhY2ggYSBwZXJmb3JtYW5jZSBldmVudCB0byBhIGNvbnRleHQKICoKICogRmlyc3Qgd2UgYWRkIHRoZSBldmVudCB0byB0aGUgbGlzdCB3aXRoIHRoZSBoYXJkd2FyZSBlbmFibGUgYml0CiAqIGluIGV2ZW50LT5od19jb25maWcgY2xlYXJlZC4KICoKICogSWYgdGhlIGV2ZW50IGlzIGF0dGFjaGVkIHRvIGEgdGFzayB3aGljaCBpcyBvbiBhIENQVSB3ZSB1c2UgYSBzbXAKICogY2FsbCB0byBlbmFibGUgaXQgaW4gdGhlIHRhc2sgY29udGV4dC4gVGhlIHRhc2sgbWlnaHQgaGF2ZSBiZWVuCiAqIHNjaGVkdWxlZCBhd2F5LCBidXQgd2UgY2hlY2sgdGhpcyBpbiB0aGUgc21wIGNhbGwgYWdhaW4uCiAqLwpzdGF0aWMgdm9pZApwZXJmX2luc3RhbGxfaW5fY29udGV4dChzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgsCgkJCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJaW50IGNwdSkKewoJc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrID0gY3R4LT50YXNrOwoKCWxvY2tkZXBfYXNzZXJ0X2hlbGQoJmN0eC0+bXV0ZXgpOwoKCWV2ZW50LT5jdHggPSBjdHg7CgoJaWYgKCF0YXNrKSB7CgkJLyoKCQkgKiBQZXIgY3B1IGV2ZW50cyBhcmUgaW5zdGFsbGVkIHZpYSBhbiBzbXAgY2FsbCBhbmQKCQkgKiB0aGUgaW5zdGFsbCBpcyBhbHdheXMgc3VjY2Vzc2Z1bC4KCQkgKi8KCQljcHVfZnVuY3Rpb25fY2FsbChjcHUsIF9fcGVyZl9pbnN0YWxsX2luX2NvbnRleHQsIGV2ZW50KTsKCQlyZXR1cm47Cgl9CgpyZXRyeToKCWlmICghdGFza19mdW5jdGlvbl9jYWxsKHRhc2ssIF9fcGVyZl9pbnN0YWxsX2luX2NvbnRleHQsIGV2ZW50KSkKCQlyZXR1cm47CgoJcmF3X3NwaW5fbG9ja19pcnEoJmN0eC0+bG9jayk7CgkvKgoJICogSWYgd2UgZmFpbGVkIHRvIGZpbmQgYSBydW5uaW5nIHRhc2ssIGJ1dCBmaW5kIHRoZSBjb250ZXh0IGFjdGl2ZSBub3cKCSAqIHRoYXQgd2UndmUgYWNxdWlyZWQgdGhlIGN0eC0+bG9jaywgcmV0cnkuCgkgKi8KCWlmIChjdHgtPmlzX2FjdGl2ZSkgewoJCXJhd19zcGluX3VubG9ja19pcnEoJmN0eC0+bG9jayk7CgkJZ290byByZXRyeTsKCX0KCgkvKgoJICogU2luY2UgdGhlIHRhc2sgaXNuJ3QgcnVubmluZywgaXRzIHNhZmUgdG8gYWRkIHRoZSBldmVudCwgdXMgaG9sZGluZwoJICogdGhlIGN0eC0+bG9jayBlbnN1cmVzIHRoZSB0YXNrIHdvbid0IGdldCBzY2hlZHVsZWQgaW4uCgkgKi8KCWFkZF9ldmVudF90b19jdHgoZXZlbnQsIGN0eCk7CglyYXdfc3Bpbl91bmxvY2tfaXJxKCZjdHgtPmxvY2spOwp9CgovKgogKiBQdXQgYSBldmVudCBpbnRvIGluYWN0aXZlIHN0YXRlIGFuZCB1cGRhdGUgdGltZSBmaWVsZHMuCiAqIEVuYWJsaW5nIHRoZSBsZWFkZXIgb2YgYSBncm91cCBlZmZlY3RpdmVseSBlbmFibGVzIGFsbAogKiB0aGUgZ3JvdXAgbWVtYmVycyB0aGF0IGFyZW4ndCBleHBsaWNpdGx5IGRpc2FibGVkLCBzbyB3ZQogKiBoYXZlIHRvIHVwZGF0ZSB0aGVpciAtPnRzdGFtcF9lbmFibGVkIGFsc28uCiAqIE5vdGU6IHRoaXMgd29ya3MgZm9yIGdyb3VwIG1lbWJlcnMgYXMgd2VsbCBhcyBncm91cCBsZWFkZXJzCiAqIHNpbmNlIHRoZSBub24tbGVhZGVyIG1lbWJlcnMnIHNpYmxpbmdfbGlzdHMgd2lsbCBiZSBlbXB0eS4KICovCnN0YXRpYyB2b2lkIF9fcGVyZl9ldmVudF9tYXJrX2VuYWJsZWQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKnN1YjsKCXU2NCB0c3RhbXAgPSBwZXJmX2V2ZW50X3RpbWUoZXZlbnQpOwoKCWV2ZW50LT5zdGF0ZSA9IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkU7CglldmVudC0+dHN0YW1wX2VuYWJsZWQgPSB0c3RhbXAgLSBldmVudC0+dG90YWxfdGltZV9lbmFibGVkOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShzdWIsICZldmVudC0+c2libGluZ19saXN0LCBncm91cF9lbnRyeSkgewoJCWlmIChzdWItPnN0YXRlID49IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUpCgkJCXN1Yi0+dHN0YW1wX2VuYWJsZWQgPSB0c3RhbXAgLSBzdWItPnRvdGFsX3RpbWVfZW5hYmxlZDsKCX0KfQoKLyoKICogQ3Jvc3MgQ1BVIGNhbGwgdG8gZW5hYmxlIGEgcGVyZm9ybWFuY2UgZXZlbnQKICovCnN0YXRpYyBpbnQgX19wZXJmX2V2ZW50X2VuYWJsZSh2b2lkICppbmZvKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQgPSBpbmZvOwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4ID0gZXZlbnQtPmN0eDsKCXN0cnVjdCBwZXJmX2V2ZW50ICpsZWFkZXIgPSBldmVudC0+Z3JvdXBfbGVhZGVyOwoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCA9IF9fZ2V0X2NwdV9jb250ZXh0KGN0eCk7CglpbnQgZXJyOwoKCWlmIChXQVJOX09OX09OQ0UoIWN0eC0+aXNfYWN0aXZlKSkKCQlyZXR1cm4gLUVJTlZBTDsKCglyYXdfc3Bpbl9sb2NrKCZjdHgtPmxvY2spOwoJdXBkYXRlX2NvbnRleHRfdGltZShjdHgpOwoKCWlmIChldmVudC0+c3RhdGUgPj0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRSkKCQlnb3RvIHVubG9jazsKCV9fcGVyZl9ldmVudF9tYXJrX2VuYWJsZWQoZXZlbnQsIGN0eCk7CgoJaWYgKCFldmVudF9maWx0ZXJfbWF0Y2goZXZlbnQpKQoJCWdvdG8gdW5sb2NrOwoKCS8qCgkgKiBJZiB0aGUgZXZlbnQgaXMgaW4gYSBncm91cCBhbmQgaXNuJ3QgdGhlIGdyb3VwIGxlYWRlciwKCSAqIHRoZW4gZG9uJ3QgcHV0IGl0IG9uIHVubGVzcyB0aGUgZ3JvdXAgaXMgb24uCgkgKi8KCWlmIChsZWFkZXIgIT0gZXZlbnQgJiYgbGVhZGVyLT5zdGF0ZSAhPSBQRVJGX0VWRU5UX1NUQVRFX0FDVElWRSkKCQlnb3RvIHVubG9jazsKCglpZiAoIWdyb3VwX2Nhbl9nb19vbihldmVudCwgY3B1Y3R4LCAxKSkgewoJCWVyciA9IC1FRVhJU1Q7Cgl9IGVsc2UgewoJCWlmIChldmVudCA9PSBsZWFkZXIpCgkJCWVyciA9IGdyb3VwX3NjaGVkX2luKGV2ZW50LCBjcHVjdHgsIGN0eCk7CgkJZWxzZQoJCQllcnIgPSBldmVudF9zY2hlZF9pbihldmVudCwgY3B1Y3R4LCBjdHgpOwoJfQoKCWlmIChlcnIpIHsKCQkvKgoJCSAqIElmIHRoaXMgZXZlbnQgY2FuJ3QgZ28gb24gYW5kIGl0J3MgcGFydCBvZiBhCgkJICogZ3JvdXAsIHRoZW4gdGhlIHdob2xlIGdyb3VwIGhhcyB0byBjb21lIG9mZi4KCQkgKi8KCQlpZiAobGVhZGVyICE9IGV2ZW50KQoJCQlncm91cF9zY2hlZF9vdXQobGVhZGVyLCBjcHVjdHgsIGN0eCk7CgkJaWYgKGxlYWRlci0+YXR0ci5waW5uZWQpIHsKCQkJdXBkYXRlX2dyb3VwX3RpbWVzKGxlYWRlcik7CgkJCWxlYWRlci0+c3RhdGUgPSBQRVJGX0VWRU5UX1NUQVRFX0VSUk9SOwoJCX0KCX0KCnVubG9jazoKCXJhd19zcGluX3VubG9jaygmY3R4LT5sb2NrKTsKCglyZXR1cm4gMDsKfQoKLyoKICogRW5hYmxlIGEgZXZlbnQuCiAqCiAqIElmIGV2ZW50LT5jdHggaXMgYSBjbG9uZWQgY29udGV4dCwgY2FsbGVycyBtdXN0IG1ha2Ugc3VyZSB0aGF0CiAqIGV2ZXJ5IHRhc2sgc3RydWN0IHRoYXQgZXZlbnQtPmN0eC0+dGFzayBjb3VsZCBwb3NzaWJseSBwb2ludCB0bwogKiByZW1haW5zIHZhbGlkLiAgVGhpcyBjb25kaXRpb24gaXMgc2F0aXNmaWVkIHdoZW4gY2FsbGVkIHRocm91Z2gKICogcGVyZl9ldmVudF9mb3JfZWFjaF9jaGlsZCBvciBwZXJmX2V2ZW50X2Zvcl9lYWNoIGFzIGRlc2NyaWJlZAogKiBmb3IgcGVyZl9ldmVudF9kaXNhYmxlLgogKi8Kdm9pZCBwZXJmX2V2ZW50X2VuYWJsZShzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IGV2ZW50LT5jdHg7CglzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2sgPSBjdHgtPnRhc2s7CgoJaWYgKCF0YXNrKSB7CgkJLyoKCQkgKiBFbmFibGUgdGhlIGV2ZW50IG9uIHRoZSBjcHUgdGhhdCBpdCdzIG9uCgkJICovCgkJY3B1X2Z1bmN0aW9uX2NhbGwoZXZlbnQtPmNwdSwgX19wZXJmX2V2ZW50X2VuYWJsZSwgZXZlbnQpOwoJCXJldHVybjsKCX0KCglyYXdfc3Bpbl9sb2NrX2lycSgmY3R4LT5sb2NrKTsKCWlmIChldmVudC0+c3RhdGUgPj0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRSkKCQlnb3RvIG91dDsKCgkvKgoJICogSWYgdGhlIGV2ZW50IGlzIGluIGVycm9yIHN0YXRlLCBjbGVhciB0aGF0IGZpcnN0LgoJICogVGhhdCB3YXksIGlmIHdlIHNlZSB0aGUgZXZlbnQgaW4gZXJyb3Igc3RhdGUgYmVsb3csIHdlCgkgKiBrbm93IHRoYXQgaXQgaGFzIGdvbmUgYmFjayBpbnRvIGVycm9yIHN0YXRlLCBhcyBkaXN0aW5jdAoJICogZnJvbSB0aGUgdGFzayBoYXZpbmcgYmVlbiBzY2hlZHVsZWQgYXdheSBiZWZvcmUgdGhlCgkgKiBjcm9zcy1jYWxsIGFycml2ZWQuCgkgKi8KCWlmIChldmVudC0+c3RhdGUgPT0gUEVSRl9FVkVOVF9TVEFURV9FUlJPUikKCQlldmVudC0+c3RhdGUgPSBQRVJGX0VWRU5UX1NUQVRFX09GRjsKCnJldHJ5OgoJaWYgKCFjdHgtPmlzX2FjdGl2ZSkgewoJCV9fcGVyZl9ldmVudF9tYXJrX2VuYWJsZWQoZXZlbnQsIGN0eCk7CgkJZ290byBvdXQ7Cgl9CgoJcmF3X3NwaW5fdW5sb2NrX2lycSgmY3R4LT5sb2NrKTsKCglpZiAoIXRhc2tfZnVuY3Rpb25fY2FsbCh0YXNrLCBfX3BlcmZfZXZlbnRfZW5hYmxlLCBldmVudCkpCgkJcmV0dXJuOwoKCXJhd19zcGluX2xvY2tfaXJxKCZjdHgtPmxvY2spOwoKCS8qCgkgKiBJZiB0aGUgY29udGV4dCBpcyBhY3RpdmUgYW5kIHRoZSBldmVudCBpcyBzdGlsbCBvZmYsCgkgKiB3ZSBuZWVkIHRvIHJldHJ5IHRoZSBjcm9zcy1jYWxsLgoJICovCglpZiAoY3R4LT5pc19hY3RpdmUgJiYgZXZlbnQtPnN0YXRlID09IFBFUkZfRVZFTlRfU1RBVEVfT0ZGKSB7CgkJLyoKCQkgKiB0YXNrIGNvdWxkIGhhdmUgYmVlbiBmbGlwcGVkIGJ5IGEgY29uY3VycmVudAoJCSAqIHBlcmZfZXZlbnRfY29udGV4dF9zY2hlZF9vdXQoKQoJCSAqLwoJCXRhc2sgPSBjdHgtPnRhc2s7CgkJZ290byByZXRyeTsKCX0KCm91dDoKCXJhd19zcGluX3VubG9ja19pcnEoJmN0eC0+bG9jayk7Cn0KCnN0YXRpYyBpbnQgcGVyZl9ldmVudF9yZWZyZXNoKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgaW50IHJlZnJlc2gpCnsKCS8qCgkgKiBub3Qgc3VwcG9ydGVkIG9uIGluaGVyaXRlZCBldmVudHMKCSAqLwoJaWYgKGV2ZW50LT5hdHRyLmluaGVyaXQgfHwgIWlzX3NhbXBsaW5nX2V2ZW50KGV2ZW50KSkKCQlyZXR1cm4gLUVJTlZBTDsKCglhdG9taWNfYWRkKHJlZnJlc2gsICZldmVudC0+ZXZlbnRfbGltaXQpOwoJcGVyZl9ldmVudF9lbmFibGUoZXZlbnQpOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBjdHhfc2NoZWRfb3V0KHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCwKCQkJICBzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4LAoJCQkgIGVudW0gZXZlbnRfdHlwZV90IGV2ZW50X3R5cGUpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCglyYXdfc3Bpbl9sb2NrKCZjdHgtPmxvY2spOwoJcGVyZl9wbXVfZGlzYWJsZShjdHgtPnBtdSk7CgljdHgtPmlzX2FjdGl2ZSA9IDA7CglpZiAobGlrZWx5KCFjdHgtPm5yX2V2ZW50cykpCgkJZ290byBvdXQ7Cgl1cGRhdGVfY29udGV4dF90aW1lKGN0eCk7CgoJaWYgKCFjdHgtPm5yX2FjdGl2ZSkKCQlnb3RvIG91dDsKCglpZiAoZXZlbnRfdHlwZSAmIEVWRU5UX1BJTk5FRCkgewoJCWxpc3RfZm9yX2VhY2hfZW50cnkoZXZlbnQsICZjdHgtPnBpbm5lZF9ncm91cHMsIGdyb3VwX2VudHJ5KQoJCQlncm91cF9zY2hlZF9vdXQoZXZlbnQsIGNwdWN0eCwgY3R4KTsKCX0KCglpZiAoZXZlbnRfdHlwZSAmIEVWRU5UX0ZMRVhJQkxFKSB7CgkJbGlzdF9mb3JfZWFjaF9lbnRyeShldmVudCwgJmN0eC0+ZmxleGlibGVfZ3JvdXBzLCBncm91cF9lbnRyeSkKCQkJZ3JvdXBfc2NoZWRfb3V0KGV2ZW50LCBjcHVjdHgsIGN0eCk7Cgl9Cm91dDoKCXBlcmZfcG11X2VuYWJsZShjdHgtPnBtdSk7CglyYXdfc3Bpbl91bmxvY2soJmN0eC0+bG9jayk7Cn0KCi8qCiAqIFRlc3Qgd2hldGhlciB0d28gY29udGV4dHMgYXJlIGVxdWl2YWxlbnQsIGkuZS4gd2hldGhlciB0aGV5CiAqIGhhdmUgYm90aCBiZWVuIGNsb25lZCBmcm9tIHRoZSBzYW1lIHZlcnNpb24gb2YgdGhlIHNhbWUgY29udGV4dAogKiBhbmQgdGhleSBib3RoIGhhdmUgdGhlIHNhbWUgbnVtYmVyIG9mIGVuYWJsZWQgZXZlbnRzLgogKiBJZiB0aGUgbnVtYmVyIG9mIGVuYWJsZWQgZXZlbnRzIGlzIHRoZSBzYW1lLCB0aGVuIHRoZSBzZXQKICogb2YgZW5hYmxlZCBldmVudHMgc2hvdWxkIGJlIHRoZSBzYW1lLCBiZWNhdXNlIHRoZXNlIGFyZSBib3RoCiAqIGluaGVyaXRlZCBjb250ZXh0cywgdGhlcmVmb3JlIHdlIGNhbid0IGFjY2VzcyBpbmRpdmlkdWFsIGV2ZW50cwogKiBpbiB0aGVtIGRpcmVjdGx5IHdpdGggYW4gZmQ7IHdlIGNhbiBvbmx5IGVuYWJsZS9kaXNhYmxlIGFsbAogKiBldmVudHMgdmlhIHByY3RsLCBvciBlbmFibGUvZGlzYWJsZSBhbGwgZXZlbnRzIGluIGEgZmFtaWx5CiAqIHZpYSBpb2N0bCwgd2hpY2ggd2lsbCBoYXZlIHRoZSBzYW1lIGVmZmVjdCBvbiBib3RoIGNvbnRleHRzLgogKi8Kc3RhdGljIGludCBjb250ZXh0X2VxdWl2KHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eDEsCgkJCSBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgyKQp7CglyZXR1cm4gY3R4MS0+cGFyZW50X2N0eCAmJiBjdHgxLT5wYXJlbnRfY3R4ID09IGN0eDItPnBhcmVudF9jdHgKCQkmJiBjdHgxLT5wYXJlbnRfZ2VuID09IGN0eDItPnBhcmVudF9nZW4KCQkmJiAhY3R4MS0+cGluX2NvdW50ICYmICFjdHgyLT5waW5fY291bnQ7Cn0KCnN0YXRpYyB2b2lkIF9fcGVyZl9ldmVudF9zeW5jX3N0YXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJICAgICBzdHJ1Y3QgcGVyZl9ldmVudCAqbmV4dF9ldmVudCkKewoJdTY0IHZhbHVlOwoKCWlmICghZXZlbnQtPmF0dHIuaW5oZXJpdF9zdGF0KQoJCXJldHVybjsKCgkvKgoJICogVXBkYXRlIHRoZSBldmVudCB2YWx1ZSwgd2UgY2Fubm90IHVzZSBwZXJmX2V2ZW50X3JlYWQoKQoJICogYmVjYXVzZSB3ZSdyZSBpbiB0aGUgbWlkZGxlIG9mIGEgY29udGV4dCBzd2l0Y2ggYW5kIGhhdmUgSVJRcwoJICogZGlzYWJsZWQsIHdoaWNoIHVwc2V0cyBzbXBfY2FsbF9mdW5jdGlvbl9zaW5nbGUoKSwgaG93ZXZlcgoJICogd2Uga25vdyB0aGUgZXZlbnQgbXVzdCBiZSBvbiB0aGUgY3VycmVudCBDUFUsIHRoZXJlZm9yZSB3ZQoJICogZG9uJ3QgbmVlZCB0byB1c2UgaXQuCgkgKi8KCXN3aXRjaCAoZXZlbnQtPnN0YXRlKSB7CgljYXNlIFBFUkZfRVZFTlRfU1RBVEVfQUNUSVZFOgoJCWV2ZW50LT5wbXUtPnJlYWQoZXZlbnQpOwoJCS8qIGZhbGwtdGhyb3VnaCAqLwoKCWNhc2UgUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRToKCQl1cGRhdGVfZXZlbnRfdGltZXMoZXZlbnQpOwoJCWJyZWFrOwoKCWRlZmF1bHQ6CgkJYnJlYWs7Cgl9CgoJLyoKCSAqIEluIG9yZGVyIHRvIGtlZXAgcGVyLXRhc2sgc3RhdHMgcmVsaWFibGUgd2UgbmVlZCB0byBmbGlwIHRoZSBldmVudAoJICogdmFsdWVzIHdoZW4gd2UgZmxpcCB0aGUgY29udGV4dHMuCgkgKi8KCXZhbHVlID0gbG9jYWw2NF9yZWFkKCZuZXh0X2V2ZW50LT5jb3VudCk7Cgl2YWx1ZSA9IGxvY2FsNjRfeGNoZygmZXZlbnQtPmNvdW50LCB2YWx1ZSk7Cglsb2NhbDY0X3NldCgmbmV4dF9ldmVudC0+Y291bnQsIHZhbHVlKTsKCglzd2FwKGV2ZW50LT50b3RhbF90aW1lX2VuYWJsZWQsIG5leHRfZXZlbnQtPnRvdGFsX3RpbWVfZW5hYmxlZCk7Cglzd2FwKGV2ZW50LT50b3RhbF90aW1lX3J1bm5pbmcsIG5leHRfZXZlbnQtPnRvdGFsX3RpbWVfcnVubmluZyk7CgoJLyoKCSAqIFNpbmNlIHdlIHN3aXp6bGVkIHRoZSB2YWx1ZXMsIHVwZGF0ZSB0aGUgdXNlciB2aXNpYmxlIGRhdGEgdG9vLgoJICovCglwZXJmX2V2ZW50X3VwZGF0ZV91c2VycGFnZShldmVudCk7CglwZXJmX2V2ZW50X3VwZGF0ZV91c2VycGFnZShuZXh0X2V2ZW50KTsKfQoKI2RlZmluZSBsaXN0X25leHRfZW50cnkocG9zLCBtZW1iZXIpIFwKCWxpc3RfZW50cnkocG9zLT5tZW1iZXIubmV4dCwgdHlwZW9mKCpwb3MpLCBtZW1iZXIpCgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X3N5bmNfc3RhdChzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgsCgkJCQkgICBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpuZXh0X2N0eCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCAqbmV4dF9ldmVudDsKCglpZiAoIWN0eC0+bnJfc3RhdCkKCQlyZXR1cm47CgoJdXBkYXRlX2NvbnRleHRfdGltZShjdHgpOwoKCWV2ZW50ID0gbGlzdF9maXJzdF9lbnRyeSgmY3R4LT5ldmVudF9saXN0LAoJCQkJICAgc3RydWN0IHBlcmZfZXZlbnQsIGV2ZW50X2VudHJ5KTsKCgluZXh0X2V2ZW50ID0gbGlzdF9maXJzdF9lbnRyeSgmbmV4dF9jdHgtPmV2ZW50X2xpc3QsCgkJCQkJc3RydWN0IHBlcmZfZXZlbnQsIGV2ZW50X2VudHJ5KTsKCgl3aGlsZSAoJmV2ZW50LT5ldmVudF9lbnRyeSAhPSAmY3R4LT5ldmVudF9saXN0ICYmCgkgICAgICAgJm5leHRfZXZlbnQtPmV2ZW50X2VudHJ5ICE9ICZuZXh0X2N0eC0+ZXZlbnRfbGlzdCkgewoKCQlfX3BlcmZfZXZlbnRfc3luY19zdGF0KGV2ZW50LCBuZXh0X2V2ZW50KTsKCgkJZXZlbnQgPSBsaXN0X25leHRfZW50cnkoZXZlbnQsIGV2ZW50X2VudHJ5KTsKCQluZXh0X2V2ZW50ID0gbGlzdF9uZXh0X2VudHJ5KG5leHRfZXZlbnQsIGV2ZW50X2VudHJ5KTsKCX0KfQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9jb250ZXh0X3NjaGVkX291dChzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2ssIGludCBjdHhuLAoJCQkJCSBzdHJ1Y3QgdGFza19zdHJ1Y3QgKm5leHQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IHRhc2stPnBlcmZfZXZlbnRfY3R4cFtjdHhuXTsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKm5leHRfY3R4OwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqcGFyZW50OwoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eDsKCWludCBkb19zd2l0Y2ggPSAxOwoKCWlmIChsaWtlbHkoIWN0eCkpCgkJcmV0dXJuOwoKCWNwdWN0eCA9IF9fZ2V0X2NwdV9jb250ZXh0KGN0eCk7CglpZiAoIWNwdWN0eC0+dGFza19jdHgpCgkJcmV0dXJuOwoKCXJjdV9yZWFkX2xvY2soKTsKCXBhcmVudCA9IHJjdV9kZXJlZmVyZW5jZShjdHgtPnBhcmVudF9jdHgpOwoJbmV4dF9jdHggPSBuZXh0LT5wZXJmX2V2ZW50X2N0eHBbY3R4bl07CglpZiAocGFyZW50ICYmIG5leHRfY3R4ICYmCgkgICAgcmN1X2RlcmVmZXJlbmNlKG5leHRfY3R4LT5wYXJlbnRfY3R4KSA9PSBwYXJlbnQpIHsKCQkvKgoJCSAqIExvb2tzIGxpa2UgdGhlIHR3byBjb250ZXh0cyBhcmUgY2xvbmVzLCBzbyB3ZSBtaWdodCBiZQoJCSAqIGFibGUgdG8gb3B0aW1pemUgdGhlIGNvbnRleHQgc3dpdGNoLiAgV2UgbG9jayBib3RoCgkJICogY29udGV4dHMgYW5kIGNoZWNrIHRoYXQgdGhleSBhcmUgY2xvbmVzIHVuZGVyIHRoZQoJCSAqIGxvY2sgKGluY2x1ZGluZyByZS1jaGVja2luZyB0aGF0IG5laXRoZXIgaGFzIGJlZW4KCQkgKiB1bmNsb25lZCBpbiB0aGUgbWVhbnRpbWUpLiAgSXQgZG9lc24ndCBtYXR0ZXIgd2hpY2gKCQkgKiBvcmRlciB3ZSB0YWtlIHRoZSBsb2NrcyBiZWNhdXNlIG5vIG90aGVyIGNwdSBjb3VsZAoJCSAqIGJlIHRyeWluZyB0byBsb2NrIGJvdGggb2YgdGhlc2UgdGFza3MuCgkJICovCgkJcmF3X3NwaW5fbG9jaygmY3R4LT5sb2NrKTsKCQlyYXdfc3Bpbl9sb2NrX25lc3RlZCgmbmV4dF9jdHgtPmxvY2ssIFNJTkdMRV9ERVBUSF9ORVNUSU5HKTsKCQlpZiAoY29udGV4dF9lcXVpdihjdHgsIG5leHRfY3R4KSkgewoJCQkvKgoJCQkgKiBYWFggZG8gd2UgbmVlZCBhIG1lbW9yeSBiYXJyaWVyIG9mIHNvcnRzCgkJCSAqIHdydCB0byByY3VfZGVyZWZlcmVuY2UoKSBvZiBwZXJmX2V2ZW50X2N0eHAKCQkJICovCgkJCXRhc2stPnBlcmZfZXZlbnRfY3R4cFtjdHhuXSA9IG5leHRfY3R4OwoJCQluZXh0LT5wZXJmX2V2ZW50X2N0eHBbY3R4bl0gPSBjdHg7CgkJCWN0eC0+dGFzayA9IG5leHQ7CgkJCW5leHRfY3R4LT50YXNrID0gdGFzazsKCQkJZG9fc3dpdGNoID0gMDsKCgkJCXBlcmZfZXZlbnRfc3luY19zdGF0KGN0eCwgbmV4dF9jdHgpOwoJCX0KCQlyYXdfc3Bpbl91bmxvY2soJm5leHRfY3R4LT5sb2NrKTsKCQlyYXdfc3Bpbl91bmxvY2soJmN0eC0+bG9jayk7Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKCglpZiAoZG9fc3dpdGNoKSB7CgkJY3R4X3NjaGVkX291dChjdHgsIGNwdWN0eCwgRVZFTlRfQUxMKTsKCQljcHVjdHgtPnRhc2tfY3R4ID0gTlVMTDsKCX0KfQoKI2RlZmluZSBmb3JfZWFjaF90YXNrX2NvbnRleHRfbnIoY3R4bikJCQkJCVwKCWZvciAoKGN0eG4pID0gMDsgKGN0eG4pIDwgcGVyZl9ucl90YXNrX2NvbnRleHRzOyAoY3R4bikrKykKCi8qCiAqIENhbGxlZCBmcm9tIHNjaGVkdWxlciB0byByZW1vdmUgdGhlIGV2ZW50cyBvZiB0aGUgY3VycmVudCB0YXNrLAogKiB3aXRoIGludGVycnVwdHMgZGlzYWJsZWQuCiAqCiAqIFdlIHN0b3AgZWFjaCBldmVudCBhbmQgdXBkYXRlIHRoZSBldmVudCB2YWx1ZSBpbiBldmVudC0+Y291bnQuCiAqCiAqIFRoaXMgZG9lcyBub3QgcHJvdGVjdCB1cyBhZ2FpbnN0IE5NSSwgYnV0IGRpc2FibGUoKQogKiBzZXRzIHRoZSBkaXNhYmxlZCBiaXQgaW4gdGhlIGNvbnRyb2wgZmllbGQgb2YgZXZlbnQgX2JlZm9yZV8KICogYWNjZXNzaW5nIHRoZSBldmVudCBjb250cm9sIHJlZ2lzdGVyLiBJZiBhIE5NSSBoaXRzLCB0aGVuIGl0IHdpbGwKICogbm90IHJlc3RhcnQgdGhlIGV2ZW50LgogKi8Kdm9pZCBfX3BlcmZfZXZlbnRfdGFza19zY2hlZF9vdXQoc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrLAoJCQkJIHN0cnVjdCB0YXNrX3N0cnVjdCAqbmV4dCkKewoJaW50IGN0eG47CgoJZm9yX2VhY2hfdGFza19jb250ZXh0X25yKGN0eG4pCgkJcGVyZl9ldmVudF9jb250ZXh0X3NjaGVkX291dCh0YXNrLCBjdHhuLCBuZXh0KTsKfQoKc3RhdGljIHZvaWQgdGFza19jdHhfc2NoZWRfb3V0KHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCwKCQkJICAgICAgIGVudW0gZXZlbnRfdHlwZV90IGV2ZW50X3R5cGUpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHggPSBfX2dldF9jcHVfY29udGV4dChjdHgpOwoKCWlmICghY3B1Y3R4LT50YXNrX2N0eCkKCQlyZXR1cm47CgoJaWYgKFdBUk5fT05fT05DRShjdHggIT0gY3B1Y3R4LT50YXNrX2N0eCkpCgkJcmV0dXJuOwoKCWN0eF9zY2hlZF9vdXQoY3R4LCBjcHVjdHgsIGV2ZW50X3R5cGUpOwoJY3B1Y3R4LT50YXNrX2N0eCA9IE5VTEw7Cn0KCi8qCiAqIENhbGxlZCB3aXRoIElSUXMgZGlzYWJsZWQKICovCnN0YXRpYyB2b2lkIGNwdV9jdHhfc2NoZWRfb3V0KHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgsCgkJCSAgICAgIGVudW0gZXZlbnRfdHlwZV90IGV2ZW50X3R5cGUpCnsKCWN0eF9zY2hlZF9vdXQoJmNwdWN0eC0+Y3R4LCBjcHVjdHgsIGV2ZW50X3R5cGUpOwp9CgpzdGF0aWMgdm9pZApjdHhfcGlubmVkX3NjaGVkX2luKHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCwKCQkgICAgc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoKCWxpc3RfZm9yX2VhY2hfZW50cnkoZXZlbnQsICZjdHgtPnBpbm5lZF9ncm91cHMsIGdyb3VwX2VudHJ5KSB7CgkJaWYgKGV2ZW50LT5zdGF0ZSA8PSBQRVJGX0VWRU5UX1NUQVRFX09GRikKCQkJY29udGludWU7CgkJaWYgKCFldmVudF9maWx0ZXJfbWF0Y2goZXZlbnQpKQoJCQljb250aW51ZTsKCgkJaWYgKGdyb3VwX2Nhbl9nb19vbihldmVudCwgY3B1Y3R4LCAxKSkKCQkJZ3JvdXBfc2NoZWRfaW4oZXZlbnQsIGNwdWN0eCwgY3R4KTsKCgkJLyoKCQkgKiBJZiB0aGlzIHBpbm5lZCBncm91cCBoYXNuJ3QgYmVlbiBzY2hlZHVsZWQsCgkJICogcHV0IGl0IGluIGVycm9yIHN0YXRlLgoJCSAqLwoJCWlmIChldmVudC0+c3RhdGUgPT0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRSkgewoJCQl1cGRhdGVfZ3JvdXBfdGltZXMoZXZlbnQpOwoJCQlldmVudC0+c3RhdGUgPSBQRVJGX0VWRU5UX1NUQVRFX0VSUk9SOwoJCX0KCX0KfQoKc3RhdGljIHZvaWQKY3R4X2ZsZXhpYmxlX3NjaGVkX2luKHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCwKCQkgICAgICBzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4KQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQ7CglpbnQgY2FuX2FkZF9odyA9IDE7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeShldmVudCwgJmN0eC0+ZmxleGlibGVfZ3JvdXBzLCBncm91cF9lbnRyeSkgewoJCS8qIElnbm9yZSBldmVudHMgaW4gT0ZGIG9yIEVSUk9SIHN0YXRlICovCgkJaWYgKGV2ZW50LT5zdGF0ZSA8PSBQRVJGX0VWRU5UX1NUQVRFX09GRikKCQkJY29udGludWU7CgkJLyoKCQkgKiBMaXN0ZW4gdG8gdGhlICdjcHUnIHNjaGVkdWxpbmcgZmlsdGVyIGNvbnN0cmFpbnQKCQkgKiBvZiBldmVudHM6CgkJICovCgkJaWYgKCFldmVudF9maWx0ZXJfbWF0Y2goZXZlbnQpKQoJCQljb250aW51ZTsKCgkJaWYgKGdyb3VwX2Nhbl9nb19vbihldmVudCwgY3B1Y3R4LCBjYW5fYWRkX2h3KSkgewoJCQlpZiAoZ3JvdXBfc2NoZWRfaW4oZXZlbnQsIGNwdWN0eCwgY3R4KSkKCQkJCWNhbl9hZGRfaHcgPSAwOwoJCX0KCX0KfQoKc3RhdGljIHZvaWQKY3R4X3NjaGVkX2luKHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCwKCSAgICAgc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCwKCSAgICAgZW51bSBldmVudF90eXBlX3QgZXZlbnRfdHlwZSkKewoJcmF3X3NwaW5fbG9jaygmY3R4LT5sb2NrKTsKCWN0eC0+aXNfYWN0aXZlID0gMTsKCWlmIChsaWtlbHkoIWN0eC0+bnJfZXZlbnRzKSkKCQlnb3RvIG91dDsKCgljdHgtPnRpbWVzdGFtcCA9IHBlcmZfY2xvY2soKTsKCgkvKgoJICogRmlyc3QgZ28gdGhyb3VnaCB0aGUgbGlzdCBhbmQgcHV0IG9uIGFueSBwaW5uZWQgZ3JvdXBzCgkgKiBpbiBvcmRlciB0byBnaXZlIHRoZW0gdGhlIGJlc3QgY2hhbmNlIG9mIGdvaW5nIG9uLgoJICovCglpZiAoZXZlbnRfdHlwZSAmIEVWRU5UX1BJTk5FRCkKCQljdHhfcGlubmVkX3NjaGVkX2luKGN0eCwgY3B1Y3R4KTsKCgkvKiBUaGVuIHdhbGsgdGhyb3VnaCB0aGUgbG93ZXIgcHJpbyBmbGV4aWJsZSBncm91cHMgKi8KCWlmIChldmVudF90eXBlICYgRVZFTlRfRkxFWElCTEUpCgkJY3R4X2ZsZXhpYmxlX3NjaGVkX2luKGN0eCwgY3B1Y3R4KTsKCm91dDoKCXJhd19zcGluX3VubG9jaygmY3R4LT5sb2NrKTsKfQoKc3RhdGljIHZvaWQgY3B1X2N0eF9zY2hlZF9pbihzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4LAoJCQkgICAgIGVudW0gZXZlbnRfdHlwZV90IGV2ZW50X3R5cGUpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9ICZjcHVjdHgtPmN0eDsKCgljdHhfc2NoZWRfaW4oY3R4LCBjcHVjdHgsIGV2ZW50X3R5cGUpOwp9CgpzdGF0aWMgdm9pZCB0YXNrX2N0eF9zY2hlZF9pbihzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgsCgkJCSAgICAgIGVudW0gZXZlbnRfdHlwZV90IGV2ZW50X3R5cGUpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHg7CgoJY3B1Y3R4ID0gX19nZXRfY3B1X2NvbnRleHQoY3R4KTsKCWlmIChjcHVjdHgtPnRhc2tfY3R4ID09IGN0eCkKCQlyZXR1cm47CgoJY3R4X3NjaGVkX2luKGN0eCwgY3B1Y3R4LCBldmVudF90eXBlKTsKCWNwdWN0eC0+dGFza19jdHggPSBjdHg7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfY29udGV4dF9zY2hlZF9pbihzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHg7CgoJY3B1Y3R4ID0gX19nZXRfY3B1X2NvbnRleHQoY3R4KTsKCWlmIChjcHVjdHgtPnRhc2tfY3R4ID09IGN0eCkKCQlyZXR1cm47CgoJcGVyZl9wbXVfZGlzYWJsZShjdHgtPnBtdSk7CgkvKgoJICogV2Ugd2FudCB0byBrZWVwIHRoZSBmb2xsb3dpbmcgcHJpb3JpdHkgb3JkZXI6CgkgKiBjcHUgcGlubmVkICh0aGF0IGRvbid0IG5lZWQgdG8gbW92ZSksIHRhc2sgcGlubmVkLAoJICogY3B1IGZsZXhpYmxlLCB0YXNrIGZsZXhpYmxlLgoJICovCgljcHVfY3R4X3NjaGVkX291dChjcHVjdHgsIEVWRU5UX0ZMRVhJQkxFKTsKCgljdHhfc2NoZWRfaW4oY3R4LCBjcHVjdHgsIEVWRU5UX1BJTk5FRCk7CgljcHVfY3R4X3NjaGVkX2luKGNwdWN0eCwgRVZFTlRfRkxFWElCTEUpOwoJY3R4X3NjaGVkX2luKGN0eCwgY3B1Y3R4LCBFVkVOVF9GTEVYSUJMRSk7CgoJY3B1Y3R4LT50YXNrX2N0eCA9IGN0eDsKCgkvKgoJICogU2luY2UgdGhlc2Ugcm90YXRpb25zIGFyZSBwZXItY3B1LCB3ZSBuZWVkIHRvIGVuc3VyZSB0aGUKCSAqIGNwdS1jb250ZXh0IHdlIGdvdCBzY2hlZHVsZWQgb24gaXMgYWN0dWFsbHkgcm90YXRpbmcuCgkgKi8KCXBlcmZfcG11X3JvdGF0ZV9zdGFydChjdHgtPnBtdSk7CglwZXJmX3BtdV9lbmFibGUoY3R4LT5wbXUpOwp9CgovKgogKiBDYWxsZWQgZnJvbSBzY2hlZHVsZXIgdG8gYWRkIHRoZSBldmVudHMgb2YgdGhlIGN1cnJlbnQgdGFzawogKiB3aXRoIGludGVycnVwdHMgZGlzYWJsZWQuCiAqCiAqIFdlIHJlc3RvcmUgdGhlIGV2ZW50IHZhbHVlIGFuZCB0aGVuIGVuYWJsZSBpdC4KICoKICogVGhpcyBkb2VzIG5vdCBwcm90ZWN0IHVzIGFnYWluc3QgTk1JLCBidXQgZW5hYmxlKCkKICogc2V0cyB0aGUgZW5hYmxlZCBiaXQgaW4gdGhlIGNvbnRyb2wgZmllbGQgb2YgZXZlbnQgX2JlZm9yZV8KICogYWNjZXNzaW5nIHRoZSBldmVudCBjb250cm9sIHJlZ2lzdGVyLiBJZiBhIE5NSSBoaXRzLCB0aGVuIGl0IHdpbGwKICoga2VlcCB0aGUgZXZlbnQgcnVubmluZy4KICovCnZvaWQgX19wZXJmX2V2ZW50X3Rhc2tfc2NoZWRfaW4oc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrKQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHg7CglpbnQgY3R4bjsKCglmb3JfZWFjaF90YXNrX2NvbnRleHRfbnIoY3R4bikgewoJCWN0eCA9IHRhc2stPnBlcmZfZXZlbnRfY3R4cFtjdHhuXTsKCQlpZiAobGlrZWx5KCFjdHgpKQoJCQljb250aW51ZTsKCgkJcGVyZl9ldmVudF9jb250ZXh0X3NjaGVkX2luKGN0eCk7Cgl9Cn0KCnN0YXRpYyB1NjQgcGVyZl9jYWxjdWxhdGVfcGVyaW9kKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgdTY0IG5zZWMsIHU2NCBjb3VudCkKewoJdTY0IGZyZXF1ZW5jeSA9IGV2ZW50LT5hdHRyLnNhbXBsZV9mcmVxOwoJdTY0IHNlYyA9IE5TRUNfUEVSX1NFQzsKCXU2NCBkaXZpc29yLCBkaXZpZGVuZDsKCglpbnQgY291bnRfZmxzLCBuc2VjX2ZscywgZnJlcXVlbmN5X2Zscywgc2VjX2ZsczsKCgljb3VudF9mbHMgPSBmbHM2NChjb3VudCk7Cgluc2VjX2ZscyA9IGZsczY0KG5zZWMpOwoJZnJlcXVlbmN5X2ZscyA9IGZsczY0KGZyZXF1ZW5jeSk7CglzZWNfZmxzID0gMzA7CgoJLyoKCSAqIFdlIGdvdCBAY291bnQgaW4gQG5zZWMsIHdpdGggYSB0YXJnZXQgb2Ygc2FtcGxlX2ZyZXEgSFoKCSAqIHRoZSB0YXJnZXQgcGVyaW9kIGJlY29tZXM6CgkgKgoJICogICAgICAgICAgICAgQGNvdW50ICogMTBeOQoJICogcGVyaW9kID0gLS0tLS0tLS0tLS0tLS0tLS0tLQoJICogICAgICAgICAgQG5zZWMgKiBzYW1wbGVfZnJlcQoJICoKCSAqLwoKCS8qCgkgKiBSZWR1Y2UgYWNjdXJhY3kgYnkgb25lIGJpdCBzdWNoIHRoYXQgQGEgYW5kIEBiIGNvbnZlcmdlCgkgKiB0byBhIHNpbWlsYXIgbWFnbml0dWRlLgoJICovCiNkZWZpbmUgUkVEVUNFX0ZMUyhhLCBiKQkJXApkbyB7CQkJCQlcCglpZiAoYSMjX2ZscyA+IGIjI19mbHMpIHsJXAoJCWEgPj49IDE7CQlcCgkJYSMjX2Zscy0tOwkJXAoJfSBlbHNlIHsJCQlcCgkJYiA+Pj0gMTsJCVwKCQliIyNfZmxzLS07CQlcCgl9CQkJCVwKfSB3aGlsZSAoMCkKCgkvKgoJICogUmVkdWNlIGFjY3VyYWN5IHVudGlsIGVpdGhlciB0ZXJtIGZpdHMgaW4gYSB1NjQsIHRoZW4gcHJvY2VlZCB3aXRoCgkgKiB0aGUgb3RoZXIsIHNvIHRoYXQgZmluYWxseSB3ZSBjYW4gZG8gYSB1NjQvdTY0IGRpdmlzaW9uLgoJICovCgl3aGlsZSAoY291bnRfZmxzICsgc2VjX2ZscyA+IDY0ICYmIG5zZWNfZmxzICsgZnJlcXVlbmN5X2ZscyA+IDY0KSB7CgkJUkVEVUNFX0ZMUyhuc2VjLCBmcmVxdWVuY3kpOwoJCVJFRFVDRV9GTFMoc2VjLCBjb3VudCk7Cgl9CgoJaWYgKGNvdW50X2ZscyArIHNlY19mbHMgPiA2NCkgewoJCWRpdmlzb3IgPSBuc2VjICogZnJlcXVlbmN5OwoKCQl3aGlsZSAoY291bnRfZmxzICsgc2VjX2ZscyA+IDY0KSB7CgkJCVJFRFVDRV9GTFMoY291bnQsIHNlYyk7CgkJCWRpdmlzb3IgPj49IDE7CgkJfQoKCQlkaXZpZGVuZCA9IGNvdW50ICogc2VjOwoJfSBlbHNlIHsKCQlkaXZpZGVuZCA9IGNvdW50ICogc2VjOwoKCQl3aGlsZSAobnNlY19mbHMgKyBmcmVxdWVuY3lfZmxzID4gNjQpIHsKCQkJUkVEVUNFX0ZMUyhuc2VjLCBmcmVxdWVuY3kpOwoJCQlkaXZpZGVuZCA+Pj0gMTsKCQl9CgoJCWRpdmlzb3IgPSBuc2VjICogZnJlcXVlbmN5OwoJfQoKCWlmICghZGl2aXNvcikKCQlyZXR1cm4gZGl2aWRlbmQ7CgoJcmV0dXJuIGRpdjY0X3U2NChkaXZpZGVuZCwgZGl2aXNvcik7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfYWRqdXN0X3BlcmlvZChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIHU2NCBuc2VjLCB1NjQgY291bnQpCnsKCXN0cnVjdCBod19wZXJmX2V2ZW50ICpod2MgPSAmZXZlbnQtPmh3OwoJczY0IHBlcmlvZCwgc2FtcGxlX3BlcmlvZDsKCXM2NCBkZWx0YTsKCglwZXJpb2QgPSBwZXJmX2NhbGN1bGF0ZV9wZXJpb2QoZXZlbnQsIG5zZWMsIGNvdW50KTsKCglkZWx0YSA9IChzNjQpKHBlcmlvZCAtIGh3Yy0+c2FtcGxlX3BlcmlvZCk7CglkZWx0YSA9IChkZWx0YSArIDcpIC8gODsgLyogbG93IHBhc3MgZmlsdGVyICovCgoJc2FtcGxlX3BlcmlvZCA9IGh3Yy0+c2FtcGxlX3BlcmlvZCArIGRlbHRhOwoKCWlmICghc2FtcGxlX3BlcmlvZCkKCQlzYW1wbGVfcGVyaW9kID0gMTsKCglod2MtPnNhbXBsZV9wZXJpb2QgPSBzYW1wbGVfcGVyaW9kOwoKCWlmIChsb2NhbDY0X3JlYWQoJmh3Yy0+cGVyaW9kX2xlZnQpID4gOCpzYW1wbGVfcGVyaW9kKSB7CgkJZXZlbnQtPnBtdS0+c3RvcChldmVudCwgUEVSRl9FRl9VUERBVEUpOwoJCWxvY2FsNjRfc2V0KCZod2MtPnBlcmlvZF9sZWZ0LCAwKTsKCQlldmVudC0+cG11LT5zdGFydChldmVudCwgUEVSRl9FRl9SRUxPQUQpOwoJfQp9CgpzdGF0aWMgdm9pZCBwZXJmX2N0eF9hZGp1c3RfZnJlcShzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgsIHU2NCBwZXJpb2QpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCXN0cnVjdCBod19wZXJmX2V2ZW50ICpod2M7Cgl1NjQgaW50ZXJydXB0cywgbm93OwoJczY0IGRlbHRhOwoKCXJhd19zcGluX2xvY2soJmN0eC0+bG9jayk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5X3JjdShldmVudCwgJmN0eC0+ZXZlbnRfbGlzdCwgZXZlbnRfZW50cnkpIHsKCQlpZiAoZXZlbnQtPnN0YXRlICE9IFBFUkZfRVZFTlRfU1RBVEVfQUNUSVZFKQoJCQljb250aW51ZTsKCgkJaWYgKCFldmVudF9maWx0ZXJfbWF0Y2goZXZlbnQpKQoJCQljb250aW51ZTsKCgkJaHdjID0gJmV2ZW50LT5odzsKCgkJaW50ZXJydXB0cyA9IGh3Yy0+aW50ZXJydXB0czsKCQlod2MtPmludGVycnVwdHMgPSAwOwoKCQkvKgoJCSAqIHVudGhyb3R0bGUgZXZlbnRzIG9uIHRoZSB0aWNrCgkJICovCgkJaWYgKGludGVycnVwdHMgPT0gTUFYX0lOVEVSUlVQVFMpIHsKCQkJcGVyZl9sb2dfdGhyb3R0bGUoZXZlbnQsIDEpOwoJCQlldmVudC0+cG11LT5zdGFydChldmVudCwgMCk7CgkJfQoKCQlpZiAoIWV2ZW50LT5hdHRyLmZyZXEgfHwgIWV2ZW50LT5hdHRyLnNhbXBsZV9mcmVxKQoJCQljb250aW51ZTsKCgkJZXZlbnQtPnBtdS0+cmVhZChldmVudCk7CgkJbm93ID0gbG9jYWw2NF9yZWFkKCZldmVudC0+Y291bnQpOwoJCWRlbHRhID0gbm93IC0gaHdjLT5mcmVxX2NvdW50X3N0YW1wOwoJCWh3Yy0+ZnJlcV9jb3VudF9zdGFtcCA9IG5vdzsKCgkJaWYgKGRlbHRhID4gMCkKCQkJcGVyZl9hZGp1c3RfcGVyaW9kKGV2ZW50LCBwZXJpb2QsIGRlbHRhKTsKCX0KCXJhd19zcGluX3VubG9jaygmY3R4LT5sb2NrKTsKfQoKLyoKICogUm91bmQtcm9iaW4gYSBjb250ZXh0J3MgZXZlbnRzOgogKi8Kc3RhdGljIHZvaWQgcm90YXRlX2N0eChzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgpCnsKCXJhd19zcGluX2xvY2soJmN0eC0+bG9jayk7CgoJLyoKCSAqIFJvdGF0ZSB0aGUgZmlyc3QgZW50cnkgbGFzdCBvZiBub24tcGlubmVkIGdyb3Vwcy4gUm90YXRpb24gbWlnaHQgYmUKCSAqIGRpc2FibGVkIGJ5IHRoZSBpbmhlcml0YW5jZSBjb2RlLgoJICovCglpZiAoIWN0eC0+cm90YXRlX2Rpc2FibGUpCgkJbGlzdF9yb3RhdGVfbGVmdCgmY3R4LT5mbGV4aWJsZV9ncm91cHMpOwoKCXJhd19zcGluX3VubG9jaygmY3R4LT5sb2NrKTsKfQoKLyoKICogcGVyZl9wbXVfcm90YXRlX3N0YXJ0KCkgYW5kIHBlcmZfcm90YXRlX2NvbnRleHQoKSBhcmUgZnVsbHkgc2VyaWFsaXplZAogKiBiZWNhdXNlIHRoZXkncmUgc3RyaWN0bHkgY3B1IGFmZmluZSBhbmQgcm90YXRlX3N0YXJ0IGlzIGNhbGxlZCB3aXRoIElSUXMKICogZGlzYWJsZWQsIHdoaWxlIHJvdGF0ZV9jb250ZXh0IGlzIGNhbGxlZCBmcm9tIElSUSBjb250ZXh0LgogKi8Kc3RhdGljIHZvaWQgcGVyZl9yb3RhdGVfY29udGV4dChzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4KQp7Cgl1NjQgaW50ZXJ2YWwgPSAodTY0KWNwdWN0eC0+amlmZmllc19pbnRlcnZhbCAqIFRJQ0tfTlNFQzsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IE5VTEw7CglpbnQgcm90YXRlID0gMCwgcmVtb3ZlID0gMTsKCglpZiAoY3B1Y3R4LT5jdHgubnJfZXZlbnRzKSB7CgkJcmVtb3ZlID0gMDsKCQlpZiAoY3B1Y3R4LT5jdHgubnJfZXZlbnRzICE9IGNwdWN0eC0+Y3R4Lm5yX2FjdGl2ZSkKCQkJcm90YXRlID0gMTsKCX0KCgljdHggPSBjcHVjdHgtPnRhc2tfY3R4OwoJaWYgKGN0eCAmJiBjdHgtPm5yX2V2ZW50cykgewoJCXJlbW92ZSA9IDA7CgkJaWYgKGN0eC0+bnJfZXZlbnRzICE9IGN0eC0+bnJfYWN0aXZlKQoJCQlyb3RhdGUgPSAxOwoJfQoKCXBlcmZfcG11X2Rpc2FibGUoY3B1Y3R4LT5jdHgucG11KTsKCXBlcmZfY3R4X2FkanVzdF9mcmVxKCZjcHVjdHgtPmN0eCwgaW50ZXJ2YWwpOwoJaWYgKGN0eCkKCQlwZXJmX2N0eF9hZGp1c3RfZnJlcShjdHgsIGludGVydmFsKTsKCglpZiAoIXJvdGF0ZSkKCQlnb3RvIGRvbmU7CgoJY3B1X2N0eF9zY2hlZF9vdXQoY3B1Y3R4LCBFVkVOVF9GTEVYSUJMRSk7CglpZiAoY3R4KQoJCXRhc2tfY3R4X3NjaGVkX291dChjdHgsIEVWRU5UX0ZMRVhJQkxFKTsKCglyb3RhdGVfY3R4KCZjcHVjdHgtPmN0eCk7CglpZiAoY3R4KQoJCXJvdGF0ZV9jdHgoY3R4KTsKCgljcHVfY3R4X3NjaGVkX2luKGNwdWN0eCwgRVZFTlRfRkxFWElCTEUpOwoJaWYgKGN0eCkKCQl0YXNrX2N0eF9zY2hlZF9pbihjdHgsIEVWRU5UX0ZMRVhJQkxFKTsKCmRvbmU6CglpZiAocmVtb3ZlKQoJCWxpc3RfZGVsX2luaXQoJmNwdWN0eC0+cm90YXRpb25fbGlzdCk7CgoJcGVyZl9wbXVfZW5hYmxlKGNwdWN0eC0+Y3R4LnBtdSk7Cn0KCnZvaWQgcGVyZl9ldmVudF90YXNrX3RpY2sodm9pZCkKewoJc3RydWN0IGxpc3RfaGVhZCAqaGVhZCA9ICZfX2dldF9jcHVfdmFyKHJvdGF0aW9uX2xpc3QpOwoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCwgKnRtcDsKCglXQVJOX09OKCFpcnFzX2Rpc2FibGVkKCkpOwoKCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShjcHVjdHgsIHRtcCwgaGVhZCwgcm90YXRpb25fbGlzdCkgewoJCWlmIChjcHVjdHgtPmppZmZpZXNfaW50ZXJ2YWwgPT0gMSB8fAoJCQkJIShqaWZmaWVzICUgY3B1Y3R4LT5qaWZmaWVzX2ludGVydmFsKSkKCQkJcGVyZl9yb3RhdGVfY29udGV4dChjcHVjdHgpOwoJfQp9CgpzdGF0aWMgaW50IGV2ZW50X2VuYWJsZV9vbl9leGVjKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCkKewoJaWYgKCFldmVudC0+YXR0ci5lbmFibGVfb25fZXhlYykKCQlyZXR1cm4gMDsKCglldmVudC0+YXR0ci5lbmFibGVfb25fZXhlYyA9IDA7CglpZiAoZXZlbnQtPnN0YXRlID49IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUpCgkJcmV0dXJuIDA7CgoJX19wZXJmX2V2ZW50X21hcmtfZW5hYmxlZChldmVudCwgY3R4KTsKCglyZXR1cm4gMTsKfQoKLyoKICogRW5hYmxlIGFsbCBvZiBhIHRhc2sncyBldmVudHMgdGhhdCBoYXZlIGJlZW4gbWFya2VkIGVuYWJsZS1vbi1leGVjLgogKiBUaGlzIGV4cGVjdHMgdGFzayA9PSBjdXJyZW50LgogKi8Kc3RhdGljIHZvaWQgcGVyZl9ldmVudF9lbmFibGVfb25fZXhlYyhzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CglpbnQgZW5hYmxlZCA9IDA7CglpbnQgcmV0OwoKCWxvY2FsX2lycV9zYXZlKGZsYWdzKTsKCWlmICghY3R4IHx8ICFjdHgtPm5yX2V2ZW50cykKCQlnb3RvIG91dDsKCgl0YXNrX2N0eF9zY2hlZF9vdXQoY3R4LCBFVkVOVF9BTEwpOwoKCXJhd19zcGluX2xvY2soJmN0eC0+bG9jayk7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeShldmVudCwgJmN0eC0+cGlubmVkX2dyb3VwcywgZ3JvdXBfZW50cnkpIHsKCQlyZXQgPSBldmVudF9lbmFibGVfb25fZXhlYyhldmVudCwgY3R4KTsKCQlpZiAocmV0KQoJCQllbmFibGVkID0gMTsKCX0KCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGV2ZW50LCAmY3R4LT5mbGV4aWJsZV9ncm91cHMsIGdyb3VwX2VudHJ5KSB7CgkJcmV0ID0gZXZlbnRfZW5hYmxlX29uX2V4ZWMoZXZlbnQsIGN0eCk7CgkJaWYgKHJldCkKCQkJZW5hYmxlZCA9IDE7Cgl9CgoJLyoKCSAqIFVuY2xvbmUgdGhpcyBjb250ZXh0IGlmIHdlIGVuYWJsZWQgYW55IGV2ZW50LgoJICovCglpZiAoZW5hYmxlZCkKCQl1bmNsb25lX2N0eChjdHgpOwoKCXJhd19zcGluX3VubG9jaygmY3R4LT5sb2NrKTsKCglwZXJmX2V2ZW50X2NvbnRleHRfc2NoZWRfaW4oY3R4KTsKb3V0OgoJbG9jYWxfaXJxX3Jlc3RvcmUoZmxhZ3MpOwp9CgovKgogKiBDcm9zcyBDUFUgY2FsbCB0byByZWFkIHRoZSBoYXJkd2FyZSBldmVudAogKi8Kc3RhdGljIHZvaWQgX19wZXJmX2V2ZW50X3JlYWQodm9pZCAqaW5mbykKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50ID0gaW5mbzsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IGV2ZW50LT5jdHg7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4ID0gX19nZXRfY3B1X2NvbnRleHQoY3R4KTsKCgkvKgoJICogSWYgdGhpcyBpcyBhIHRhc2sgY29udGV4dCwgd2UgbmVlZCB0byBjaGVjayB3aGV0aGVyIGl0IGlzCgkgKiB0aGUgY3VycmVudCB0YXNrIGNvbnRleHQgb2YgdGhpcyBjcHUuICBJZiBub3QgaXQgaGFzIGJlZW4KCSAqIHNjaGVkdWxlZCBvdXQgYmVmb3JlIHRoZSBzbXAgY2FsbCBhcnJpdmVkLiAgSW4gdGhhdCBjYXNlCgkgKiBldmVudC0+Y291bnQgd291bGQgaGF2ZSBiZWVuIHVwZGF0ZWQgdG8gYSByZWNlbnQgc2FtcGxlCgkgKiB3aGVuIHRoZSBldmVudCB3YXMgc2NoZWR1bGVkIG91dC4KCSAqLwoJaWYgKGN0eC0+dGFzayAmJiBjcHVjdHgtPnRhc2tfY3R4ICE9IGN0eCkKCQlyZXR1cm47CgoJcmF3X3NwaW5fbG9jaygmY3R4LT5sb2NrKTsKCWlmIChjdHgtPmlzX2FjdGl2ZSkKCQl1cGRhdGVfY29udGV4dF90aW1lKGN0eCk7Cgl1cGRhdGVfZXZlbnRfdGltZXMoZXZlbnQpOwoJaWYgKGV2ZW50LT5zdGF0ZSA9PSBQRVJGX0VWRU5UX1NUQVRFX0FDVElWRSkKCQlldmVudC0+cG11LT5yZWFkKGV2ZW50KTsKCXJhd19zcGluX3VubG9jaygmY3R4LT5sb2NrKTsKfQoKc3RhdGljIGlubGluZSB1NjQgcGVyZl9ldmVudF9jb3VudChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXJldHVybiBsb2NhbDY0X3JlYWQoJmV2ZW50LT5jb3VudCkgKyBhdG9taWM2NF9yZWFkKCZldmVudC0+Y2hpbGRfY291bnQpOwp9CgpzdGF0aWMgdTY0IHBlcmZfZXZlbnRfcmVhZChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCS8qCgkgKiBJZiBldmVudCBpcyBlbmFibGVkIGFuZCBjdXJyZW50bHkgYWN0aXZlIG9uIGEgQ1BVLCB1cGRhdGUgdGhlCgkgKiB2YWx1ZSBpbiB0aGUgZXZlbnQgc3RydWN0dXJlOgoJICovCglpZiAoZXZlbnQtPnN0YXRlID09IFBFUkZfRVZFTlRfU1RBVEVfQUNUSVZFKSB7CgkJc21wX2NhbGxfZnVuY3Rpb25fc2luZ2xlKGV2ZW50LT5vbmNwdSwKCQkJCQkgX19wZXJmX2V2ZW50X3JlYWQsIGV2ZW50LCAxKTsKCX0gZWxzZSBpZiAoZXZlbnQtPnN0YXRlID09IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUpIHsKCQlzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSBldmVudC0+Y3R4OwoJCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJCXJhd19zcGluX2xvY2tfaXJxc2F2ZSgmY3R4LT5sb2NrLCBmbGFncyk7CgkJLyoKCQkgKiBtYXkgcmVhZCB3aGlsZSBjb250ZXh0IGlzIG5vdCBhY3RpdmUKCQkgKiAoZS5nLiwgdGhyZWFkIGlzIGJsb2NrZWQpLCBpbiB0aGF0IGNhc2UKCQkgKiB3ZSBjYW5ub3QgdXBkYXRlIGNvbnRleHQgdGltZQoJCSAqLwoJCWlmIChjdHgtPmlzX2FjdGl2ZSkKCQkJdXBkYXRlX2NvbnRleHRfdGltZShjdHgpOwoJCXVwZGF0ZV9ldmVudF90aW1lcyhldmVudCk7CgkJcmF3X3NwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmN0eC0+bG9jaywgZmxhZ3MpOwoJfQoKCXJldHVybiBwZXJmX2V2ZW50X2NvdW50KGV2ZW50KTsKfQoKLyoKICogQ2FsbGNoYWluIHN1cHBvcnQKICovCgpzdHJ1Y3QgY2FsbGNoYWluX2NwdXNfZW50cmllcyB7CglzdHJ1Y3QgcmN1X2hlYWQJCQlyY3VfaGVhZDsKCXN0cnVjdCBwZXJmX2NhbGxjaGFpbl9lbnRyeQkqY3B1X2VudHJpZXNbMF07Cn07CgpzdGF0aWMgREVGSU5FX1BFUl9DUFUoaW50LCBjYWxsY2hhaW5fcmVjdXJzaW9uW1BFUkZfTlJfQ09OVEVYVFNdKTsKc3RhdGljIGF0b21pY190IG5yX2NhbGxjaGFpbl9ldmVudHM7CnN0YXRpYyBERUZJTkVfTVVURVgoY2FsbGNoYWluX211dGV4KTsKc3RydWN0IGNhbGxjaGFpbl9jcHVzX2VudHJpZXMgKmNhbGxjaGFpbl9jcHVzX2VudHJpZXM7CgoKX193ZWFrIHZvaWQgcGVyZl9jYWxsY2hhaW5fa2VybmVsKHN0cnVjdCBwZXJmX2NhbGxjaGFpbl9lbnRyeSAqZW50cnksCgkJCQkgIHN0cnVjdCBwdF9yZWdzICpyZWdzKQp7Cn0KCl9fd2VhayB2b2lkIHBlcmZfY2FsbGNoYWluX3VzZXIoc3RydWN0IHBlcmZfY2FsbGNoYWluX2VudHJ5ICplbnRyeSwKCQkJCXN0cnVjdCBwdF9yZWdzICpyZWdzKQp7Cn0KCnN0YXRpYyB2b2lkIHJlbGVhc2VfY2FsbGNoYWluX2J1ZmZlcnNfcmN1KHN0cnVjdCByY3VfaGVhZCAqaGVhZCkKewoJc3RydWN0IGNhbGxjaGFpbl9jcHVzX2VudHJpZXMgKmVudHJpZXM7CglpbnQgY3B1OwoKCWVudHJpZXMgPSBjb250YWluZXJfb2YoaGVhZCwgc3RydWN0IGNhbGxjaGFpbl9jcHVzX2VudHJpZXMsIHJjdV9oZWFkKTsKCglmb3JfZWFjaF9wb3NzaWJsZV9jcHUoY3B1KQoJCWtmcmVlKGVudHJpZXMtPmNwdV9lbnRyaWVzW2NwdV0pOwoKCWtmcmVlKGVudHJpZXMpOwp9CgpzdGF0aWMgdm9pZCByZWxlYXNlX2NhbGxjaGFpbl9idWZmZXJzKHZvaWQpCnsKCXN0cnVjdCBjYWxsY2hhaW5fY3B1c19lbnRyaWVzICplbnRyaWVzOwoKCWVudHJpZXMgPSBjYWxsY2hhaW5fY3B1c19lbnRyaWVzOwoJcmN1X2Fzc2lnbl9wb2ludGVyKGNhbGxjaGFpbl9jcHVzX2VudHJpZXMsIE5VTEwpOwoJY2FsbF9yY3UoJmVudHJpZXMtPnJjdV9oZWFkLCByZWxlYXNlX2NhbGxjaGFpbl9idWZmZXJzX3JjdSk7Cn0KCnN0YXRpYyBpbnQgYWxsb2NfY2FsbGNoYWluX2J1ZmZlcnModm9pZCkKewoJaW50IGNwdTsKCWludCBzaXplOwoJc3RydWN0IGNhbGxjaGFpbl9jcHVzX2VudHJpZXMgKmVudHJpZXM7CgoJLyoKCSAqIFdlIGNhbid0IHVzZSB0aGUgcGVyY3B1IGFsbG9jYXRpb24gQVBJIGZvciBkYXRhIHRoYXQgY2FuIGJlCgkgKiBhY2Nlc3NlZCBmcm9tIE5NSS4gVXNlIGEgdGVtcG9yYXJ5IG1hbnVhbCBwZXIgY3B1IGFsbG9jYXRpb24KCSAqIHVudGlsIHRoYXQgZ2V0cyBzb3J0ZWQgb3V0LgoJICovCglzaXplID0gb2Zmc2V0b2Yoc3RydWN0IGNhbGxjaGFpbl9jcHVzX2VudHJpZXMsIGNwdV9lbnRyaWVzW25yX2NwdV9pZHNdKTsKCgllbnRyaWVzID0ga3phbGxvYyhzaXplLCBHRlBfS0VSTkVMKTsKCWlmICghZW50cmllcykKCQlyZXR1cm4gLUVOT01FTTsKCglzaXplID0gc2l6ZW9mKHN0cnVjdCBwZXJmX2NhbGxjaGFpbl9lbnRyeSkgKiBQRVJGX05SX0NPTlRFWFRTOwoKCWZvcl9lYWNoX3Bvc3NpYmxlX2NwdShjcHUpIHsKCQllbnRyaWVzLT5jcHVfZW50cmllc1tjcHVdID0ga21hbGxvY19ub2RlKHNpemUsIEdGUF9LRVJORUwsCgkJCQkJCQkgY3B1X3RvX25vZGUoY3B1KSk7CgkJaWYgKCFlbnRyaWVzLT5jcHVfZW50cmllc1tjcHVdKQoJCQlnb3RvIGZhaWw7Cgl9CgoJcmN1X2Fzc2lnbl9wb2ludGVyKGNhbGxjaGFpbl9jcHVzX2VudHJpZXMsIGVudHJpZXMpOwoKCXJldHVybiAwOwoKZmFpbDoKCWZvcl9lYWNoX3Bvc3NpYmxlX2NwdShjcHUpCgkJa2ZyZWUoZW50cmllcy0+Y3B1X2VudHJpZXNbY3B1XSk7CglrZnJlZShlbnRyaWVzKTsKCglyZXR1cm4gLUVOT01FTTsKfQoKc3RhdGljIGludCBnZXRfY2FsbGNoYWluX2J1ZmZlcnModm9pZCkKewoJaW50IGVyciA9IDA7CglpbnQgY291bnQ7CgoJbXV0ZXhfbG9jaygmY2FsbGNoYWluX211dGV4KTsKCgljb3VudCA9IGF0b21pY19pbmNfcmV0dXJuKCZucl9jYWxsY2hhaW5fZXZlbnRzKTsKCWlmIChXQVJOX09OX09OQ0UoY291bnQgPCAxKSkgewoJCWVyciA9IC1FSU5WQUw7CgkJZ290byBleGl0OwoJfQoKCWlmIChjb3VudCA+IDEpIHsKCQkvKiBJZiB0aGUgYWxsb2NhdGlvbiBmYWlsZWQsIGdpdmUgdXAgKi8KCQlpZiAoIWNhbGxjaGFpbl9jcHVzX2VudHJpZXMpCgkJCWVyciA9IC1FTk9NRU07CgkJZ290byBleGl0OwoJfQoKCWVyciA9IGFsbG9jX2NhbGxjaGFpbl9idWZmZXJzKCk7CglpZiAoZXJyKQoJCXJlbGVhc2VfY2FsbGNoYWluX2J1ZmZlcnMoKTsKZXhpdDoKCW11dGV4X3VubG9jaygmY2FsbGNoYWluX211dGV4KTsKCglyZXR1cm4gZXJyOwp9CgpzdGF0aWMgdm9pZCBwdXRfY2FsbGNoYWluX2J1ZmZlcnModm9pZCkKewoJaWYgKGF0b21pY19kZWNfYW5kX211dGV4X2xvY2soJm5yX2NhbGxjaGFpbl9ldmVudHMsICZjYWxsY2hhaW5fbXV0ZXgpKSB7CgkJcmVsZWFzZV9jYWxsY2hhaW5fYnVmZmVycygpOwoJCW11dGV4X3VubG9jaygmY2FsbGNoYWluX211dGV4KTsKCX0KfQoKc3RhdGljIGludCBnZXRfcmVjdXJzaW9uX2NvbnRleHQoaW50ICpyZWN1cnNpb24pCnsKCWludCByY3R4OwoKCWlmIChpbl9ubWkoKSkKCQlyY3R4ID0gMzsKCWVsc2UgaWYgKGluX2lycSgpKQoJCXJjdHggPSAyOwoJZWxzZSBpZiAoaW5fc29mdGlycSgpKQoJCXJjdHggPSAxOwoJZWxzZQoJCXJjdHggPSAwOwoKCWlmIChyZWN1cnNpb25bcmN0eF0pCgkJcmV0dXJuIC0xOwoKCXJlY3Vyc2lvbltyY3R4XSsrOwoJYmFycmllcigpOwoKCXJldHVybiByY3R4Owp9CgpzdGF0aWMgaW5saW5lIHZvaWQgcHV0X3JlY3Vyc2lvbl9jb250ZXh0KGludCAqcmVjdXJzaW9uLCBpbnQgcmN0eCkKewoJYmFycmllcigpOwoJcmVjdXJzaW9uW3JjdHhdLS07Cn0KCnN0YXRpYyBzdHJ1Y3QgcGVyZl9jYWxsY2hhaW5fZW50cnkgKmdldF9jYWxsY2hhaW5fZW50cnkoaW50ICpyY3R4KQp7CglpbnQgY3B1OwoJc3RydWN0IGNhbGxjaGFpbl9jcHVzX2VudHJpZXMgKmVudHJpZXM7CgoJKnJjdHggPSBnZXRfcmVjdXJzaW9uX2NvbnRleHQoX19nZXRfY3B1X3ZhcihjYWxsY2hhaW5fcmVjdXJzaW9uKSk7CglpZiAoKnJjdHggPT0gLTEpCgkJcmV0dXJuIE5VTEw7CgoJZW50cmllcyA9IHJjdV9kZXJlZmVyZW5jZShjYWxsY2hhaW5fY3B1c19lbnRyaWVzKTsKCWlmICghZW50cmllcykKCQlyZXR1cm4gTlVMTDsKCgljcHUgPSBzbXBfcHJvY2Vzc29yX2lkKCk7CgoJcmV0dXJuICZlbnRyaWVzLT5jcHVfZW50cmllc1tjcHVdWypyY3R4XTsKfQoKc3RhdGljIHZvaWQKcHV0X2NhbGxjaGFpbl9lbnRyeShpbnQgcmN0eCkKewoJcHV0X3JlY3Vyc2lvbl9jb250ZXh0KF9fZ2V0X2NwdV92YXIoY2FsbGNoYWluX3JlY3Vyc2lvbiksIHJjdHgpOwp9CgpzdGF0aWMgc3RydWN0IHBlcmZfY2FsbGNoYWluX2VudHJ5ICpwZXJmX2NhbGxjaGFpbihzdHJ1Y3QgcHRfcmVncyAqcmVncykKewoJaW50IHJjdHg7CglzdHJ1Y3QgcGVyZl9jYWxsY2hhaW5fZW50cnkgKmVudHJ5OwoKCgllbnRyeSA9IGdldF9jYWxsY2hhaW5fZW50cnkoJnJjdHgpOwoJaWYgKHJjdHggPT0gLTEpCgkJcmV0dXJuIE5VTEw7CgoJaWYgKCFlbnRyeSkKCQlnb3RvIGV4aXRfcHV0OwoKCWVudHJ5LT5uciA9IDA7CgoJaWYgKCF1c2VyX21vZGUocmVncykpIHsKCQlwZXJmX2NhbGxjaGFpbl9zdG9yZShlbnRyeSwgUEVSRl9DT05URVhUX0tFUk5FTCk7CgkJcGVyZl9jYWxsY2hhaW5fa2VybmVsKGVudHJ5LCByZWdzKTsKCQlpZiAoY3VycmVudC0+bW0pCgkJCXJlZ3MgPSB0YXNrX3B0X3JlZ3MoY3VycmVudCk7CgkJZWxzZQoJCQlyZWdzID0gTlVMTDsKCX0KCglpZiAocmVncykgewoJCXBlcmZfY2FsbGNoYWluX3N0b3JlKGVudHJ5LCBQRVJGX0NPTlRFWFRfVVNFUik7CgkJcGVyZl9jYWxsY2hhaW5fdXNlcihlbnRyeSwgcmVncyk7Cgl9CgpleGl0X3B1dDoKCXB1dF9jYWxsY2hhaW5fZW50cnkocmN0eCk7CgoJcmV0dXJuIGVudHJ5Owp9CgovKgogKiBJbml0aWFsaXplIHRoZSBwZXJmX2V2ZW50IGNvbnRleHQgaW4gYSB0YXNrX3N0cnVjdDoKICovCnN0YXRpYyB2b2lkIF9fcGVyZl9ldmVudF9pbml0X2NvbnRleHQoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglyYXdfc3Bpbl9sb2NrX2luaXQoJmN0eC0+bG9jayk7CgltdXRleF9pbml0KCZjdHgtPm11dGV4KTsKCUlOSVRfTElTVF9IRUFEKCZjdHgtPnBpbm5lZF9ncm91cHMpOwoJSU5JVF9MSVNUX0hFQUQoJmN0eC0+ZmxleGlibGVfZ3JvdXBzKTsKCUlOSVRfTElTVF9IRUFEKCZjdHgtPmV2ZW50X2xpc3QpOwoJYXRvbWljX3NldCgmY3R4LT5yZWZjb3VudCwgMSk7Cn0KCnN0YXRpYyBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICoKYWxsb2NfcGVyZl9jb250ZXh0KHN0cnVjdCBwbXUgKnBtdSwgc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrKQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHg7CgoJY3R4ID0ga3phbGxvYyhzaXplb2Yoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCksIEdGUF9LRVJORUwpOwoJaWYgKCFjdHgpCgkJcmV0dXJuIE5VTEw7CgoJX19wZXJmX2V2ZW50X2luaXRfY29udGV4dChjdHgpOwoJaWYgKHRhc2spIHsKCQljdHgtPnRhc2sgPSB0YXNrOwoJCWdldF90YXNrX3N0cnVjdCh0YXNrKTsKCX0KCWN0eC0+cG11ID0gcG11OwoKCXJldHVybiBjdHg7Cn0KCnN0YXRpYyBzdHJ1Y3QgdGFza19zdHJ1Y3QgKgpmaW5kX2xpdmVseV90YXNrX2J5X3ZwaWQocGlkX3QgdnBpZCkKewoJc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrOwoJaW50IGVycjsKCglyY3VfcmVhZF9sb2NrKCk7CglpZiAoIXZwaWQpCgkJdGFzayA9IGN1cnJlbnQ7CgllbHNlCgkJdGFzayA9IGZpbmRfdGFza19ieV92cGlkKHZwaWQpOwoJaWYgKHRhc2spCgkJZ2V0X3Rhc2tfc3RydWN0KHRhc2spOwoJcmN1X3JlYWRfdW5sb2NrKCk7CgoJaWYgKCF0YXNrKQoJCXJldHVybiBFUlJfUFRSKC1FU1JDSCk7CgoJLyogUmV1c2UgcHRyYWNlIHBlcm1pc3Npb24gY2hlY2tzIGZvciBub3cuICovCgllcnIgPSAtRUFDQ0VTOwoJaWYgKCFwdHJhY2VfbWF5X2FjY2Vzcyh0YXNrLCBQVFJBQ0VfTU9ERV9SRUFEKSkKCQlnb3RvIGVycm91dDsKCglyZXR1cm4gdGFzazsKZXJyb3V0OgoJcHV0X3Rhc2tfc3RydWN0KHRhc2spOwoJcmV0dXJuIEVSUl9QVFIoZXJyKTsKCn0KCi8qCiAqIFJldHVybnMgYSBtYXRjaGluZyBjb250ZXh0IHdpdGggcmVmY291bnQgYW5kIHBpbmNvdW50LgogKi8Kc3RhdGljIHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKgpmaW5kX2dldF9jb250ZXh0KHN0cnVjdCBwbXUgKnBtdSwgc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrLCBpbnQgY3B1KQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHg7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4OwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCWludCBjdHhuLCBlcnI7CgoJaWYgKCF0YXNrKSB7CgkJLyogTXVzdCBiZSByb290IHRvIG9wZXJhdGUgb24gYSBDUFUgZXZlbnQ6ICovCgkJaWYgKHBlcmZfcGFyYW5vaWRfY3B1KCkgJiYgIWNhcGFibGUoQ0FQX1NZU19BRE1JTikpCgkJCXJldHVybiBFUlJfUFRSKC1FQUNDRVMpOwoKCQkvKgoJCSAqIFdlIGNvdWxkIGJlIGNsZXZlciBhbmQgYWxsb3cgdG8gYXR0YWNoIGEgZXZlbnQgdG8gYW4KCQkgKiBvZmZsaW5lIENQVSBhbmQgYWN0aXZhdGUgaXQgd2hlbiB0aGUgQ1BVIGNvbWVzIHVwLCBidXQKCQkgKiB0aGF0J3MgZm9yIGxhdGVyLgoJCSAqLwoJCWlmICghY3B1X29ubGluZShjcHUpKQoJCQlyZXR1cm4gRVJSX1BUUigtRU5PREVWKTsKCgkJY3B1Y3R4ID0gcGVyX2NwdV9wdHIocG11LT5wbXVfY3B1X2NvbnRleHQsIGNwdSk7CgkJY3R4ID0gJmNwdWN0eC0+Y3R4OwoJCWdldF9jdHgoY3R4KTsKCQkrK2N0eC0+cGluX2NvdW50OwoKCQlyZXR1cm4gY3R4OwoJfQoKCWVyciA9IC1FSU5WQUw7CgljdHhuID0gcG11LT50YXNrX2N0eF9ucjsKCWlmIChjdHhuIDwgMCkKCQlnb3RvIGVycm91dDsKCnJldHJ5OgoJY3R4ID0gcGVyZl9sb2NrX3Rhc2tfY29udGV4dCh0YXNrLCBjdHhuLCAmZmxhZ3MpOwoJaWYgKGN0eCkgewoJCXVuY2xvbmVfY3R4KGN0eCk7CgkJKytjdHgtPnBpbl9jb3VudDsKCQlyYXdfc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY3R4LT5sb2NrLCBmbGFncyk7Cgl9CgoJaWYgKCFjdHgpIHsKCQljdHggPSBhbGxvY19wZXJmX2NvbnRleHQocG11LCB0YXNrKTsKCQllcnIgPSAtRU5PTUVNOwoJCWlmICghY3R4KQoJCQlnb3RvIGVycm91dDsKCgkJZ2V0X2N0eChjdHgpOwoKCQllcnIgPSAwOwoJCW11dGV4X2xvY2soJnRhc2stPnBlcmZfZXZlbnRfbXV0ZXgpOwoJCS8qCgkJICogSWYgaXQgaGFzIGFscmVhZHkgcGFzc2VkIHBlcmZfZXZlbnRfZXhpdF90YXNrKCkuCgkJICogd2UgbXVzdCBzZWUgUEZfRVhJVElORywgaXQgdGFrZXMgdGhpcyBtdXRleCB0b28uCgkJICovCgkJaWYgKHRhc2stPmZsYWdzICYgUEZfRVhJVElORykKCQkJZXJyID0gLUVTUkNIOwoJCWVsc2UgaWYgKHRhc2stPnBlcmZfZXZlbnRfY3R4cFtjdHhuXSkKCQkJZXJyID0gLUVBR0FJTjsKCQllbHNlIHsKCQkJKytjdHgtPnBpbl9jb3VudDsKCQkJcmN1X2Fzc2lnbl9wb2ludGVyKHRhc2stPnBlcmZfZXZlbnRfY3R4cFtjdHhuXSwgY3R4KTsKCQl9CgkJbXV0ZXhfdW5sb2NrKCZ0YXNrLT5wZXJmX2V2ZW50X211dGV4KTsKCgkJaWYgKHVubGlrZWx5KGVycikpIHsKCQkJcHV0X3Rhc2tfc3RydWN0KHRhc2spOwoJCQlrZnJlZShjdHgpOwoKCQkJaWYgKGVyciA9PSAtRUFHQUlOKQoJCQkJZ290byByZXRyeTsKCQkJZ290byBlcnJvdXQ7CgkJfQoJfQoKCXJldHVybiBjdHg7CgplcnJvdXQ6CglyZXR1cm4gRVJSX1BUUihlcnIpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X2ZyZWVfZmlsdGVyKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCk7CgpzdGF0aWMgdm9pZCBmcmVlX2V2ZW50X3JjdShzdHJ1Y3QgcmN1X2hlYWQgKmhlYWQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCglldmVudCA9IGNvbnRhaW5lcl9vZihoZWFkLCBzdHJ1Y3QgcGVyZl9ldmVudCwgcmN1X2hlYWQpOwoJaWYgKGV2ZW50LT5ucykKCQlwdXRfcGlkX25zKGV2ZW50LT5ucyk7CglwZXJmX2V2ZW50X2ZyZWVfZmlsdGVyKGV2ZW50KTsKCWtmcmVlKGV2ZW50KTsKfQoKc3RhdGljIHZvaWQgcGVyZl9idWZmZXJfcHV0KHN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyKTsKCnN0YXRpYyB2b2lkIGZyZWVfZXZlbnQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglpcnFfd29ya19zeW5jKCZldmVudC0+cGVuZGluZyk7CgoJaWYgKCFldmVudC0+cGFyZW50KSB7CgkJaWYgKGV2ZW50LT5hdHRhY2hfc3RhdGUgJiBQRVJGX0FUVEFDSF9UQVNLKQoJCQlqdW1wX2xhYmVsX2RlYygmcGVyZl90YXNrX2V2ZW50cyk7CgkJaWYgKGV2ZW50LT5hdHRyLm1tYXAgfHwgZXZlbnQtPmF0dHIubW1hcF9kYXRhKQoJCQlhdG9taWNfZGVjKCZucl9tbWFwX2V2ZW50cyk7CgkJaWYgKGV2ZW50LT5hdHRyLmNvbW0pCgkJCWF0b21pY19kZWMoJm5yX2NvbW1fZXZlbnRzKTsKCQlpZiAoZXZlbnQtPmF0dHIudGFzaykKCQkJYXRvbWljX2RlYygmbnJfdGFza19ldmVudHMpOwoJCWlmIChldmVudC0+YXR0ci5zYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0NBTExDSEFJTikKCQkJcHV0X2NhbGxjaGFpbl9idWZmZXJzKCk7Cgl9CgoJaWYgKGV2ZW50LT5idWZmZXIpIHsKCQlwZXJmX2J1ZmZlcl9wdXQoZXZlbnQtPmJ1ZmZlcik7CgkJZXZlbnQtPmJ1ZmZlciA9IE5VTEw7Cgl9CgoJaWYgKGV2ZW50LT5kZXN0cm95KQoJCWV2ZW50LT5kZXN0cm95KGV2ZW50KTsKCglpZiAoZXZlbnQtPmN0eCkKCQlwdXRfY3R4KGV2ZW50LT5jdHgpOwoKCWNhbGxfcmN1KCZldmVudC0+cmN1X2hlYWQsIGZyZWVfZXZlbnRfcmN1KTsKfQoKaW50IHBlcmZfZXZlbnRfcmVsZWFzZV9rZXJuZWwoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSBldmVudC0+Y3R4OwoKCS8qCgkgKiBSZW1vdmUgZnJvbSB0aGUgUE1VLCBjYW4ndCBnZXQgcmUtZW5hYmxlZCBzaW5jZSB3ZSBnb3QKCSAqIGhlcmUgYmVjYXVzZSB0aGUgbGFzdCByZWYgd2VudC4KCSAqLwoJcGVyZl9ldmVudF9kaXNhYmxlKGV2ZW50KTsKCglXQVJOX09OX09OQ0UoY3R4LT5wYXJlbnRfY3R4KTsKCS8qCgkgKiBUaGVyZSBhcmUgdHdvIHdheXMgdGhpcyBhbm5vdGF0aW9uIGlzIHVzZWZ1bDoKCSAqCgkgKiAgMSkgdGhlcmUgaXMgYSBsb2NrIHJlY3Vyc2lvbiBmcm9tIHBlcmZfZXZlbnRfZXhpdF90YXNrCgkgKiAgICAgc2VlIHRoZSBjb21tZW50IHRoZXJlLgoJICoKCSAqICAyKSB0aGVyZSBpcyBhIGxvY2staW52ZXJzaW9uIHdpdGggbW1hcF9zZW0gdGhyb3VnaAoJICogICAgIHBlcmZfZXZlbnRfcmVhZF9ncm91cCgpLCB3aGljaCB0YWtlcyBmYXVsdHMgd2hpbGUKCSAqICAgICBob2xkaW5nIGN0eC0+bXV0ZXgsIGhvd2V2ZXIgdGhpcyBpcyBjYWxsZWQgYWZ0ZXIKCSAqICAgICB0aGUgbGFzdCBmaWxlZGVzYyBkaWVkLCBzbyB0aGVyZSBpcyBubyBwb3NzaWJpbGl0eQoJICogICAgIHRvIHRyaWdnZXIgdGhlIEFCLUJBIGNhc2UuCgkgKi8KCW11dGV4X2xvY2tfbmVzdGVkKCZjdHgtPm11dGV4LCBTSU5HTEVfREVQVEhfTkVTVElORyk7CglyYXdfc3Bpbl9sb2NrX2lycSgmY3R4LT5sb2NrKTsKCXBlcmZfZ3JvdXBfZGV0YWNoKGV2ZW50KTsKCWxpc3RfZGVsX2V2ZW50KGV2ZW50LCBjdHgpOwoJcmF3X3NwaW5fdW5sb2NrX2lycSgmY3R4LT5sb2NrKTsKCW11dGV4X3VubG9jaygmY3R4LT5tdXRleCk7CgoJZnJlZV9ldmVudChldmVudCk7CgoJcmV0dXJuIDA7Cn0KRVhQT1JUX1NZTUJPTF9HUEwocGVyZl9ldmVudF9yZWxlYXNlX2tlcm5lbCk7CgovKgogKiBDYWxsZWQgd2hlbiB0aGUgbGFzdCByZWZlcmVuY2UgdG8gdGhlIGZpbGUgaXMgZ29uZS4KICovCnN0YXRpYyBpbnQgcGVyZl9yZWxlYXNlKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQgPSBmaWxlLT5wcml2YXRlX2RhdGE7CglzdHJ1Y3QgdGFza19zdHJ1Y3QgKm93bmVyOwoKCWZpbGUtPnByaXZhdGVfZGF0YSA9IE5VTEw7CgoJcmN1X3JlYWRfbG9jaygpOwoJb3duZXIgPSBBQ0NFU1NfT05DRShldmVudC0+b3duZXIpOwoJLyoKCSAqIE1hdGNoZXMgdGhlIHNtcF93bWIoKSBpbiBwZXJmX2V2ZW50X2V4aXRfdGFzaygpLiBJZiB3ZSBvYnNlcnZlCgkgKiAhb3duZXIgaXQgbWVhbnMgdGhlIGxpc3QgZGVsZXRpb24gaXMgY29tcGxldGUgYW5kIHdlIGNhbiBpbmRlZWQKCSAqIGZyZWUgdGhpcyBldmVudCwgb3RoZXJ3aXNlIHdlIG5lZWQgdG8gc2VyaWFsaXplIG9uCgkgKiBvd25lci0+cGVyZl9ldmVudF9tdXRleC4KCSAqLwoJc21wX3JlYWRfYmFycmllcl9kZXBlbmRzKCk7CglpZiAob3duZXIpIHsKCQkvKgoJCSAqIFNpbmNlIGRlbGF5ZWRfcHV0X3Rhc2tfc3RydWN0KCkgYWxzbyBkcm9wcyB0aGUgbGFzdAoJCSAqIHRhc2sgcmVmZXJlbmNlIHdlIGNhbiBzYWZlbHkgdGFrZSBhIG5ldyByZWZlcmVuY2UKCQkgKiB3aGlsZSBob2xkaW5nIHRoZSByY3VfcmVhZF9sb2NrKCkuCgkJICovCgkJZ2V0X3Rhc2tfc3RydWN0KG93bmVyKTsKCX0KCXJjdV9yZWFkX3VubG9jaygpOwoKCWlmIChvd25lcikgewoJCW11dGV4X2xvY2soJm93bmVyLT5wZXJmX2V2ZW50X211dGV4KTsKCQkvKgoJCSAqIFdlIGhhdmUgdG8gcmUtY2hlY2sgdGhlIGV2ZW50LT5vd25lciBmaWVsZCwgaWYgaXQgaXMgY2xlYXJlZAoJCSAqIHdlIHJhY2VkIHdpdGggcGVyZl9ldmVudF9leGl0X3Rhc2soKSwgYWNxdWlyaW5nIHRoZSBtdXRleAoJCSAqIGVuc3VyZWQgdGhleSdyZSBkb25lLCBhbmQgd2UgY2FuIHByb2NlZWQgd2l0aCBmcmVlaW5nIHRoZQoJCSAqIGV2ZW50LgoJCSAqLwoJCWlmIChldmVudC0+b3duZXIpCgkJCWxpc3RfZGVsX2luaXQoJmV2ZW50LT5vd25lcl9lbnRyeSk7CgkJbXV0ZXhfdW5sb2NrKCZvd25lci0+cGVyZl9ldmVudF9tdXRleCk7CgkJcHV0X3Rhc2tfc3RydWN0KG93bmVyKTsKCX0KCglyZXR1cm4gcGVyZl9ldmVudF9yZWxlYXNlX2tlcm5lbChldmVudCk7Cn0KCnU2NCBwZXJmX2V2ZW50X3JlYWRfdmFsdWUoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCB1NjQgKmVuYWJsZWQsIHU2NCAqcnVubmluZykKewoJc3RydWN0IHBlcmZfZXZlbnQgKmNoaWxkOwoJdTY0IHRvdGFsID0gMDsKCgkqZW5hYmxlZCA9IDA7CgkqcnVubmluZyA9IDA7CgoJbXV0ZXhfbG9jaygmZXZlbnQtPmNoaWxkX211dGV4KTsKCXRvdGFsICs9IHBlcmZfZXZlbnRfcmVhZChldmVudCk7CgkqZW5hYmxlZCArPSBldmVudC0+dG90YWxfdGltZV9lbmFibGVkICsKCQkJYXRvbWljNjRfcmVhZCgmZXZlbnQtPmNoaWxkX3RvdGFsX3RpbWVfZW5hYmxlZCk7CgkqcnVubmluZyArPSBldmVudC0+dG90YWxfdGltZV9ydW5uaW5nICsKCQkJYXRvbWljNjRfcmVhZCgmZXZlbnQtPmNoaWxkX3RvdGFsX3RpbWVfcnVubmluZyk7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeShjaGlsZCwgJmV2ZW50LT5jaGlsZF9saXN0LCBjaGlsZF9saXN0KSB7CgkJdG90YWwgKz0gcGVyZl9ldmVudF9yZWFkKGNoaWxkKTsKCQkqZW5hYmxlZCArPSBjaGlsZC0+dG90YWxfdGltZV9lbmFibGVkOwoJCSpydW5uaW5nICs9IGNoaWxkLT50b3RhbF90aW1lX3J1bm5pbmc7Cgl9CgltdXRleF91bmxvY2soJmV2ZW50LT5jaGlsZF9tdXRleCk7CgoJcmV0dXJuIHRvdGFsOwp9CkVYUE9SVF9TWU1CT0xfR1BMKHBlcmZfZXZlbnRfcmVhZF92YWx1ZSk7CgpzdGF0aWMgaW50IHBlcmZfZXZlbnRfcmVhZF9ncm91cChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCQkgICB1NjQgcmVhZF9mb3JtYXQsIGNoYXIgX191c2VyICpidWYpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpsZWFkZXIgPSBldmVudC0+Z3JvdXBfbGVhZGVyLCAqc3ViOwoJaW50IG4gPSAwLCBzaXplID0gMCwgcmV0ID0gLUVGQVVMVDsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IGxlYWRlci0+Y3R4OwoJdTY0IHZhbHVlc1s1XTsKCXU2NCBjb3VudCwgZW5hYmxlZCwgcnVubmluZzsKCgltdXRleF9sb2NrKCZjdHgtPm11dGV4KTsKCWNvdW50ID0gcGVyZl9ldmVudF9yZWFkX3ZhbHVlKGxlYWRlciwgJmVuYWJsZWQsICZydW5uaW5nKTsKCgl2YWx1ZXNbbisrXSA9IDEgKyBsZWFkZXItPm5yX3NpYmxpbmdzOwoJaWYgKHJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfVE9UQUxfVElNRV9FTkFCTEVEKQoJCXZhbHVlc1tuKytdID0gZW5hYmxlZDsKCWlmIChyZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX1RPVEFMX1RJTUVfUlVOTklORykKCQl2YWx1ZXNbbisrXSA9IHJ1bm5pbmc7Cgl2YWx1ZXNbbisrXSA9IGNvdW50OwoJaWYgKHJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfSUQpCgkJdmFsdWVzW24rK10gPSBwcmltYXJ5X2V2ZW50X2lkKGxlYWRlcik7CgoJc2l6ZSA9IG4gKiBzaXplb2YodTY0KTsKCglpZiAoY29weV90b191c2VyKGJ1ZiwgdmFsdWVzLCBzaXplKSkKCQlnb3RvIHVubG9jazsKCglyZXQgPSBzaXplOwoKCWxpc3RfZm9yX2VhY2hfZW50cnkoc3ViLCAmbGVhZGVyLT5zaWJsaW5nX2xpc3QsIGdyb3VwX2VudHJ5KSB7CgkJbiA9IDA7CgoJCXZhbHVlc1tuKytdID0gcGVyZl9ldmVudF9yZWFkX3ZhbHVlKHN1YiwgJmVuYWJsZWQsICZydW5uaW5nKTsKCQlpZiAocmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9JRCkKCQkJdmFsdWVzW24rK10gPSBwcmltYXJ5X2V2ZW50X2lkKHN1Yik7CgoJCXNpemUgPSBuICogc2l6ZW9mKHU2NCk7CgoJCWlmIChjb3B5X3RvX3VzZXIoYnVmICsgcmV0LCB2YWx1ZXMsIHNpemUpKSB7CgkJCXJldCA9IC1FRkFVTFQ7CgkJCWdvdG8gdW5sb2NrOwoJCX0KCgkJcmV0ICs9IHNpemU7Cgl9CnVubG9jazoKCW11dGV4X3VubG9jaygmY3R4LT5tdXRleCk7CgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIGludCBwZXJmX2V2ZW50X3JlYWRfb25lKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJCSB1NjQgcmVhZF9mb3JtYXQsIGNoYXIgX191c2VyICpidWYpCnsKCXU2NCBlbmFibGVkLCBydW5uaW5nOwoJdTY0IHZhbHVlc1s0XTsKCWludCBuID0gMDsKCgl2YWx1ZXNbbisrXSA9IHBlcmZfZXZlbnRfcmVhZF92YWx1ZShldmVudCwgJmVuYWJsZWQsICZydW5uaW5nKTsKCWlmIChyZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX1RPVEFMX1RJTUVfRU5BQkxFRCkKCQl2YWx1ZXNbbisrXSA9IGVuYWJsZWQ7CglpZiAocmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9UT1RBTF9USU1FX1JVTk5JTkcpCgkJdmFsdWVzW24rK10gPSBydW5uaW5nOwoJaWYgKHJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfSUQpCgkJdmFsdWVzW24rK10gPSBwcmltYXJ5X2V2ZW50X2lkKGV2ZW50KTsKCglpZiAoY29weV90b191c2VyKGJ1ZiwgdmFsdWVzLCBuICogc2l6ZW9mKHU2NCkpKQoJCXJldHVybiAtRUZBVUxUOwoKCXJldHVybiBuICogc2l6ZW9mKHU2NCk7Cn0KCi8qCiAqIFJlYWQgdGhlIHBlcmZvcm1hbmNlIGV2ZW50IC0gc2ltcGxlIG5vbiBibG9ja2luZyB2ZXJzaW9uIGZvciBub3cKICovCnN0YXRpYyBzc2l6ZV90CnBlcmZfcmVhZF9odyhzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIGNoYXIgX191c2VyICpidWYsIHNpemVfdCBjb3VudCkKewoJdTY0IHJlYWRfZm9ybWF0ID0gZXZlbnQtPmF0dHIucmVhZF9mb3JtYXQ7CglpbnQgcmV0OwoKCS8qCgkgKiBSZXR1cm4gZW5kLW9mLWZpbGUgZm9yIGEgcmVhZCBvbiBhIGV2ZW50IHRoYXQgaXMgaW4KCSAqIGVycm9yIHN0YXRlIChpLmUuIGJlY2F1c2UgaXQgd2FzIHBpbm5lZCBidXQgaXQgY291bGRuJ3QgYmUKCSAqIHNjaGVkdWxlZCBvbiB0byB0aGUgQ1BVIGF0IHNvbWUgcG9pbnQpLgoJICovCglpZiAoZXZlbnQtPnN0YXRlID09IFBFUkZfRVZFTlRfU1RBVEVfRVJST1IpCgkJcmV0dXJuIDA7CgoJaWYgKGNvdW50IDwgZXZlbnQtPnJlYWRfc2l6ZSkKCQlyZXR1cm4gLUVOT1NQQzsKCglXQVJOX09OX09OQ0UoZXZlbnQtPmN0eC0+cGFyZW50X2N0eCk7CglpZiAocmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9HUk9VUCkKCQlyZXQgPSBwZXJmX2V2ZW50X3JlYWRfZ3JvdXAoZXZlbnQsIHJlYWRfZm9ybWF0LCBidWYpOwoJZWxzZQoJCXJldCA9IHBlcmZfZXZlbnRfcmVhZF9vbmUoZXZlbnQsIHJlYWRfZm9ybWF0LCBidWYpOwoKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBzc2l6ZV90CnBlcmZfcmVhZChzdHJ1Y3QgZmlsZSAqZmlsZSwgY2hhciBfX3VzZXIgKmJ1Ziwgc2l6ZV90IGNvdW50LCBsb2ZmX3QgKnBwb3MpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCglyZXR1cm4gcGVyZl9yZWFkX2h3KGV2ZW50LCBidWYsIGNvdW50KTsKfQoKc3RhdGljIHVuc2lnbmVkIGludCBwZXJmX3BvbGwoc3RydWN0IGZpbGUgKmZpbGUsIHBvbGxfdGFibGUgKndhaXQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCXN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyOwoJdW5zaWduZWQgaW50IGV2ZW50cyA9IFBPTExfSFVQOwoKCXJjdV9yZWFkX2xvY2soKTsKCWJ1ZmZlciA9IHJjdV9kZXJlZmVyZW5jZShldmVudC0+YnVmZmVyKTsKCWlmIChidWZmZXIpCgkJZXZlbnRzID0gYXRvbWljX3hjaGcoJmJ1ZmZlci0+cG9sbCwgMCk7CglyY3VfcmVhZF91bmxvY2soKTsKCglwb2xsX3dhaXQoZmlsZSwgJmV2ZW50LT53YWl0cSwgd2FpdCk7CgoJcmV0dXJuIGV2ZW50czsKfQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9yZXNldChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCSh2b2lkKXBlcmZfZXZlbnRfcmVhZChldmVudCk7Cglsb2NhbDY0X3NldCgmZXZlbnQtPmNvdW50LCAwKTsKCXBlcmZfZXZlbnRfdXBkYXRlX3VzZXJwYWdlKGV2ZW50KTsKfQoKLyoKICogSG9sZGluZyB0aGUgdG9wLWxldmVsIGV2ZW50J3MgY2hpbGRfbXV0ZXggbWVhbnMgdGhhdCBhbnkKICogZGVzY2VuZGFudCBwcm9jZXNzIHRoYXQgaGFzIGluaGVyaXRlZCB0aGlzIGV2ZW50IHdpbGwgYmxvY2sKICogaW4gc3luY19jaGlsZF9ldmVudCBpZiBpdCBnb2VzIHRvIGV4aXQsIHRodXMgc2F0aXNmeWluZyB0aGUKICogdGFzayBleGlzdGVuY2UgcmVxdWlyZW1lbnRzIG9mIHBlcmZfZXZlbnRfZW5hYmxlL2Rpc2FibGUuCiAqLwpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X2Zvcl9lYWNoX2NoaWxkKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJCQl2b2lkICgqZnVuYykoc3RydWN0IHBlcmZfZXZlbnQgKikpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpjaGlsZDsKCglXQVJOX09OX09OQ0UoZXZlbnQtPmN0eC0+cGFyZW50X2N0eCk7CgltdXRleF9sb2NrKCZldmVudC0+Y2hpbGRfbXV0ZXgpOwoJZnVuYyhldmVudCk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KGNoaWxkLCAmZXZlbnQtPmNoaWxkX2xpc3QsIGNoaWxkX2xpc3QpCgkJZnVuYyhjaGlsZCk7CgltdXRleF91bmxvY2soJmV2ZW50LT5jaGlsZF9tdXRleCk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfZm9yX2VhY2goc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJICB2b2lkICgqZnVuYykoc3RydWN0IHBlcmZfZXZlbnQgKikpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IGV2ZW50LT5jdHg7CglzdHJ1Y3QgcGVyZl9ldmVudCAqc2libGluZzsKCglXQVJOX09OX09OQ0UoY3R4LT5wYXJlbnRfY3R4KTsKCW11dGV4X2xvY2soJmN0eC0+bXV0ZXgpOwoJZXZlbnQgPSBldmVudC0+Z3JvdXBfbGVhZGVyOwoKCXBlcmZfZXZlbnRfZm9yX2VhY2hfY2hpbGQoZXZlbnQsIGZ1bmMpOwoJZnVuYyhldmVudCk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KHNpYmxpbmcsICZldmVudC0+c2libGluZ19saXN0LCBncm91cF9lbnRyeSkKCQlwZXJmX2V2ZW50X2Zvcl9lYWNoX2NoaWxkKGV2ZW50LCBmdW5jKTsKCW11dGV4X3VubG9jaygmY3R4LT5tdXRleCk7Cn0KCnN0YXRpYyBpbnQgcGVyZl9ldmVudF9wZXJpb2Qoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCB1NjQgX191c2VyICphcmcpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IGV2ZW50LT5jdHg7CglpbnQgcmV0ID0gMDsKCXU2NCB2YWx1ZTsKCglpZiAoIWlzX3NhbXBsaW5nX2V2ZW50KGV2ZW50KSkKCQlyZXR1cm4gLUVJTlZBTDsKCglpZiAoY29weV9mcm9tX3VzZXIoJnZhbHVlLCBhcmcsIHNpemVvZih2YWx1ZSkpKQoJCXJldHVybiAtRUZBVUxUOwoKCWlmICghdmFsdWUpCgkJcmV0dXJuIC1FSU5WQUw7CgoJcmF3X3NwaW5fbG9ja19pcnEoJmN0eC0+bG9jayk7CglpZiAoZXZlbnQtPmF0dHIuZnJlcSkgewoJCWlmICh2YWx1ZSA+IHN5c2N0bF9wZXJmX2V2ZW50X3NhbXBsZV9yYXRlKSB7CgkJCXJldCA9IC1FSU5WQUw7CgkJCWdvdG8gdW5sb2NrOwoJCX0KCgkJZXZlbnQtPmF0dHIuc2FtcGxlX2ZyZXEgPSB2YWx1ZTsKCX0gZWxzZSB7CgkJZXZlbnQtPmF0dHIuc2FtcGxlX3BlcmlvZCA9IHZhbHVlOwoJCWV2ZW50LT5ody5zYW1wbGVfcGVyaW9kID0gdmFsdWU7Cgl9CnVubG9jazoKCXJhd19zcGluX3VubG9ja19pcnEoJmN0eC0+bG9jayk7CgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIGNvbnN0IHN0cnVjdCBmaWxlX29wZXJhdGlvbnMgcGVyZl9mb3BzOwoKc3RhdGljIHN0cnVjdCBwZXJmX2V2ZW50ICpwZXJmX2ZnZXRfbGlnaHQoaW50IGZkLCBpbnQgKmZwdXRfbmVlZGVkKQp7CglzdHJ1Y3QgZmlsZSAqZmlsZTsKCglmaWxlID0gZmdldF9saWdodChmZCwgZnB1dF9uZWVkZWQpOwoJaWYgKCFmaWxlKQoJCXJldHVybiBFUlJfUFRSKC1FQkFERik7CgoJaWYgKGZpbGUtPmZfb3AgIT0gJnBlcmZfZm9wcykgewoJCWZwdXRfbGlnaHQoZmlsZSwgKmZwdXRfbmVlZGVkKTsKCQkqZnB1dF9uZWVkZWQgPSAwOwoJCXJldHVybiBFUlJfUFRSKC1FQkFERik7Cgl9CgoJcmV0dXJuIGZpbGUtPnByaXZhdGVfZGF0YTsKfQoKc3RhdGljIGludCBwZXJmX2V2ZW50X3NldF9vdXRwdXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJIHN0cnVjdCBwZXJmX2V2ZW50ICpvdXRwdXRfZXZlbnQpOwpzdGF0aWMgaW50IHBlcmZfZXZlbnRfc2V0X2ZpbHRlcihzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIHZvaWQgX191c2VyICphcmcpOwoKc3RhdGljIGxvbmcgcGVyZl9pb2N0bChzdHJ1Y3QgZmlsZSAqZmlsZSwgdW5zaWduZWQgaW50IGNtZCwgdW5zaWduZWQgbG9uZyBhcmcpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCXZvaWQgKCpmdW5jKShzdHJ1Y3QgcGVyZl9ldmVudCAqKTsKCXUzMiBmbGFncyA9IGFyZzsKCglzd2l0Y2ggKGNtZCkgewoJY2FzZSBQRVJGX0VWRU5UX0lPQ19FTkFCTEU6CgkJZnVuYyA9IHBlcmZfZXZlbnRfZW5hYmxlOwoJCWJyZWFrOwoJY2FzZSBQRVJGX0VWRU5UX0lPQ19ESVNBQkxFOgoJCWZ1bmMgPSBwZXJmX2V2ZW50X2Rpc2FibGU7CgkJYnJlYWs7CgljYXNlIFBFUkZfRVZFTlRfSU9DX1JFU0VUOgoJCWZ1bmMgPSBwZXJmX2V2ZW50X3Jlc2V0OwoJCWJyZWFrOwoKCWNhc2UgUEVSRl9FVkVOVF9JT0NfUkVGUkVTSDoKCQlyZXR1cm4gcGVyZl9ldmVudF9yZWZyZXNoKGV2ZW50LCBhcmcpOwoKCWNhc2UgUEVSRl9FVkVOVF9JT0NfUEVSSU9EOgoJCXJldHVybiBwZXJmX2V2ZW50X3BlcmlvZChldmVudCwgKHU2NCBfX3VzZXIgKilhcmcpOwoKCWNhc2UgUEVSRl9FVkVOVF9JT0NfU0VUX09VVFBVVDoKCXsKCQlzdHJ1Y3QgcGVyZl9ldmVudCAqb3V0cHV0X2V2ZW50ID0gTlVMTDsKCQlpbnQgZnB1dF9uZWVkZWQgPSAwOwoJCWludCByZXQ7CgoJCWlmIChhcmcgIT0gLTEpIHsKCQkJb3V0cHV0X2V2ZW50ID0gcGVyZl9mZ2V0X2xpZ2h0KGFyZywgJmZwdXRfbmVlZGVkKTsKCQkJaWYgKElTX0VSUihvdXRwdXRfZXZlbnQpKQoJCQkJcmV0dXJuIFBUUl9FUlIob3V0cHV0X2V2ZW50KTsKCQl9CgoJCXJldCA9IHBlcmZfZXZlbnRfc2V0X291dHB1dChldmVudCwgb3V0cHV0X2V2ZW50KTsKCQlpZiAob3V0cHV0X2V2ZW50KQoJCQlmcHV0X2xpZ2h0KG91dHB1dF9ldmVudC0+ZmlscCwgZnB1dF9uZWVkZWQpOwoKCQlyZXR1cm4gcmV0OwoJfQoKCWNhc2UgUEVSRl9FVkVOVF9JT0NfU0VUX0ZJTFRFUjoKCQlyZXR1cm4gcGVyZl9ldmVudF9zZXRfZmlsdGVyKGV2ZW50LCAodm9pZCBfX3VzZXIgKilhcmcpOwoKCWRlZmF1bHQ6CgkJcmV0dXJuIC1FTk9UVFk7Cgl9CgoJaWYgKGZsYWdzICYgUEVSRl9JT0NfRkxBR19HUk9VUCkKCQlwZXJmX2V2ZW50X2Zvcl9lYWNoKGV2ZW50LCBmdW5jKTsKCWVsc2UKCQlwZXJmX2V2ZW50X2Zvcl9lYWNoX2NoaWxkKGV2ZW50LCBmdW5jKTsKCglyZXR1cm4gMDsKfQoKaW50IHBlcmZfZXZlbnRfdGFza19lbmFibGUodm9pZCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoKCW11dGV4X2xvY2soJmN1cnJlbnQtPnBlcmZfZXZlbnRfbXV0ZXgpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShldmVudCwgJmN1cnJlbnQtPnBlcmZfZXZlbnRfbGlzdCwgb3duZXJfZW50cnkpCgkJcGVyZl9ldmVudF9mb3JfZWFjaF9jaGlsZChldmVudCwgcGVyZl9ldmVudF9lbmFibGUpOwoJbXV0ZXhfdW5sb2NrKCZjdXJyZW50LT5wZXJmX2V2ZW50X211dGV4KTsKCglyZXR1cm4gMDsKfQoKaW50IHBlcmZfZXZlbnRfdGFza19kaXNhYmxlKHZvaWQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCgltdXRleF9sb2NrKCZjdXJyZW50LT5wZXJmX2V2ZW50X211dGV4KTsKCWxpc3RfZm9yX2VhY2hfZW50cnkoZXZlbnQsICZjdXJyZW50LT5wZXJmX2V2ZW50X2xpc3QsIG93bmVyX2VudHJ5KQoJCXBlcmZfZXZlbnRfZm9yX2VhY2hfY2hpbGQoZXZlbnQsIHBlcmZfZXZlbnRfZGlzYWJsZSk7CgltdXRleF91bmxvY2soJmN1cnJlbnQtPnBlcmZfZXZlbnRfbXV0ZXgpOwoKCXJldHVybiAwOwp9CgojaWZuZGVmIFBFUkZfRVZFTlRfSU5ERVhfT0ZGU0VUCiMgZGVmaW5lIFBFUkZfRVZFTlRfSU5ERVhfT0ZGU0VUIDAKI2VuZGlmCgpzdGF0aWMgaW50IHBlcmZfZXZlbnRfaW5kZXgoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglpZiAoZXZlbnQtPmh3LnN0YXRlICYgUEVSRl9IRVNfU1RPUFBFRCkKCQlyZXR1cm4gMDsKCglpZiAoZXZlbnQtPnN0YXRlICE9IFBFUkZfRVZFTlRfU1RBVEVfQUNUSVZFKQoJCXJldHVybiAwOwoKCXJldHVybiBldmVudC0+aHcuaWR4ICsgMSAtIFBFUkZfRVZFTlRfSU5ERVhfT0ZGU0VUOwp9CgovKgogKiBDYWxsZXJzIG5lZWQgdG8gZW5zdXJlIHRoZXJlIGNhbiBiZSBubyBuZXN0aW5nIG9mIHRoaXMgZnVuY3Rpb24sIG90aGVyd2lzZQogKiB0aGUgc2VxbG9jayBsb2dpYyBnb2VzIGJhZC4gV2UgY2FuIG5vdCBzZXJpYWxpemUgdGhpcyBiZWNhdXNlIHRoZSBhcmNoCiAqIGNvZGUgY2FsbHMgdGhpcyBmcm9tIE5NSSBjb250ZXh0LgogKi8Kdm9pZCBwZXJmX2V2ZW50X3VwZGF0ZV91c2VycGFnZShzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X21tYXBfcGFnZSAqdXNlcnBnOwoJc3RydWN0IHBlcmZfYnVmZmVyICpidWZmZXI7CgoJcmN1X3JlYWRfbG9jaygpOwoJYnVmZmVyID0gcmN1X2RlcmVmZXJlbmNlKGV2ZW50LT5idWZmZXIpOwoJaWYgKCFidWZmZXIpCgkJZ290byB1bmxvY2s7CgoJdXNlcnBnID0gYnVmZmVyLT51c2VyX3BhZ2U7CgoJLyoKCSAqIERpc2FibGUgcHJlZW1wdGlvbiBzbyBhcyB0byBub3QgbGV0IHRoZSBjb3JyZXNwb25kaW5nIHVzZXItc3BhY2UKCSAqIHNwaW4gdG9vIGxvbmcgaWYgd2UgZ2V0IHByZWVtcHRlZC4KCSAqLwoJcHJlZW1wdF9kaXNhYmxlKCk7CgkrK3VzZXJwZy0+bG9jazsKCWJhcnJpZXIoKTsKCXVzZXJwZy0+aW5kZXggPSBwZXJmX2V2ZW50X2luZGV4KGV2ZW50KTsKCXVzZXJwZy0+b2Zmc2V0ID0gcGVyZl9ldmVudF9jb3VudChldmVudCk7CglpZiAoZXZlbnQtPnN0YXRlID09IFBFUkZfRVZFTlRfU1RBVEVfQUNUSVZFKQoJCXVzZXJwZy0+b2Zmc2V0IC09IGxvY2FsNjRfcmVhZCgmZXZlbnQtPmh3LnByZXZfY291bnQpOwoKCXVzZXJwZy0+dGltZV9lbmFibGVkID0gZXZlbnQtPnRvdGFsX3RpbWVfZW5hYmxlZCArCgkJCWF0b21pYzY0X3JlYWQoJmV2ZW50LT5jaGlsZF90b3RhbF90aW1lX2VuYWJsZWQpOwoKCXVzZXJwZy0+dGltZV9ydW5uaW5nID0gZXZlbnQtPnRvdGFsX3RpbWVfcnVubmluZyArCgkJCWF0b21pYzY0X3JlYWQoJmV2ZW50LT5jaGlsZF90b3RhbF90aW1lX3J1bm5pbmcpOwoKCWJhcnJpZXIoKTsKCSsrdXNlcnBnLT5sb2NrOwoJcHJlZW1wdF9lbmFibGUoKTsKdW5sb2NrOgoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCnN0YXRpYyB1bnNpZ25lZCBsb25nIHBlcmZfZGF0YV9zaXplKHN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyKTsKCnN0YXRpYyB2b2lkCnBlcmZfYnVmZmVyX2luaXQoc3RydWN0IHBlcmZfYnVmZmVyICpidWZmZXIsIGxvbmcgd2F0ZXJtYXJrLCBpbnQgZmxhZ3MpCnsKCWxvbmcgbWF4X3NpemUgPSBwZXJmX2RhdGFfc2l6ZShidWZmZXIpOwoKCWlmICh3YXRlcm1hcmspCgkJYnVmZmVyLT53YXRlcm1hcmsgPSBtaW4obWF4X3NpemUsIHdhdGVybWFyayk7CgoJaWYgKCFidWZmZXItPndhdGVybWFyaykKCQlidWZmZXItPndhdGVybWFyayA9IG1heF9zaXplIC8gMjsKCglpZiAoZmxhZ3MgJiBQRVJGX0JVRkZFUl9XUklUQUJMRSkKCQlidWZmZXItPndyaXRhYmxlID0gMTsKCglhdG9taWNfc2V0KCZidWZmZXItPnJlZmNvdW50LCAxKTsKfQoKI2lmbmRlZiBDT05GSUdfUEVSRl9VU0VfVk1BTExPQwoKLyoKICogQmFjayBwZXJmX21tYXAoKSB3aXRoIHJlZ3VsYXIgR0ZQX0tFUk5FTC0wIHBhZ2VzLgogKi8KCnN0YXRpYyBzdHJ1Y3QgcGFnZSAqCnBlcmZfbW1hcF90b19wYWdlKHN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyLCB1bnNpZ25lZCBsb25nIHBnb2ZmKQp7CglpZiAocGdvZmYgPiBidWZmZXItPm5yX3BhZ2VzKQoJCXJldHVybiBOVUxMOwoKCWlmIChwZ29mZiA9PSAwKQoJCXJldHVybiB2aXJ0X3RvX3BhZ2UoYnVmZmVyLT51c2VyX3BhZ2UpOwoKCXJldHVybiB2aXJ0X3RvX3BhZ2UoYnVmZmVyLT5kYXRhX3BhZ2VzW3Bnb2ZmIC0gMV0pOwp9CgpzdGF0aWMgdm9pZCAqcGVyZl9tbWFwX2FsbG9jX3BhZ2UoaW50IGNwdSkKewoJc3RydWN0IHBhZ2UgKnBhZ2U7CglpbnQgbm9kZTsKCglub2RlID0gKGNwdSA9PSAtMSkgPyBjcHUgOiBjcHVfdG9fbm9kZShjcHUpOwoJcGFnZSA9IGFsbG9jX3BhZ2VzX25vZGUobm9kZSwgR0ZQX0tFUk5FTCB8IF9fR0ZQX1pFUk8sIDApOwoJaWYgKCFwYWdlKQoJCXJldHVybiBOVUxMOwoKCXJldHVybiBwYWdlX2FkZHJlc3MocGFnZSk7Cn0KCnN0YXRpYyBzdHJ1Y3QgcGVyZl9idWZmZXIgKgpwZXJmX2J1ZmZlcl9hbGxvYyhpbnQgbnJfcGFnZXMsIGxvbmcgd2F0ZXJtYXJrLCBpbnQgY3B1LCBpbnQgZmxhZ3MpCnsKCXN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyOwoJdW5zaWduZWQgbG9uZyBzaXplOwoJaW50IGk7CgoJc2l6ZSA9IHNpemVvZihzdHJ1Y3QgcGVyZl9idWZmZXIpOwoJc2l6ZSArPSBucl9wYWdlcyAqIHNpemVvZih2b2lkICopOwoKCWJ1ZmZlciA9IGt6YWxsb2Moc2l6ZSwgR0ZQX0tFUk5FTCk7CglpZiAoIWJ1ZmZlcikKCQlnb3RvIGZhaWw7CgoJYnVmZmVyLT51c2VyX3BhZ2UgPSBwZXJmX21tYXBfYWxsb2NfcGFnZShjcHUpOwoJaWYgKCFidWZmZXItPnVzZXJfcGFnZSkKCQlnb3RvIGZhaWxfdXNlcl9wYWdlOwoKCWZvciAoaSA9IDA7IGkgPCBucl9wYWdlczsgaSsrKSB7CgkJYnVmZmVyLT5kYXRhX3BhZ2VzW2ldID0gcGVyZl9tbWFwX2FsbG9jX3BhZ2UoY3B1KTsKCQlpZiAoIWJ1ZmZlci0+ZGF0YV9wYWdlc1tpXSkKCQkJZ290byBmYWlsX2RhdGFfcGFnZXM7Cgl9CgoJYnVmZmVyLT5ucl9wYWdlcyA9IG5yX3BhZ2VzOwoKCXBlcmZfYnVmZmVyX2luaXQoYnVmZmVyLCB3YXRlcm1hcmssIGZsYWdzKTsKCglyZXR1cm4gYnVmZmVyOwoKZmFpbF9kYXRhX3BhZ2VzOgoJZm9yIChpLS07IGkgPj0gMDsgaS0tKQoJCWZyZWVfcGFnZSgodW5zaWduZWQgbG9uZylidWZmZXItPmRhdGFfcGFnZXNbaV0pOwoKCWZyZWVfcGFnZSgodW5zaWduZWQgbG9uZylidWZmZXItPnVzZXJfcGFnZSk7CgpmYWlsX3VzZXJfcGFnZToKCWtmcmVlKGJ1ZmZlcik7CgpmYWlsOgoJcmV0dXJuIE5VTEw7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfbW1hcF9mcmVlX3BhZ2UodW5zaWduZWQgbG9uZyBhZGRyKQp7CglzdHJ1Y3QgcGFnZSAqcGFnZSA9IHZpcnRfdG9fcGFnZSgodm9pZCAqKWFkZHIpOwoKCXBhZ2UtPm1hcHBpbmcgPSBOVUxMOwoJX19mcmVlX3BhZ2UocGFnZSk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfYnVmZmVyX2ZyZWUoc3RydWN0IHBlcmZfYnVmZmVyICpidWZmZXIpCnsKCWludCBpOwoKCXBlcmZfbW1hcF9mcmVlX3BhZ2UoKHVuc2lnbmVkIGxvbmcpYnVmZmVyLT51c2VyX3BhZ2UpOwoJZm9yIChpID0gMDsgaSA8IGJ1ZmZlci0+bnJfcGFnZXM7IGkrKykKCQlwZXJmX21tYXBfZnJlZV9wYWdlKCh1bnNpZ25lZCBsb25nKWJ1ZmZlci0+ZGF0YV9wYWdlc1tpXSk7CglrZnJlZShidWZmZXIpOwp9CgpzdGF0aWMgaW5saW5lIGludCBwYWdlX29yZGVyKHN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyKQp7CglyZXR1cm4gMDsKfQoKI2Vsc2UKCi8qCiAqIEJhY2sgcGVyZl9tbWFwKCkgd2l0aCB2bWFsbG9jIG1lbW9yeS4KICoKICogUmVxdWlyZWQgZm9yIGFyY2hpdGVjdHVyZXMgdGhhdCBoYXZlIGQtY2FjaGUgYWxpYXNpbmcgaXNzdWVzLgogKi8KCnN0YXRpYyBpbmxpbmUgaW50IHBhZ2Vfb3JkZXIoc3RydWN0IHBlcmZfYnVmZmVyICpidWZmZXIpCnsKCXJldHVybiBidWZmZXItPnBhZ2Vfb3JkZXI7Cn0KCnN0YXRpYyBzdHJ1Y3QgcGFnZSAqCnBlcmZfbW1hcF90b19wYWdlKHN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyLCB1bnNpZ25lZCBsb25nIHBnb2ZmKQp7CglpZiAocGdvZmYgPiAoMVVMIDw8IHBhZ2Vfb3JkZXIoYnVmZmVyKSkpCgkJcmV0dXJuIE5VTEw7CgoJcmV0dXJuIHZtYWxsb2NfdG9fcGFnZSgodm9pZCAqKWJ1ZmZlci0+dXNlcl9wYWdlICsgcGdvZmYgKiBQQUdFX1NJWkUpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX21tYXBfdW5tYXJrX3BhZ2Uodm9pZCAqYWRkcikKewoJc3RydWN0IHBhZ2UgKnBhZ2UgPSB2bWFsbG9jX3RvX3BhZ2UoYWRkcik7CgoJcGFnZS0+bWFwcGluZyA9IE5VTEw7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfYnVmZmVyX2ZyZWVfd29yayhzdHJ1Y3Qgd29ya19zdHJ1Y3QgKndvcmspCnsKCXN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyOwoJdm9pZCAqYmFzZTsKCWludCBpLCBucjsKCglidWZmZXIgPSBjb250YWluZXJfb2Yod29yaywgc3RydWN0IHBlcmZfYnVmZmVyLCB3b3JrKTsKCW5yID0gMSA8PCBwYWdlX29yZGVyKGJ1ZmZlcik7CgoJYmFzZSA9IGJ1ZmZlci0+dXNlcl9wYWdlOwoJZm9yIChpID0gMDsgaSA8IG5yICsgMTsgaSsrKQoJCXBlcmZfbW1hcF91bm1hcmtfcGFnZShiYXNlICsgKGkgKiBQQUdFX1NJWkUpKTsKCgl2ZnJlZShiYXNlKTsKCWtmcmVlKGJ1ZmZlcik7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfYnVmZmVyX2ZyZWUoc3RydWN0IHBlcmZfYnVmZmVyICpidWZmZXIpCnsKCXNjaGVkdWxlX3dvcmsoJmJ1ZmZlci0+d29yayk7Cn0KCnN0YXRpYyBzdHJ1Y3QgcGVyZl9idWZmZXIgKgpwZXJmX2J1ZmZlcl9hbGxvYyhpbnQgbnJfcGFnZXMsIGxvbmcgd2F0ZXJtYXJrLCBpbnQgY3B1LCBpbnQgZmxhZ3MpCnsKCXN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyOwoJdW5zaWduZWQgbG9uZyBzaXplOwoJdm9pZCAqYWxsX2J1ZjsKCglzaXplID0gc2l6ZW9mKHN0cnVjdCBwZXJmX2J1ZmZlcik7CglzaXplICs9IHNpemVvZih2b2lkICopOwoKCWJ1ZmZlciA9IGt6YWxsb2Moc2l6ZSwgR0ZQX0tFUk5FTCk7CglpZiAoIWJ1ZmZlcikKCQlnb3RvIGZhaWw7CgoJSU5JVF9XT1JLKCZidWZmZXItPndvcmssIHBlcmZfYnVmZmVyX2ZyZWVfd29yayk7CgoJYWxsX2J1ZiA9IHZtYWxsb2NfdXNlcigobnJfcGFnZXMgKyAxKSAqIFBBR0VfU0laRSk7CglpZiAoIWFsbF9idWYpCgkJZ290byBmYWlsX2FsbF9idWY7CgoJYnVmZmVyLT51c2VyX3BhZ2UgPSBhbGxfYnVmOwoJYnVmZmVyLT5kYXRhX3BhZ2VzWzBdID0gYWxsX2J1ZiArIFBBR0VfU0laRTsKCWJ1ZmZlci0+cGFnZV9vcmRlciA9IGlsb2cyKG5yX3BhZ2VzKTsKCWJ1ZmZlci0+bnJfcGFnZXMgPSAxOwoKCXBlcmZfYnVmZmVyX2luaXQoYnVmZmVyLCB3YXRlcm1hcmssIGZsYWdzKTsKCglyZXR1cm4gYnVmZmVyOwoKZmFpbF9hbGxfYnVmOgoJa2ZyZWUoYnVmZmVyKTsKCmZhaWw6CglyZXR1cm4gTlVMTDsKfQoKI2VuZGlmCgpzdGF0aWMgdW5zaWduZWQgbG9uZyBwZXJmX2RhdGFfc2l6ZShzdHJ1Y3QgcGVyZl9idWZmZXIgKmJ1ZmZlcikKewoJcmV0dXJuIGJ1ZmZlci0+bnJfcGFnZXMgPDwgKFBBR0VfU0hJRlQgKyBwYWdlX29yZGVyKGJ1ZmZlcikpOwp9CgpzdGF0aWMgaW50IHBlcmZfbW1hcF9mYXVsdChzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYSwgc3RydWN0IHZtX2ZhdWx0ICp2bWYpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IHZtYS0+dm1fZmlsZS0+cHJpdmF0ZV9kYXRhOwoJc3RydWN0IHBlcmZfYnVmZmVyICpidWZmZXI7CglpbnQgcmV0ID0gVk1fRkFVTFRfU0lHQlVTOwoKCWlmICh2bWYtPmZsYWdzICYgRkFVTFRfRkxBR19NS1dSSVRFKSB7CgkJaWYgKHZtZi0+cGdvZmYgPT0gMCkKCQkJcmV0ID0gMDsKCQlyZXR1cm4gcmV0OwoJfQoKCXJjdV9yZWFkX2xvY2soKTsKCWJ1ZmZlciA9IHJjdV9kZXJlZmVyZW5jZShldmVudC0+YnVmZmVyKTsKCWlmICghYnVmZmVyKQoJCWdvdG8gdW5sb2NrOwoKCWlmICh2bWYtPnBnb2ZmICYmICh2bWYtPmZsYWdzICYgRkFVTFRfRkxBR19XUklURSkpCgkJZ290byB1bmxvY2s7CgoJdm1mLT5wYWdlID0gcGVyZl9tbWFwX3RvX3BhZ2UoYnVmZmVyLCB2bWYtPnBnb2ZmKTsKCWlmICghdm1mLT5wYWdlKQoJCWdvdG8gdW5sb2NrOwoKCWdldF9wYWdlKHZtZi0+cGFnZSk7Cgl2bWYtPnBhZ2UtPm1hcHBpbmcgPSB2bWEtPnZtX2ZpbGUtPmZfbWFwcGluZzsKCXZtZi0+cGFnZS0+aW5kZXggICA9IHZtZi0+cGdvZmY7CgoJcmV0ID0gMDsKdW5sb2NrOgoJcmN1X3JlYWRfdW5sb2NrKCk7CgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIHZvaWQgcGVyZl9idWZmZXJfZnJlZV9yY3Uoc3RydWN0IHJjdV9oZWFkICpyY3VfaGVhZCkKewoJc3RydWN0IHBlcmZfYnVmZmVyICpidWZmZXI7CgoJYnVmZmVyID0gY29udGFpbmVyX29mKHJjdV9oZWFkLCBzdHJ1Y3QgcGVyZl9idWZmZXIsIHJjdV9oZWFkKTsKCXBlcmZfYnVmZmVyX2ZyZWUoYnVmZmVyKTsKfQoKc3RhdGljIHN0cnVjdCBwZXJmX2J1ZmZlciAqcGVyZl9idWZmZXJfZ2V0KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJc3RydWN0IHBlcmZfYnVmZmVyICpidWZmZXI7CgoJcmN1X3JlYWRfbG9jaygpOwoJYnVmZmVyID0gcmN1X2RlcmVmZXJlbmNlKGV2ZW50LT5idWZmZXIpOwoJaWYgKGJ1ZmZlcikgewoJCWlmICghYXRvbWljX2luY19ub3RfemVybygmYnVmZmVyLT5yZWZjb3VudCkpCgkJCWJ1ZmZlciA9IE5VTEw7Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKCglyZXR1cm4gYnVmZmVyOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2J1ZmZlcl9wdXQoc3RydWN0IHBlcmZfYnVmZmVyICpidWZmZXIpCnsKCWlmICghYXRvbWljX2RlY19hbmRfdGVzdCgmYnVmZmVyLT5yZWZjb3VudCkpCgkJcmV0dXJuOwoKCWNhbGxfcmN1KCZidWZmZXItPnJjdV9oZWFkLCBwZXJmX2J1ZmZlcl9mcmVlX3JjdSk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfbW1hcF9vcGVuKHN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqdm1hKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQgPSB2bWEtPnZtX2ZpbGUtPnByaXZhdGVfZGF0YTsKCglhdG9taWNfaW5jKCZldmVudC0+bW1hcF9jb3VudCk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfbW1hcF9jbG9zZShzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYSkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50ID0gdm1hLT52bV9maWxlLT5wcml2YXRlX2RhdGE7CgoJaWYgKGF0b21pY19kZWNfYW5kX211dGV4X2xvY2soJmV2ZW50LT5tbWFwX2NvdW50LCAmZXZlbnQtPm1tYXBfbXV0ZXgpKSB7CgkJdW5zaWduZWQgbG9uZyBzaXplID0gcGVyZl9kYXRhX3NpemUoZXZlbnQtPmJ1ZmZlcik7CgkJc3RydWN0IHVzZXJfc3RydWN0ICp1c2VyID0gZXZlbnQtPm1tYXBfdXNlcjsKCQlzdHJ1Y3QgcGVyZl9idWZmZXIgKmJ1ZmZlciA9IGV2ZW50LT5idWZmZXI7CgoJCWF0b21pY19sb25nX3N1Yigoc2l6ZSA+PiBQQUdFX1NISUZUKSArIDEsICZ1c2VyLT5sb2NrZWRfdm0pOwoJCXZtYS0+dm1fbW0tPmxvY2tlZF92bSAtPSBldmVudC0+bW1hcF9sb2NrZWQ7CgkJcmN1X2Fzc2lnbl9wb2ludGVyKGV2ZW50LT5idWZmZXIsIE5VTEwpOwoJCW11dGV4X3VubG9jaygmZXZlbnQtPm1tYXBfbXV0ZXgpOwoKCQlwZXJmX2J1ZmZlcl9wdXQoYnVmZmVyKTsKCQlmcmVlX3VpZCh1c2VyKTsKCX0KfQoKc3RhdGljIGNvbnN0IHN0cnVjdCB2bV9vcGVyYXRpb25zX3N0cnVjdCBwZXJmX21tYXBfdm1vcHMgPSB7Cgkub3BlbgkJPSBwZXJmX21tYXBfb3BlbiwKCS5jbG9zZQkJPSBwZXJmX21tYXBfY2xvc2UsCgkuZmF1bHQJCT0gcGVyZl9tbWFwX2ZhdWx0LAoJLnBhZ2VfbWt3cml0ZQk9IHBlcmZfbW1hcF9mYXVsdCwKfTsKCnN0YXRpYyBpbnQgcGVyZl9tbWFwKHN0cnVjdCBmaWxlICpmaWxlLCBzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYSkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50ID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwoJdW5zaWduZWQgbG9uZyB1c2VyX2xvY2tlZCwgdXNlcl9sb2NrX2xpbWl0OwoJc3RydWN0IHVzZXJfc3RydWN0ICp1c2VyID0gY3VycmVudF91c2VyKCk7Cgl1bnNpZ25lZCBsb25nIGxvY2tlZCwgbG9ja19saW1pdDsKCXN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyOwoJdW5zaWduZWQgbG9uZyB2bWFfc2l6ZTsKCXVuc2lnbmVkIGxvbmcgbnJfcGFnZXM7Cglsb25nIHVzZXJfZXh0cmEsIGV4dHJhOwoJaW50IHJldCA9IDAsIGZsYWdzID0gMDsKCgkvKgoJICogRG9uJ3QgYWxsb3cgbW1hcCgpIG9mIGluaGVyaXRlZCBwZXItdGFzayBjb3VudGVycy4gVGhpcyB3b3VsZAoJICogY3JlYXRlIGEgcGVyZm9ybWFuY2UgaXNzdWUgZHVlIHRvIGFsbCBjaGlsZHJlbiB3cml0aW5nIHRvIHRoZQoJICogc2FtZSBidWZmZXIuCgkgKi8KCWlmIChldmVudC0+Y3B1ID09IC0xICYmIGV2ZW50LT5hdHRyLmluaGVyaXQpCgkJcmV0dXJuIC1FSU5WQUw7CgoJaWYgKCEodm1hLT52bV9mbGFncyAmIFZNX1NIQVJFRCkpCgkJcmV0dXJuIC1FSU5WQUw7CgoJdm1hX3NpemUgPSB2bWEtPnZtX2VuZCAtIHZtYS0+dm1fc3RhcnQ7Cglucl9wYWdlcyA9ICh2bWFfc2l6ZSAvIFBBR0VfU0laRSkgLSAxOwoKCS8qCgkgKiBJZiB3ZSBoYXZlIGJ1ZmZlciBwYWdlcyBlbnN1cmUgdGhleSdyZSBhIHBvd2VyLW9mLXR3byBudW1iZXIsIHNvIHdlCgkgKiBjYW4gZG8gYml0bWFza3MgaW5zdGVhZCBvZiBtb2R1bG8uCgkgKi8KCWlmIChucl9wYWdlcyAhPSAwICYmICFpc19wb3dlcl9vZl8yKG5yX3BhZ2VzKSkKCQlyZXR1cm4gLUVJTlZBTDsKCglpZiAodm1hX3NpemUgIT0gUEFHRV9TSVpFICogKDEgKyBucl9wYWdlcykpCgkJcmV0dXJuIC1FSU5WQUw7CgoJaWYgKHZtYS0+dm1fcGdvZmYgIT0gMCkKCQlyZXR1cm4gLUVJTlZBTDsKCglXQVJOX09OX09OQ0UoZXZlbnQtPmN0eC0+cGFyZW50X2N0eCk7CgltdXRleF9sb2NrKCZldmVudC0+bW1hcF9tdXRleCk7CglpZiAoZXZlbnQtPmJ1ZmZlcikgewoJCWlmIChldmVudC0+YnVmZmVyLT5ucl9wYWdlcyA9PSBucl9wYWdlcykKCQkJYXRvbWljX2luYygmZXZlbnQtPmJ1ZmZlci0+cmVmY291bnQpOwoJCWVsc2UKCQkJcmV0ID0gLUVJTlZBTDsKCQlnb3RvIHVubG9jazsKCX0KCgl1c2VyX2V4dHJhID0gbnJfcGFnZXMgKyAxOwoJdXNlcl9sb2NrX2xpbWl0ID0gc3lzY3RsX3BlcmZfZXZlbnRfbWxvY2sgPj4gKFBBR0VfU0hJRlQgLSAxMCk7CgoJLyoKCSAqIEluY3JlYXNlIHRoZSBsaW1pdCBsaW5lYXJseSB3aXRoIG1vcmUgQ1BVczoKCSAqLwoJdXNlcl9sb2NrX2xpbWl0ICo9IG51bV9vbmxpbmVfY3B1cygpOwoKCXVzZXJfbG9ja2VkID0gYXRvbWljX2xvbmdfcmVhZCgmdXNlci0+bG9ja2VkX3ZtKSArIHVzZXJfZXh0cmE7CgoJZXh0cmEgPSAwOwoJaWYgKHVzZXJfbG9ja2VkID4gdXNlcl9sb2NrX2xpbWl0KQoJCWV4dHJhID0gdXNlcl9sb2NrZWQgLSB1c2VyX2xvY2tfbGltaXQ7CgoJbG9ja19saW1pdCA9IHJsaW1pdChSTElNSVRfTUVNTE9DSyk7Cglsb2NrX2xpbWl0ID4+PSBQQUdFX1NISUZUOwoJbG9ja2VkID0gdm1hLT52bV9tbS0+bG9ja2VkX3ZtICsgZXh0cmE7CgoJaWYgKChsb2NrZWQgPiBsb2NrX2xpbWl0KSAmJiBwZXJmX3BhcmFub2lkX3RyYWNlcG9pbnRfcmF3KCkgJiYKCQkhY2FwYWJsZShDQVBfSVBDX0xPQ0spKSB7CgkJcmV0ID0gLUVQRVJNOwoJCWdvdG8gdW5sb2NrOwoJfQoKCVdBUk5fT04oZXZlbnQtPmJ1ZmZlcik7CgoJaWYgKHZtYS0+dm1fZmxhZ3MgJiBWTV9XUklURSkKCQlmbGFncyB8PSBQRVJGX0JVRkZFUl9XUklUQUJMRTsKCglidWZmZXIgPSBwZXJmX2J1ZmZlcl9hbGxvYyhucl9wYWdlcywgZXZlbnQtPmF0dHIud2FrZXVwX3dhdGVybWFyaywKCQkJCSAgIGV2ZW50LT5jcHUsIGZsYWdzKTsKCWlmICghYnVmZmVyKSB7CgkJcmV0ID0gLUVOT01FTTsKCQlnb3RvIHVubG9jazsKCX0KCXJjdV9hc3NpZ25fcG9pbnRlcihldmVudC0+YnVmZmVyLCBidWZmZXIpOwoKCWF0b21pY19sb25nX2FkZCh1c2VyX2V4dHJhLCAmdXNlci0+bG9ja2VkX3ZtKTsKCWV2ZW50LT5tbWFwX2xvY2tlZCA9IGV4dHJhOwoJZXZlbnQtPm1tYXBfdXNlciA9IGdldF9jdXJyZW50X3VzZXIoKTsKCXZtYS0+dm1fbW0tPmxvY2tlZF92bSArPSBldmVudC0+bW1hcF9sb2NrZWQ7Cgp1bmxvY2s6CglpZiAoIXJldCkKCQlhdG9taWNfaW5jKCZldmVudC0+bW1hcF9jb3VudCk7CgltdXRleF91bmxvY2soJmV2ZW50LT5tbWFwX211dGV4KTsKCgl2bWEtPnZtX2ZsYWdzIHw9IFZNX1JFU0VSVkVEOwoJdm1hLT52bV9vcHMgPSAmcGVyZl9tbWFwX3Ztb3BzOwoKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBpbnQgcGVyZl9mYXN5bmMoaW50IGZkLCBzdHJ1Y3QgZmlsZSAqZmlscCwgaW50IG9uKQp7CglzdHJ1Y3QgaW5vZGUgKmlub2RlID0gZmlscC0+Zl9wYXRoLmRlbnRyeS0+ZF9pbm9kZTsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IGZpbHAtPnByaXZhdGVfZGF0YTsKCWludCByZXR2YWw7CgoJbXV0ZXhfbG9jaygmaW5vZGUtPmlfbXV0ZXgpOwoJcmV0dmFsID0gZmFzeW5jX2hlbHBlcihmZCwgZmlscCwgb24sICZldmVudC0+ZmFzeW5jKTsKCW11dGV4X3VubG9jaygmaW5vZGUtPmlfbXV0ZXgpOwoKCWlmIChyZXR2YWwgPCAwKQoJCXJldHVybiByZXR2YWw7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBjb25zdCBzdHJ1Y3QgZmlsZV9vcGVyYXRpb25zIHBlcmZfZm9wcyA9IHsKCS5sbHNlZWsJCQk9IG5vX2xsc2VlaywKCS5yZWxlYXNlCQk9IHBlcmZfcmVsZWFzZSwKCS5yZWFkCQkJPSBwZXJmX3JlYWQsCgkucG9sbAkJCT0gcGVyZl9wb2xsLAoJLnVubG9ja2VkX2lvY3RsCQk9IHBlcmZfaW9jdGwsCgkuY29tcGF0X2lvY3RsCQk9IHBlcmZfaW9jdGwsCgkubW1hcAkJCT0gcGVyZl9tbWFwLAoJLmZhc3luYwkJCT0gcGVyZl9mYXN5bmMsCn07CgovKgogKiBQZXJmIGV2ZW50IHdha2V1cAogKgogKiBJZiB0aGVyZSdzIGRhdGEsIGVuc3VyZSB3ZSBzZXQgdGhlIHBvbGwoKSBzdGF0ZSBhbmQgcHVibGlzaCBldmVyeXRoaW5nCiAqIHRvIHVzZXItc3BhY2UgYmVmb3JlIHdha2luZyBldmVyeWJvZHkgdXAuCiAqLwoKdm9pZCBwZXJmX2V2ZW50X3dha2V1cChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXdha2VfdXBfYWxsKCZldmVudC0+d2FpdHEpOwoKCWlmIChldmVudC0+cGVuZGluZ19raWxsKSB7CgkJa2lsbF9mYXN5bmMoJmV2ZW50LT5mYXN5bmMsIFNJR0lPLCBldmVudC0+cGVuZGluZ19raWxsKTsKCQlldmVudC0+cGVuZGluZ19raWxsID0gMDsKCX0KfQoKc3RhdGljIHZvaWQgcGVyZl9wZW5kaW5nX2V2ZW50KHN0cnVjdCBpcnFfd29yayAqZW50cnkpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IGNvbnRhaW5lcl9vZihlbnRyeSwKCQkJc3RydWN0IHBlcmZfZXZlbnQsIHBlbmRpbmcpOwoKCWlmIChldmVudC0+cGVuZGluZ19kaXNhYmxlKSB7CgkJZXZlbnQtPnBlbmRpbmdfZGlzYWJsZSA9IDA7CgkJX19wZXJmX2V2ZW50X2Rpc2FibGUoZXZlbnQpOwoJfQoKCWlmIChldmVudC0+cGVuZGluZ193YWtldXApIHsKCQlldmVudC0+cGVuZGluZ193YWtldXAgPSAwOwoJCXBlcmZfZXZlbnRfd2FrZXVwKGV2ZW50KTsKCX0KfQoKLyoKICogV2UgYXNzdW1lIHRoZXJlIGlzIG9ubHkgS1ZNIHN1cHBvcnRpbmcgdGhlIGNhbGxiYWNrcy4KICogTGF0ZXIgb24sIHdlIG1pZ2h0IGNoYW5nZSBpdCB0byBhIGxpc3QgaWYgdGhlcmUgaXMKICogYW5vdGhlciB2aXJ0dWFsaXphdGlvbiBpbXBsZW1lbnRhdGlvbiBzdXBwb3J0aW5nIHRoZSBjYWxsYmFja3MuCiAqLwpzdHJ1Y3QgcGVyZl9ndWVzdF9pbmZvX2NhbGxiYWNrcyAqcGVyZl9ndWVzdF9jYnM7CgppbnQgcGVyZl9yZWdpc3Rlcl9ndWVzdF9pbmZvX2NhbGxiYWNrcyhzdHJ1Y3QgcGVyZl9ndWVzdF9pbmZvX2NhbGxiYWNrcyAqY2JzKQp7CglwZXJmX2d1ZXN0X2NicyA9IGNiczsKCXJldHVybiAwOwp9CkVYUE9SVF9TWU1CT0xfR1BMKHBlcmZfcmVnaXN0ZXJfZ3Vlc3RfaW5mb19jYWxsYmFja3MpOwoKaW50IHBlcmZfdW5yZWdpc3Rlcl9ndWVzdF9pbmZvX2NhbGxiYWNrcyhzdHJ1Y3QgcGVyZl9ndWVzdF9pbmZvX2NhbGxiYWNrcyAqY2JzKQp7CglwZXJmX2d1ZXN0X2NicyA9IE5VTEw7CglyZXR1cm4gMDsKfQpFWFBPUlRfU1lNQk9MX0dQTChwZXJmX3VucmVnaXN0ZXJfZ3Vlc3RfaW5mb19jYWxsYmFja3MpOwoKLyoKICogT3V0cHV0CiAqLwpzdGF0aWMgYm9vbCBwZXJmX291dHB1dF9zcGFjZShzdHJ1Y3QgcGVyZl9idWZmZXIgKmJ1ZmZlciwgdW5zaWduZWQgbG9uZyB0YWlsLAoJCQkgICAgICB1bnNpZ25lZCBsb25nIG9mZnNldCwgdW5zaWduZWQgbG9uZyBoZWFkKQp7Cgl1bnNpZ25lZCBsb25nIG1hc2s7CgoJaWYgKCFidWZmZXItPndyaXRhYmxlKQoJCXJldHVybiB0cnVlOwoKCW1hc2sgPSBwZXJmX2RhdGFfc2l6ZShidWZmZXIpIC0gMTsKCglvZmZzZXQgPSAob2Zmc2V0IC0gdGFpbCkgJiBtYXNrOwoJaGVhZCAgID0gKGhlYWQgICAtIHRhaWwpICYgbWFzazsKCglpZiAoKGludCkoaGVhZCAtIG9mZnNldCkgPCAwKQoJCXJldHVybiBmYWxzZTsKCglyZXR1cm4gdHJ1ZTsKfQoKc3RhdGljIHZvaWQgcGVyZl9vdXRwdXRfd2FrZXVwKHN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgKmhhbmRsZSkKewoJYXRvbWljX3NldCgmaGFuZGxlLT5idWZmZXItPnBvbGwsIFBPTExfSU4pOwoKCWlmIChoYW5kbGUtPm5taSkgewoJCWhhbmRsZS0+ZXZlbnQtPnBlbmRpbmdfd2FrZXVwID0gMTsKCQlpcnFfd29ya19xdWV1ZSgmaGFuZGxlLT5ldmVudC0+cGVuZGluZyk7Cgl9IGVsc2UKCQlwZXJmX2V2ZW50X3dha2V1cChoYW5kbGUtPmV2ZW50KTsKfQoKLyoKICogV2UgbmVlZCB0byBlbnN1cmUgYSBsYXRlciBldmVudF9pZCBkb2Vzbid0IHB1Ymxpc2ggYSBoZWFkIHdoZW4gYSBmb3JtZXIKICogZXZlbnQgaXNuJ3QgZG9uZSB3cml0aW5nLiBIb3dldmVyIHNpbmNlIHdlIG5lZWQgdG8gZGVhbCB3aXRoIE5NSXMgd2UKICogY2Fubm90IGZ1bGx5IHNlcmlhbGl6ZSB0aGluZ3MuCiAqCiAqIFdlIG9ubHkgcHVibGlzaCB0aGUgaGVhZCAoYW5kIGdlbmVyYXRlIGEgd2FrZXVwKSB3aGVuIHRoZSBvdXRlci1tb3N0CiAqIGV2ZW50IGNvbXBsZXRlcy4KICovCnN0YXRpYyB2b2lkIHBlcmZfb3V0cHV0X2dldF9oYW5kbGUoc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSAqaGFuZGxlKQp7CglzdHJ1Y3QgcGVyZl9idWZmZXIgKmJ1ZmZlciA9IGhhbmRsZS0+YnVmZmVyOwoKCXByZWVtcHRfZGlzYWJsZSgpOwoJbG9jYWxfaW5jKCZidWZmZXItPm5lc3QpOwoJaGFuZGxlLT53YWtldXAgPSBsb2NhbF9yZWFkKCZidWZmZXItPndha2V1cCk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfb3V0cHV0X3B1dF9oYW5kbGUoc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSAqaGFuZGxlKQp7CglzdHJ1Y3QgcGVyZl9idWZmZXIgKmJ1ZmZlciA9IGhhbmRsZS0+YnVmZmVyOwoJdW5zaWduZWQgbG9uZyBoZWFkOwoKYWdhaW46CgloZWFkID0gbG9jYWxfcmVhZCgmYnVmZmVyLT5oZWFkKTsKCgkvKgoJICogSVJRL05NSSBjYW4gaGFwcGVuIGhlcmUsIHdoaWNoIG1lYW5zIHdlIGNhbiBtaXNzIGEgaGVhZCB1cGRhdGUuCgkgKi8KCglpZiAoIWxvY2FsX2RlY19hbmRfdGVzdCgmYnVmZmVyLT5uZXN0KSkKCQlnb3RvIG91dDsKCgkvKgoJICogUHVibGlzaCB0aGUga25vd24gZ29vZCBoZWFkLiBSZWx5IG9uIHRoZSBmdWxsIGJhcnJpZXIgaW1wbGllZAoJICogYnkgYXRvbWljX2RlY19hbmRfdGVzdCgpIG9yZGVyIHRoZSBidWZmZXItPmhlYWQgcmVhZCBhbmQgdGhpcwoJICogd3JpdGUuCgkgKi8KCWJ1ZmZlci0+dXNlcl9wYWdlLT5kYXRhX2hlYWQgPSBoZWFkOwoKCS8qCgkgKiBOb3cgY2hlY2sgaWYgd2UgbWlzc2VkIGFuIHVwZGF0ZSwgcmVseSBvbiB0aGUgKGNvbXBpbGVyKQoJICogYmFycmllciBpbiBhdG9taWNfZGVjX2FuZF90ZXN0KCkgdG8gcmUtcmVhZCBidWZmZXItPmhlYWQuCgkgKi8KCWlmICh1bmxpa2VseShoZWFkICE9IGxvY2FsX3JlYWQoJmJ1ZmZlci0+aGVhZCkpKSB7CgkJbG9jYWxfaW5jKCZidWZmZXItPm5lc3QpOwoJCWdvdG8gYWdhaW47Cgl9CgoJaWYgKGhhbmRsZS0+d2FrZXVwICE9IGxvY2FsX3JlYWQoJmJ1ZmZlci0+d2FrZXVwKSkKCQlwZXJmX291dHB1dF93YWtldXAoaGFuZGxlKTsKCm91dDoKCXByZWVtcHRfZW5hYmxlKCk7Cn0KCl9fYWx3YXlzX2lubGluZSB2b2lkIHBlcmZfb3V0cHV0X2NvcHkoc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSAqaGFuZGxlLAoJCSAgICAgIGNvbnN0IHZvaWQgKmJ1ZiwgdW5zaWduZWQgaW50IGxlbikKewoJZG8gewoJCXVuc2lnbmVkIGxvbmcgc2l6ZSA9IG1pbl90KHVuc2lnbmVkIGxvbmcsIGhhbmRsZS0+c2l6ZSwgbGVuKTsKCgkJbWVtY3B5KGhhbmRsZS0+YWRkciwgYnVmLCBzaXplKTsKCgkJbGVuIC09IHNpemU7CgkJaGFuZGxlLT5hZGRyICs9IHNpemU7CgkJYnVmICs9IHNpemU7CgkJaGFuZGxlLT5zaXplIC09IHNpemU7CgkJaWYgKCFoYW5kbGUtPnNpemUpIHsKCQkJc3RydWN0IHBlcmZfYnVmZmVyICpidWZmZXIgPSBoYW5kbGUtPmJ1ZmZlcjsKCgkJCWhhbmRsZS0+cGFnZSsrOwoJCQloYW5kbGUtPnBhZ2UgJj0gYnVmZmVyLT5ucl9wYWdlcyAtIDE7CgkJCWhhbmRsZS0+YWRkciA9IGJ1ZmZlci0+ZGF0YV9wYWdlc1toYW5kbGUtPnBhZ2VdOwoJCQloYW5kbGUtPnNpemUgPSBQQUdFX1NJWkUgPDwgcGFnZV9vcmRlcihidWZmZXIpOwoJCX0KCX0gd2hpbGUgKGxlbik7Cn0KCnN0YXRpYyB2b2lkIF9fcGVyZl9ldmVudF9oZWFkZXJfX2luaXRfaWQoc3RydWN0IHBlcmZfZXZlbnRfaGVhZGVyICpoZWFkZXIsCgkJCQkJIHN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhICpkYXRhLAoJCQkJCSBzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXU2NCBzYW1wbGVfdHlwZSA9IGV2ZW50LT5hdHRyLnNhbXBsZV90eXBlOwoKCWRhdGEtPnR5cGUgPSBzYW1wbGVfdHlwZTsKCWhlYWRlci0+c2l6ZSArPSBldmVudC0+aWRfaGVhZGVyX3NpemU7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfVElEKSB7CgkJLyogbmFtZXNwYWNlIGlzc3VlcyAqLwoJCWRhdGEtPnRpZF9lbnRyeS5waWQgPSBwZXJmX2V2ZW50X3BpZChldmVudCwgY3VycmVudCk7CgkJZGF0YS0+dGlkX2VudHJ5LnRpZCA9IHBlcmZfZXZlbnRfdGlkKGV2ZW50LCBjdXJyZW50KTsKCX0KCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9USU1FKQoJCWRhdGEtPnRpbWUgPSBwZXJmX2Nsb2NrKCk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfSUQpCgkJZGF0YS0+aWQgPSBwcmltYXJ5X2V2ZW50X2lkKGV2ZW50KTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9TVFJFQU1fSUQpCgkJZGF0YS0+c3RyZWFtX2lkID0gZXZlbnQtPmlkOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0NQVSkgewoJCWRhdGEtPmNwdV9lbnRyeS5jcHUJID0gcmF3X3NtcF9wcm9jZXNzb3JfaWQoKTsKCQlkYXRhLT5jcHVfZW50cnkucmVzZXJ2ZWQgPSAwOwoJfQp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X2hlYWRlcl9faW5pdF9pZChzdHJ1Y3QgcGVyZl9ldmVudF9oZWFkZXIgKmhlYWRlciwKCQkJCSAgICAgICBzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YSwKCQkJCSAgICAgICBzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCWlmIChldmVudC0+YXR0ci5zYW1wbGVfaWRfYWxsKQoJCV9fcGVyZl9ldmVudF9oZWFkZXJfX2luaXRfaWQoaGVhZGVyLCBkYXRhLCBldmVudCk7Cn0KCnN0YXRpYyB2b2lkIF9fcGVyZl9ldmVudF9fb3V0cHV0X2lkX3NhbXBsZShzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlICpoYW5kbGUsCgkJCQkJICAgc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgKmRhdGEpCnsKCXU2NCBzYW1wbGVfdHlwZSA9IGRhdGEtPnR5cGU7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfVElEKQoJCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsIGRhdGEtPnRpZF9lbnRyeSk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfVElNRSkKCQlwZXJmX291dHB1dF9wdXQoaGFuZGxlLCBkYXRhLT50aW1lKTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9JRCkKCQlwZXJmX291dHB1dF9wdXQoaGFuZGxlLCBkYXRhLT5pZCk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfU1RSRUFNX0lEKQoJCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsIGRhdGEtPnN0cmVhbV9pZCk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfQ1BVKQoJCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsIGRhdGEtPmNwdV9lbnRyeSk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfX291dHB1dF9pZF9zYW1wbGUoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJCSBzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlICpoYW5kbGUsCgkJCQkJIHN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhICpzYW1wbGUpCnsKCWlmIChldmVudC0+YXR0ci5zYW1wbGVfaWRfYWxsKQoJCV9fcGVyZl9ldmVudF9fb3V0cHV0X2lkX3NhbXBsZShoYW5kbGUsIHNhbXBsZSk7Cn0KCmludCBwZXJmX291dHB1dF9iZWdpbihzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlICpoYW5kbGUsCgkJICAgICAgc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCB1bnNpZ25lZCBpbnQgc2l6ZSwKCQkgICAgICBpbnQgbm1pLCBpbnQgc2FtcGxlKQp7CglzdHJ1Y3QgcGVyZl9idWZmZXIgKmJ1ZmZlcjsKCXVuc2lnbmVkIGxvbmcgdGFpbCwgb2Zmc2V0LCBoZWFkOwoJaW50IGhhdmVfbG9zdDsKCXN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhIHNhbXBsZV9kYXRhOwoJc3RydWN0IHsKCQlzdHJ1Y3QgcGVyZl9ldmVudF9oZWFkZXIgaGVhZGVyOwoJCXU2NAkJCSBpZDsKCQl1NjQJCQkgbG9zdDsKCX0gbG9zdF9ldmVudDsKCglyY3VfcmVhZF9sb2NrKCk7CgkvKgoJICogRm9yIGluaGVyaXRlZCBldmVudHMgd2Ugc2VuZCBhbGwgdGhlIG91dHB1dCB0b3dhcmRzIHRoZSBwYXJlbnQuCgkgKi8KCWlmIChldmVudC0+cGFyZW50KQoJCWV2ZW50ID0gZXZlbnQtPnBhcmVudDsKCglidWZmZXIgPSByY3VfZGVyZWZlcmVuY2UoZXZlbnQtPmJ1ZmZlcik7CglpZiAoIWJ1ZmZlcikKCQlnb3RvIG91dDsKCgloYW5kbGUtPmJ1ZmZlcgk9IGJ1ZmZlcjsKCWhhbmRsZS0+ZXZlbnQJPSBldmVudDsKCWhhbmRsZS0+bm1pCT0gbm1pOwoJaGFuZGxlLT5zYW1wbGUJPSBzYW1wbGU7CgoJaWYgKCFidWZmZXItPm5yX3BhZ2VzKQoJCWdvdG8gb3V0OwoKCWhhdmVfbG9zdCA9IGxvY2FsX3JlYWQoJmJ1ZmZlci0+bG9zdCk7CglpZiAoaGF2ZV9sb3N0KSB7CgkJbG9zdF9ldmVudC5oZWFkZXIuc2l6ZSA9IHNpemVvZihsb3N0X2V2ZW50KTsKCQlwZXJmX2V2ZW50X2hlYWRlcl9faW5pdF9pZCgmbG9zdF9ldmVudC5oZWFkZXIsICZzYW1wbGVfZGF0YSwKCQkJCQkgICBldmVudCk7CgkJc2l6ZSArPSBsb3N0X2V2ZW50LmhlYWRlci5zaXplOwoJfQoKCXBlcmZfb3V0cHV0X2dldF9oYW5kbGUoaGFuZGxlKTsKCglkbyB7CgkJLyoKCQkgKiBVc2Vyc3BhY2UgY291bGQgY2hvb3NlIHRvIGlzc3VlIGEgbWIoKSBiZWZvcmUgdXBkYXRpbmcgdGhlCgkJICogdGFpbCBwb2ludGVyLiBTbyB0aGF0IGFsbCByZWFkcyB3aWxsIGJlIGNvbXBsZXRlZCBiZWZvcmUgdGhlCgkJICogd3JpdGUgaXMgaXNzdWVkLgoJCSAqLwoJCXRhaWwgPSBBQ0NFU1NfT05DRShidWZmZXItPnVzZXJfcGFnZS0+ZGF0YV90YWlsKTsKCQlzbXBfcm1iKCk7CgkJb2Zmc2V0ID0gaGVhZCA9IGxvY2FsX3JlYWQoJmJ1ZmZlci0+aGVhZCk7CgkJaGVhZCArPSBzaXplOwoJCWlmICh1bmxpa2VseSghcGVyZl9vdXRwdXRfc3BhY2UoYnVmZmVyLCB0YWlsLCBvZmZzZXQsIGhlYWQpKSkKCQkJZ290byBmYWlsOwoJfSB3aGlsZSAobG9jYWxfY21weGNoZygmYnVmZmVyLT5oZWFkLCBvZmZzZXQsIGhlYWQpICE9IG9mZnNldCk7CgoJaWYgKGhlYWQgLSBsb2NhbF9yZWFkKCZidWZmZXItPndha2V1cCkgPiBidWZmZXItPndhdGVybWFyaykKCQlsb2NhbF9hZGQoYnVmZmVyLT53YXRlcm1hcmssICZidWZmZXItPndha2V1cCk7CgoJaGFuZGxlLT5wYWdlID0gb2Zmc2V0ID4+IChQQUdFX1NISUZUICsgcGFnZV9vcmRlcihidWZmZXIpKTsKCWhhbmRsZS0+cGFnZSAmPSBidWZmZXItPm5yX3BhZ2VzIC0gMTsKCWhhbmRsZS0+c2l6ZSA9IG9mZnNldCAmICgoUEFHRV9TSVpFIDw8IHBhZ2Vfb3JkZXIoYnVmZmVyKSkgLSAxKTsKCWhhbmRsZS0+YWRkciA9IGJ1ZmZlci0+ZGF0YV9wYWdlc1toYW5kbGUtPnBhZ2VdOwoJaGFuZGxlLT5hZGRyICs9IGhhbmRsZS0+c2l6ZTsKCWhhbmRsZS0+c2l6ZSA9IChQQUdFX1NJWkUgPDwgcGFnZV9vcmRlcihidWZmZXIpKSAtIGhhbmRsZS0+c2l6ZTsKCglpZiAoaGF2ZV9sb3N0KSB7CgkJbG9zdF9ldmVudC5oZWFkZXIudHlwZSA9IFBFUkZfUkVDT1JEX0xPU1Q7CgkJbG9zdF9ldmVudC5oZWFkZXIubWlzYyA9IDA7CgkJbG9zdF9ldmVudC5pZCAgICAgICAgICA9IGV2ZW50LT5pZDsKCQlsb3N0X2V2ZW50Lmxvc3QgICAgICAgID0gbG9jYWxfeGNoZygmYnVmZmVyLT5sb3N0LCAwKTsKCgkJcGVyZl9vdXRwdXRfcHV0KGhhbmRsZSwgbG9zdF9ldmVudCk7CgkJcGVyZl9ldmVudF9fb3V0cHV0X2lkX3NhbXBsZShldmVudCwgaGFuZGxlLCAmc2FtcGxlX2RhdGEpOwoJfQoKCXJldHVybiAwOwoKZmFpbDoKCWxvY2FsX2luYygmYnVmZmVyLT5sb3N0KTsKCXBlcmZfb3V0cHV0X3B1dF9oYW5kbGUoaGFuZGxlKTsKb3V0OgoJcmN1X3JlYWRfdW5sb2NrKCk7CgoJcmV0dXJuIC1FTk9TUEM7Cn0KCnZvaWQgcGVyZl9vdXRwdXRfZW5kKHN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgKmhhbmRsZSkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50ID0gaGFuZGxlLT5ldmVudDsKCXN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyID0gaGFuZGxlLT5idWZmZXI7CgoJaW50IHdha2V1cF9ldmVudHMgPSBldmVudC0+YXR0ci53YWtldXBfZXZlbnRzOwoKCWlmIChoYW5kbGUtPnNhbXBsZSAmJiB3YWtldXBfZXZlbnRzKSB7CgkJaW50IGV2ZW50cyA9IGxvY2FsX2luY19yZXR1cm4oJmJ1ZmZlci0+ZXZlbnRzKTsKCQlpZiAoZXZlbnRzID49IHdha2V1cF9ldmVudHMpIHsKCQkJbG9jYWxfc3ViKHdha2V1cF9ldmVudHMsICZidWZmZXItPmV2ZW50cyk7CgkJCWxvY2FsX2luYygmYnVmZmVyLT53YWtldXApOwoJCX0KCX0KCglwZXJmX291dHB1dF9wdXRfaGFuZGxlKGhhbmRsZSk7CglyY3VfcmVhZF91bmxvY2soKTsKfQoKc3RhdGljIHZvaWQgcGVyZl9vdXRwdXRfcmVhZF9vbmUoc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSAqaGFuZGxlLAoJCQkJIHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJCSB1NjQgZW5hYmxlZCwgdTY0IHJ1bm5pbmcpCnsKCXU2NCByZWFkX2Zvcm1hdCA9IGV2ZW50LT5hdHRyLnJlYWRfZm9ybWF0OwoJdTY0IHZhbHVlc1s0XTsKCWludCBuID0gMDsKCgl2YWx1ZXNbbisrXSA9IHBlcmZfZXZlbnRfY291bnQoZXZlbnQpOwoJaWYgKHJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfVE9UQUxfVElNRV9FTkFCTEVEKSB7CgkJdmFsdWVzW24rK10gPSBlbmFibGVkICsKCQkJYXRvbWljNjRfcmVhZCgmZXZlbnQtPmNoaWxkX3RvdGFsX3RpbWVfZW5hYmxlZCk7Cgl9CglpZiAocmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9UT1RBTF9USU1FX1JVTk5JTkcpIHsKCQl2YWx1ZXNbbisrXSA9IHJ1bm5pbmcgKwoJCQlhdG9taWM2NF9yZWFkKCZldmVudC0+Y2hpbGRfdG90YWxfdGltZV9ydW5uaW5nKTsKCX0KCWlmIChyZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX0lEKQoJCXZhbHVlc1tuKytdID0gcHJpbWFyeV9ldmVudF9pZChldmVudCk7CgoJcGVyZl9vdXRwdXRfY29weShoYW5kbGUsIHZhbHVlcywgbiAqIHNpemVvZih1NjQpKTsKfQoKLyoKICogWFhYIFBFUkZfRk9STUFUX0dST1VQIHZzIGluaGVyaXRlZCBldmVudHMgc2VlbXMgZGlmZmljdWx0LgogKi8Kc3RhdGljIHZvaWQgcGVyZl9vdXRwdXRfcmVhZF9ncm91cChzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlICpoYW5kbGUsCgkJCSAgICBzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCSAgICB1NjQgZW5hYmxlZCwgdTY0IHJ1bm5pbmcpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpsZWFkZXIgPSBldmVudC0+Z3JvdXBfbGVhZGVyLCAqc3ViOwoJdTY0IHJlYWRfZm9ybWF0ID0gZXZlbnQtPmF0dHIucmVhZF9mb3JtYXQ7Cgl1NjQgdmFsdWVzWzVdOwoJaW50IG4gPSAwOwoKCXZhbHVlc1tuKytdID0gMSArIGxlYWRlci0+bnJfc2libGluZ3M7CgoJaWYgKHJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfVE9UQUxfVElNRV9FTkFCTEVEKQoJCXZhbHVlc1tuKytdID0gZW5hYmxlZDsKCglpZiAocmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9UT1RBTF9USU1FX1JVTk5JTkcpCgkJdmFsdWVzW24rK10gPSBydW5uaW5nOwoKCWlmIChsZWFkZXIgIT0gZXZlbnQpCgkJbGVhZGVyLT5wbXUtPnJlYWQobGVhZGVyKTsKCgl2YWx1ZXNbbisrXSA9IHBlcmZfZXZlbnRfY291bnQobGVhZGVyKTsKCWlmIChyZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX0lEKQoJCXZhbHVlc1tuKytdID0gcHJpbWFyeV9ldmVudF9pZChsZWFkZXIpOwoKCXBlcmZfb3V0cHV0X2NvcHkoaGFuZGxlLCB2YWx1ZXMsIG4gKiBzaXplb2YodTY0KSk7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeShzdWIsICZsZWFkZXItPnNpYmxpbmdfbGlzdCwgZ3JvdXBfZW50cnkpIHsKCQluID0gMDsKCgkJaWYgKHN1YiAhPSBldmVudCkKCQkJc3ViLT5wbXUtPnJlYWQoc3ViKTsKCgkJdmFsdWVzW24rK10gPSBwZXJmX2V2ZW50X2NvdW50KHN1Yik7CgkJaWYgKHJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfSUQpCgkJCXZhbHVlc1tuKytdID0gcHJpbWFyeV9ldmVudF9pZChzdWIpOwoKCQlwZXJmX291dHB1dF9jb3B5KGhhbmRsZSwgdmFsdWVzLCBuICogc2l6ZW9mKHU2NCkpOwoJfQp9CgojZGVmaW5lIFBFUkZfRk9STUFUX1RPVEFMX1RJTUVTIChQRVJGX0ZPUk1BVF9UT1RBTF9USU1FX0VOQUJMRUR8XAoJCQkJIFBFUkZfRk9STUFUX1RPVEFMX1RJTUVfUlVOTklORykKCnN0YXRpYyB2b2lkIHBlcmZfb3V0cHV0X3JlYWQoc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSAqaGFuZGxlLAoJCQkgICAgIHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJdTY0IGVuYWJsZWQgPSAwLCBydW5uaW5nID0gMCwgbm93LCBjdHhfdGltZTsKCXU2NCByZWFkX2Zvcm1hdCA9IGV2ZW50LT5hdHRyLnJlYWRfZm9ybWF0OwoKCS8qCgkgKiBjb21wdXRlIHRvdGFsX3RpbWVfZW5hYmxlZCwgdG90YWxfdGltZV9ydW5uaW5nCgkgKiBiYXNlZCBvbiBzbmFwc2hvdCB2YWx1ZXMgdGFrZW4gd2hlbiB0aGUgZXZlbnQKCSAqIHdhcyBsYXN0IHNjaGVkdWxlZCBpbi4KCSAqCgkgKiB3ZSBjYW5ub3Qgc2ltcGx5IGNhbGxlZCB1cGRhdGVfY29udGV4dF90aW1lKCkKCSAqIGJlY2F1c2Ugb2YgbG9ja2luZyBpc3N1ZSBhcyB3ZSBhcmUgY2FsbGVkIGluCgkgKiBOTUkgY29udGV4dAoJICovCglpZiAocmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9UT1RBTF9USU1FUykgewoJCW5vdyA9IHBlcmZfY2xvY2soKTsKCQljdHhfdGltZSA9IGV2ZW50LT5zaGFkb3dfY3R4X3RpbWUgKyBub3c7CgkJZW5hYmxlZCA9IGN0eF90aW1lIC0gZXZlbnQtPnRzdGFtcF9lbmFibGVkOwoJCXJ1bm5pbmcgPSBjdHhfdGltZSAtIGV2ZW50LT50c3RhbXBfcnVubmluZzsKCX0KCglpZiAoZXZlbnQtPmF0dHIucmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9HUk9VUCkKCQlwZXJmX291dHB1dF9yZWFkX2dyb3VwKGhhbmRsZSwgZXZlbnQsIGVuYWJsZWQsIHJ1bm5pbmcpOwoJZWxzZQoJCXBlcmZfb3V0cHV0X3JlYWRfb25lKGhhbmRsZSwgZXZlbnQsIGVuYWJsZWQsIHJ1bm5pbmcpOwp9Cgp2b2lkIHBlcmZfb3V0cHV0X3NhbXBsZShzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlICpoYW5kbGUsCgkJCXN0cnVjdCBwZXJmX2V2ZW50X2hlYWRlciAqaGVhZGVyLAoJCQlzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YSwKCQkJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7Cgl1NjQgc2FtcGxlX3R5cGUgPSBkYXRhLT50eXBlOwoKCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsICpoZWFkZXIpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0lQKQoJCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsIGRhdGEtPmlwKTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9USUQpCgkJcGVyZl9vdXRwdXRfcHV0KGhhbmRsZSwgZGF0YS0+dGlkX2VudHJ5KTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9USU1FKQoJCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsIGRhdGEtPnRpbWUpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0FERFIpCgkJcGVyZl9vdXRwdXRfcHV0KGhhbmRsZSwgZGF0YS0+YWRkcik7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfSUQpCgkJcGVyZl9vdXRwdXRfcHV0KGhhbmRsZSwgZGF0YS0+aWQpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1NUUkVBTV9JRCkKCQlwZXJmX291dHB1dF9wdXQoaGFuZGxlLCBkYXRhLT5zdHJlYW1faWQpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0NQVSkKCQlwZXJmX291dHB1dF9wdXQoaGFuZGxlLCBkYXRhLT5jcHVfZW50cnkpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1BFUklPRCkKCQlwZXJmX291dHB1dF9wdXQoaGFuZGxlLCBkYXRhLT5wZXJpb2QpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1JFQUQpCgkJcGVyZl9vdXRwdXRfcmVhZChoYW5kbGUsIGV2ZW50KTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9DQUxMQ0hBSU4pIHsKCQlpZiAoZGF0YS0+Y2FsbGNoYWluKSB7CgkJCWludCBzaXplID0gMTsKCgkJCWlmIChkYXRhLT5jYWxsY2hhaW4pCgkJCQlzaXplICs9IGRhdGEtPmNhbGxjaGFpbi0+bnI7CgoJCQlzaXplICo9IHNpemVvZih1NjQpOwoKCQkJcGVyZl9vdXRwdXRfY29weShoYW5kbGUsIGRhdGEtPmNhbGxjaGFpbiwgc2l6ZSk7CgkJfSBlbHNlIHsKCQkJdTY0IG5yID0gMDsKCQkJcGVyZl9vdXRwdXRfcHV0KGhhbmRsZSwgbnIpOwoJCX0KCX0KCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9SQVcpIHsKCQlpZiAoZGF0YS0+cmF3KSB7CgkJCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsIGRhdGEtPnJhdy0+c2l6ZSk7CgkJCXBlcmZfb3V0cHV0X2NvcHkoaGFuZGxlLCBkYXRhLT5yYXctPmRhdGEsCgkJCQkJIGRhdGEtPnJhdy0+c2l6ZSk7CgkJfSBlbHNlIHsKCQkJc3RydWN0IHsKCQkJCXUzMglzaXplOwoJCQkJdTMyCWRhdGE7CgkJCX0gcmF3ID0gewoJCQkJLnNpemUgPSBzaXplb2YodTMyKSwKCQkJCS5kYXRhID0gMCwKCQkJfTsKCQkJcGVyZl9vdXRwdXRfcHV0KGhhbmRsZSwgcmF3KTsKCQl9Cgl9Cn0KCnZvaWQgcGVyZl9wcmVwYXJlX3NhbXBsZShzdHJ1Y3QgcGVyZl9ldmVudF9oZWFkZXIgKmhlYWRlciwKCQkJIHN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhICpkYXRhLAoJCQkgc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkgc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKCXU2NCBzYW1wbGVfdHlwZSA9IGV2ZW50LT5hdHRyLnNhbXBsZV90eXBlOwoKCWhlYWRlci0+dHlwZSA9IFBFUkZfUkVDT1JEX1NBTVBMRTsKCWhlYWRlci0+c2l6ZSA9IHNpemVvZigqaGVhZGVyKSArIGV2ZW50LT5oZWFkZXJfc2l6ZTsKCgloZWFkZXItPm1pc2MgPSAwOwoJaGVhZGVyLT5taXNjIHw9IHBlcmZfbWlzY19mbGFncyhyZWdzKTsKCglfX3BlcmZfZXZlbnRfaGVhZGVyX19pbml0X2lkKGhlYWRlciwgZGF0YSwgZXZlbnQpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0lQKQoJCWRhdGEtPmlwID0gcGVyZl9pbnN0cnVjdGlvbl9wb2ludGVyKHJlZ3MpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0NBTExDSEFJTikgewoJCWludCBzaXplID0gMTsKCgkJZGF0YS0+Y2FsbGNoYWluID0gcGVyZl9jYWxsY2hhaW4ocmVncyk7CgoJCWlmIChkYXRhLT5jYWxsY2hhaW4pCgkJCXNpemUgKz0gZGF0YS0+Y2FsbGNoYWluLT5ucjsKCgkJaGVhZGVyLT5zaXplICs9IHNpemUgKiBzaXplb2YodTY0KTsKCX0KCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9SQVcpIHsKCQlpbnQgc2l6ZSA9IHNpemVvZih1MzIpOwoKCQlpZiAoZGF0YS0+cmF3KQoJCQlzaXplICs9IGRhdGEtPnJhdy0+c2l6ZTsKCQllbHNlCgkJCXNpemUgKz0gc2l6ZW9mKHUzMik7CgoJCVdBUk5fT05fT05DRShzaXplICYgKHNpemVvZih1NjQpLTEpKTsKCQloZWFkZXItPnNpemUgKz0gc2l6ZTsKCX0KfQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9vdXRwdXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBpbnQgbm1pLAoJCQkJc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgKmRhdGEsCgkJCQlzdHJ1Y3QgcHRfcmVncyAqcmVncykKewoJc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSBoYW5kbGU7CglzdHJ1Y3QgcGVyZl9ldmVudF9oZWFkZXIgaGVhZGVyOwoKCS8qIHByb3RlY3QgdGhlIGNhbGxjaGFpbiBidWZmZXJzICovCglyY3VfcmVhZF9sb2NrKCk7CgoJcGVyZl9wcmVwYXJlX3NhbXBsZSgmaGVhZGVyLCBkYXRhLCBldmVudCwgcmVncyk7CgoJaWYgKHBlcmZfb3V0cHV0X2JlZ2luKCZoYW5kbGUsIGV2ZW50LCBoZWFkZXIuc2l6ZSwgbm1pLCAxKSkKCQlnb3RvIGV4aXQ7CgoJcGVyZl9vdXRwdXRfc2FtcGxlKCZoYW5kbGUsICZoZWFkZXIsIGRhdGEsIGV2ZW50KTsKCglwZXJmX291dHB1dF9lbmQoJmhhbmRsZSk7CgpleGl0OgoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCi8qCiAqIHJlYWQgZXZlbnRfaWQKICovCgpzdHJ1Y3QgcGVyZl9yZWFkX2V2ZW50IHsKCXN0cnVjdCBwZXJmX2V2ZW50X2hlYWRlcgloZWFkZXI7CgoJdTMyCQkJCXBpZDsKCXUzMgkJCQl0aWQ7Cn07CgpzdGF0aWMgdm9pZApwZXJmX2V2ZW50X3JlYWRfZXZlbnQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQlzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2spCnsKCXN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgaGFuZGxlOwoJc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgc2FtcGxlOwoJc3RydWN0IHBlcmZfcmVhZF9ldmVudCByZWFkX2V2ZW50ID0gewoJCS5oZWFkZXIgPSB7CgkJCS50eXBlID0gUEVSRl9SRUNPUkRfUkVBRCwKCQkJLm1pc2MgPSAwLAoJCQkuc2l6ZSA9IHNpemVvZihyZWFkX2V2ZW50KSArIGV2ZW50LT5yZWFkX3NpemUsCgkJfSwKCQkucGlkID0gcGVyZl9ldmVudF9waWQoZXZlbnQsIHRhc2spLAoJCS50aWQgPSBwZXJmX2V2ZW50X3RpZChldmVudCwgdGFzayksCgl9OwoJaW50IHJldDsKCglwZXJmX2V2ZW50X2hlYWRlcl9faW5pdF9pZCgmcmVhZF9ldmVudC5oZWFkZXIsICZzYW1wbGUsIGV2ZW50KTsKCXJldCA9IHBlcmZfb3V0cHV0X2JlZ2luKCZoYW5kbGUsIGV2ZW50LCByZWFkX2V2ZW50LmhlYWRlci5zaXplLCAwLCAwKTsKCWlmIChyZXQpCgkJcmV0dXJuOwoKCXBlcmZfb3V0cHV0X3B1dCgmaGFuZGxlLCByZWFkX2V2ZW50KTsKCXBlcmZfb3V0cHV0X3JlYWQoJmhhbmRsZSwgZXZlbnQpOwoJcGVyZl9ldmVudF9fb3V0cHV0X2lkX3NhbXBsZShldmVudCwgJmhhbmRsZSwgJnNhbXBsZSk7CgoJcGVyZl9vdXRwdXRfZW5kKCZoYW5kbGUpOwp9CgovKgogKiB0YXNrIHRyYWNraW5nIC0tIGZvcmsvZXhpdAogKgogKiBlbmFibGVkIGJ5OiBhdHRyLmNvbW0gfCBhdHRyLm1tYXAgfCBhdHRyLm1tYXBfZGF0YSB8IGF0dHIudGFzawogKi8KCnN0cnVjdCBwZXJmX3Rhc2tfZXZlbnQgewoJc3RydWN0IHRhc2tfc3RydWN0CQkqdGFzazsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQJKnRhc2tfY3R4OwoKCXN0cnVjdCB7CgkJc3RydWN0IHBlcmZfZXZlbnRfaGVhZGVyCWhlYWRlcjsKCgkJdTMyCQkJCXBpZDsKCQl1MzIJCQkJcHBpZDsKCQl1MzIJCQkJdGlkOwoJCXUzMgkJCQlwdGlkOwoJCXU2NAkJCQl0aW1lOwoJfSBldmVudF9pZDsKfTsKCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfdGFza19vdXRwdXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJICAgICBzdHJ1Y3QgcGVyZl90YXNrX2V2ZW50ICp0YXNrX2V2ZW50KQp7CglzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlIGhhbmRsZTsKCXN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhCXNhbXBsZTsKCXN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzayA9IHRhc2tfZXZlbnQtPnRhc2s7CglpbnQgcmV0LCBzaXplID0gdGFza19ldmVudC0+ZXZlbnRfaWQuaGVhZGVyLnNpemU7CgoJcGVyZl9ldmVudF9oZWFkZXJfX2luaXRfaWQoJnRhc2tfZXZlbnQtPmV2ZW50X2lkLmhlYWRlciwgJnNhbXBsZSwgZXZlbnQpOwoKCXJldCA9IHBlcmZfb3V0cHV0X2JlZ2luKCZoYW5kbGUsIGV2ZW50LAoJCQkJdGFza19ldmVudC0+ZXZlbnRfaWQuaGVhZGVyLnNpemUsIDAsIDApOwoJaWYgKHJldCkKCQlnb3RvIG91dDsKCgl0YXNrX2V2ZW50LT5ldmVudF9pZC5waWQgPSBwZXJmX2V2ZW50X3BpZChldmVudCwgdGFzayk7Cgl0YXNrX2V2ZW50LT5ldmVudF9pZC5wcGlkID0gcGVyZl9ldmVudF9waWQoZXZlbnQsIGN1cnJlbnQpOwoKCXRhc2tfZXZlbnQtPmV2ZW50X2lkLnRpZCA9IHBlcmZfZXZlbnRfdGlkKGV2ZW50LCB0YXNrKTsKCXRhc2tfZXZlbnQtPmV2ZW50X2lkLnB0aWQgPSBwZXJmX2V2ZW50X3RpZChldmVudCwgY3VycmVudCk7CgoJcGVyZl9vdXRwdXRfcHV0KCZoYW5kbGUsIHRhc2tfZXZlbnQtPmV2ZW50X2lkKTsKCglwZXJmX2V2ZW50X19vdXRwdXRfaWRfc2FtcGxlKGV2ZW50LCAmaGFuZGxlLCAmc2FtcGxlKTsKCglwZXJmX291dHB1dF9lbmQoJmhhbmRsZSk7Cm91dDoKCXRhc2tfZXZlbnQtPmV2ZW50X2lkLmhlYWRlci5zaXplID0gc2l6ZTsKfQoKc3RhdGljIGludCBwZXJmX2V2ZW50X3Rhc2tfbWF0Y2goc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglpZiAoZXZlbnQtPnN0YXRlIDwgUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRSkKCQlyZXR1cm4gMDsKCglpZiAoIWV2ZW50X2ZpbHRlcl9tYXRjaChldmVudCkpCgkJcmV0dXJuIDA7CgoJaWYgKGV2ZW50LT5hdHRyLmNvbW0gfHwgZXZlbnQtPmF0dHIubW1hcCB8fAoJICAgIGV2ZW50LT5hdHRyLm1tYXBfZGF0YSB8fCBldmVudC0+YXR0ci50YXNrKQoJCXJldHVybiAxOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X3Rhc2tfY3R4KHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCwKCQkJCSAgc3RydWN0IHBlcmZfdGFza19ldmVudCAqdGFza19ldmVudCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoKCWxpc3RfZm9yX2VhY2hfZW50cnlfcmN1KGV2ZW50LCAmY3R4LT5ldmVudF9saXN0LCBldmVudF9lbnRyeSkgewoJCWlmIChwZXJmX2V2ZW50X3Rhc2tfbWF0Y2goZXZlbnQpKQoJCQlwZXJmX2V2ZW50X3Rhc2tfb3V0cHV0KGV2ZW50LCB0YXNrX2V2ZW50KTsKCX0KfQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF90YXNrX2V2ZW50KHN0cnVjdCBwZXJmX3Rhc2tfZXZlbnQgKnRhc2tfZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHg7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHg7CglzdHJ1Y3QgcG11ICpwbXU7CglpbnQgY3R4bjsKCglyY3VfcmVhZF9sb2NrKCk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5X3JjdShwbXUsICZwbXVzLCBlbnRyeSkgewoJCWNwdWN0eCA9IGdldF9jcHVfcHRyKHBtdS0+cG11X2NwdV9jb250ZXh0KTsKCQlpZiAoY3B1Y3R4LT5hY3RpdmVfcG11ICE9IHBtdSkKCQkJZ290byBuZXh0OwoJCXBlcmZfZXZlbnRfdGFza19jdHgoJmNwdWN0eC0+Y3R4LCB0YXNrX2V2ZW50KTsKCgkJY3R4ID0gdGFza19ldmVudC0+dGFza19jdHg7CgkJaWYgKCFjdHgpIHsKCQkJY3R4biA9IHBtdS0+dGFza19jdHhfbnI7CgkJCWlmIChjdHhuIDwgMCkKCQkJCWdvdG8gbmV4dDsKCQkJY3R4ID0gcmN1X2RlcmVmZXJlbmNlKGN1cnJlbnQtPnBlcmZfZXZlbnRfY3R4cFtjdHhuXSk7CgkJfQoJCWlmIChjdHgpCgkJCXBlcmZfZXZlbnRfdGFza19jdHgoY3R4LCB0YXNrX2V2ZW50KTsKbmV4dDoKCQlwdXRfY3B1X3B0cihwbXUtPnBtdV9jcHVfY29udGV4dCk7Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKfQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF90YXNrKHN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzaywKCQkJICAgICAgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqdGFza19jdHgsCgkJCSAgICAgIGludCBuZXcpCnsKCXN0cnVjdCBwZXJmX3Rhc2tfZXZlbnQgdGFza19ldmVudDsKCglpZiAoIWF0b21pY19yZWFkKCZucl9jb21tX2V2ZW50cykgJiYKCSAgICAhYXRvbWljX3JlYWQoJm5yX21tYXBfZXZlbnRzKSAmJgoJICAgICFhdG9taWNfcmVhZCgmbnJfdGFza19ldmVudHMpKQoJCXJldHVybjsKCgl0YXNrX2V2ZW50ID0gKHN0cnVjdCBwZXJmX3Rhc2tfZXZlbnQpewoJCS50YXNrCSAgPSB0YXNrLAoJCS50YXNrX2N0eCA9IHRhc2tfY3R4LAoJCS5ldmVudF9pZCAgICA9IHsKCQkJLmhlYWRlciA9IHsKCQkJCS50eXBlID0gbmV3ID8gUEVSRl9SRUNPUkRfRk9SSyA6IFBFUkZfUkVDT1JEX0VYSVQsCgkJCQkubWlzYyA9IDAsCgkJCQkuc2l6ZSA9IHNpemVvZih0YXNrX2V2ZW50LmV2ZW50X2lkKSwKCQkJfSwKCQkJLyogLnBpZCAgKi8KCQkJLyogLnBwaWQgKi8KCQkJLyogLnRpZCAgKi8KCQkJLyogLnB0aWQgKi8KCQkJLnRpbWUgPSBwZXJmX2Nsb2NrKCksCgkJfSwKCX07CgoJcGVyZl9ldmVudF90YXNrX2V2ZW50KCZ0YXNrX2V2ZW50KTsKfQoKdm9pZCBwZXJmX2V2ZW50X2Zvcmsoc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrKQp7CglwZXJmX2V2ZW50X3Rhc2sodGFzaywgTlVMTCwgMSk7Cn0KCi8qCiAqIGNvbW0gdHJhY2tpbmcKICovCgpzdHJ1Y3QgcGVyZl9jb21tX2V2ZW50IHsKCXN0cnVjdCB0YXNrX3N0cnVjdAkqdGFzazsKCWNoYXIJCQkqY29tbTsKCWludAkJCWNvbW1fc2l6ZTsKCglzdHJ1Y3QgewoJCXN0cnVjdCBwZXJmX2V2ZW50X2hlYWRlcgloZWFkZXI7CgoJCXUzMgkJCQlwaWQ7CgkJdTMyCQkJCXRpZDsKCX0gZXZlbnRfaWQ7Cn07CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X2NvbW1fb3V0cHV0KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJCSAgICAgc3RydWN0IHBlcmZfY29tbV9ldmVudCAqY29tbV9ldmVudCkKewoJc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSBoYW5kbGU7CglzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSBzYW1wbGU7CglpbnQgc2l6ZSA9IGNvbW1fZXZlbnQtPmV2ZW50X2lkLmhlYWRlci5zaXplOwoJaW50IHJldDsKCglwZXJmX2V2ZW50X2hlYWRlcl9faW5pdF9pZCgmY29tbV9ldmVudC0+ZXZlbnRfaWQuaGVhZGVyLCAmc2FtcGxlLCBldmVudCk7CglyZXQgPSBwZXJmX291dHB1dF9iZWdpbigmaGFuZGxlLCBldmVudCwKCQkJCWNvbW1fZXZlbnQtPmV2ZW50X2lkLmhlYWRlci5zaXplLCAwLCAwKTsKCglpZiAocmV0KQoJCWdvdG8gb3V0OwoKCWNvbW1fZXZlbnQtPmV2ZW50X2lkLnBpZCA9IHBlcmZfZXZlbnRfcGlkKGV2ZW50LCBjb21tX2V2ZW50LT50YXNrKTsKCWNvbW1fZXZlbnQtPmV2ZW50X2lkLnRpZCA9IHBlcmZfZXZlbnRfdGlkKGV2ZW50LCBjb21tX2V2ZW50LT50YXNrKTsKCglwZXJmX291dHB1dF9wdXQoJmhhbmRsZSwgY29tbV9ldmVudC0+ZXZlbnRfaWQpOwoJcGVyZl9vdXRwdXRfY29weSgmaGFuZGxlLCBjb21tX2V2ZW50LT5jb21tLAoJCQkJICAgY29tbV9ldmVudC0+Y29tbV9zaXplKTsKCglwZXJmX2V2ZW50X19vdXRwdXRfaWRfc2FtcGxlKGV2ZW50LCAmaGFuZGxlLCAmc2FtcGxlKTsKCglwZXJmX291dHB1dF9lbmQoJmhhbmRsZSk7Cm91dDoKCWNvbW1fZXZlbnQtPmV2ZW50X2lkLmhlYWRlci5zaXplID0gc2l6ZTsKfQoKc3RhdGljIGludCBwZXJmX2V2ZW50X2NvbW1fbWF0Y2goc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglpZiAoZXZlbnQtPnN0YXRlIDwgUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRSkKCQlyZXR1cm4gMDsKCglpZiAoIWV2ZW50X2ZpbHRlcl9tYXRjaChldmVudCkpCgkJcmV0dXJuIDA7CgoJaWYgKGV2ZW50LT5hdHRyLmNvbW0pCgkJcmV0dXJuIDE7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfY29tbV9jdHgoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4LAoJCQkJICBzdHJ1Y3QgcGVyZl9jb21tX2V2ZW50ICpjb21tX2V2ZW50KQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQ7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeV9yY3UoZXZlbnQsICZjdHgtPmV2ZW50X2xpc3QsIGV2ZW50X2VudHJ5KSB7CgkJaWYgKHBlcmZfZXZlbnRfY29tbV9tYXRjaChldmVudCkpCgkJCXBlcmZfZXZlbnRfY29tbV9vdXRwdXQoZXZlbnQsIGNvbW1fZXZlbnQpOwoJfQp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X2NvbW1fZXZlbnQoc3RydWN0IHBlcmZfY29tbV9ldmVudCAqY29tbV9ldmVudCkKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eDsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eDsKCWNoYXIgY29tbVtUQVNLX0NPTU1fTEVOXTsKCXVuc2lnbmVkIGludCBzaXplOwoJc3RydWN0IHBtdSAqcG11OwoJaW50IGN0eG47CgoJbWVtc2V0KGNvbW0sIDAsIHNpemVvZihjb21tKSk7CglzdHJsY3B5KGNvbW0sIGNvbW1fZXZlbnQtPnRhc2stPmNvbW0sIHNpemVvZihjb21tKSk7CglzaXplID0gQUxJR04oc3RybGVuKGNvbW0pKzEsIHNpemVvZih1NjQpKTsKCgljb21tX2V2ZW50LT5jb21tID0gY29tbTsKCWNvbW1fZXZlbnQtPmNvbW1fc2l6ZSA9IHNpemU7CgoJY29tbV9ldmVudC0+ZXZlbnRfaWQuaGVhZGVyLnNpemUgPSBzaXplb2YoY29tbV9ldmVudC0+ZXZlbnRfaWQpICsgc2l6ZTsKCXJjdV9yZWFkX2xvY2soKTsKCWxpc3RfZm9yX2VhY2hfZW50cnlfcmN1KHBtdSwgJnBtdXMsIGVudHJ5KSB7CgkJY3B1Y3R4ID0gZ2V0X2NwdV9wdHIocG11LT5wbXVfY3B1X2NvbnRleHQpOwoJCWlmIChjcHVjdHgtPmFjdGl2ZV9wbXUgIT0gcG11KQoJCQlnb3RvIG5leHQ7CgkJcGVyZl9ldmVudF9jb21tX2N0eCgmY3B1Y3R4LT5jdHgsIGNvbW1fZXZlbnQpOwoKCQljdHhuID0gcG11LT50YXNrX2N0eF9ucjsKCQlpZiAoY3R4biA8IDApCgkJCWdvdG8gbmV4dDsKCgkJY3R4ID0gcmN1X2RlcmVmZXJlbmNlKGN1cnJlbnQtPnBlcmZfZXZlbnRfY3R4cFtjdHhuXSk7CgkJaWYgKGN0eCkKCQkJcGVyZl9ldmVudF9jb21tX2N0eChjdHgsIGNvbW1fZXZlbnQpOwpuZXh0OgoJCXB1dF9jcHVfcHRyKHBtdS0+cG11X2NwdV9jb250ZXh0KTsKCX0KCXJjdV9yZWFkX3VubG9jaygpOwp9Cgp2b2lkIHBlcmZfZXZlbnRfY29tbShzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2spCnsKCXN0cnVjdCBwZXJmX2NvbW1fZXZlbnQgY29tbV9ldmVudDsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eDsKCWludCBjdHhuOwoKCWZvcl9lYWNoX3Rhc2tfY29udGV4dF9ucihjdHhuKSB7CgkJY3R4ID0gdGFzay0+cGVyZl9ldmVudF9jdHhwW2N0eG5dOwoJCWlmICghY3R4KQoJCQljb250aW51ZTsKCgkJcGVyZl9ldmVudF9lbmFibGVfb25fZXhlYyhjdHgpOwoJfQoKCWlmICghYXRvbWljX3JlYWQoJm5yX2NvbW1fZXZlbnRzKSkKCQlyZXR1cm47CgoJY29tbV9ldmVudCA9IChzdHJ1Y3QgcGVyZl9jb21tX2V2ZW50KXsKCQkudGFzawk9IHRhc2ssCgkJLyogLmNvbW0gICAgICAqLwoJCS8qIC5jb21tX3NpemUgKi8KCQkuZXZlbnRfaWQgID0gewoJCQkuaGVhZGVyID0gewoJCQkJLnR5cGUgPSBQRVJGX1JFQ09SRF9DT01NLAoJCQkJLm1pc2MgPSAwLAoJCQkJLyogLnNpemUgKi8KCQkJfSwKCQkJLyogLnBpZCAqLwoJCQkvKiAudGlkICovCgkJfSwKCX07CgoJcGVyZl9ldmVudF9jb21tX2V2ZW50KCZjb21tX2V2ZW50KTsKfQoKLyoKICogbW1hcCB0cmFja2luZwogKi8KCnN0cnVjdCBwZXJmX21tYXBfZXZlbnQgewoJc3RydWN0IHZtX2FyZWFfc3RydWN0CSp2bWE7CgoJY29uc3QgY2hhcgkJKmZpbGVfbmFtZTsKCWludAkJCWZpbGVfc2l6ZTsKCglzdHJ1Y3QgewoJCXN0cnVjdCBwZXJmX2V2ZW50X2hlYWRlcgloZWFkZXI7CgoJCXUzMgkJCQlwaWQ7CgkJdTMyCQkJCXRpZDsKCQl1NjQJCQkJc3RhcnQ7CgkJdTY0CQkJCWxlbjsKCQl1NjQJCQkJcGdvZmY7Cgl9IGV2ZW50X2lkOwp9OwoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9tbWFwX291dHB1dChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCQkgICAgIHN0cnVjdCBwZXJmX21tYXBfZXZlbnQgKm1tYXBfZXZlbnQpCnsKCXN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgaGFuZGxlOwoJc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgc2FtcGxlOwoJaW50IHNpemUgPSBtbWFwX2V2ZW50LT5ldmVudF9pZC5oZWFkZXIuc2l6ZTsKCWludCByZXQ7CgoJcGVyZl9ldmVudF9oZWFkZXJfX2luaXRfaWQoJm1tYXBfZXZlbnQtPmV2ZW50X2lkLmhlYWRlciwgJnNhbXBsZSwgZXZlbnQpOwoJcmV0ID0gcGVyZl9vdXRwdXRfYmVnaW4oJmhhbmRsZSwgZXZlbnQsCgkJCQltbWFwX2V2ZW50LT5ldmVudF9pZC5oZWFkZXIuc2l6ZSwgMCwgMCk7CglpZiAocmV0KQoJCWdvdG8gb3V0OwoKCW1tYXBfZXZlbnQtPmV2ZW50X2lkLnBpZCA9IHBlcmZfZXZlbnRfcGlkKGV2ZW50LCBjdXJyZW50KTsKCW1tYXBfZXZlbnQtPmV2ZW50X2lkLnRpZCA9IHBlcmZfZXZlbnRfdGlkKGV2ZW50LCBjdXJyZW50KTsKCglwZXJmX291dHB1dF9wdXQoJmhhbmRsZSwgbW1hcF9ldmVudC0+ZXZlbnRfaWQpOwoJcGVyZl9vdXRwdXRfY29weSgmaGFuZGxlLCBtbWFwX2V2ZW50LT5maWxlX25hbWUsCgkJCQkgICBtbWFwX2V2ZW50LT5maWxlX3NpemUpOwoKCXBlcmZfZXZlbnRfX291dHB1dF9pZF9zYW1wbGUoZXZlbnQsICZoYW5kbGUsICZzYW1wbGUpOwoKCXBlcmZfb3V0cHV0X2VuZCgmaGFuZGxlKTsKb3V0OgoJbW1hcF9ldmVudC0+ZXZlbnRfaWQuaGVhZGVyLnNpemUgPSBzaXplOwp9CgpzdGF0aWMgaW50IHBlcmZfZXZlbnRfbW1hcF9tYXRjaChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCQkgICBzdHJ1Y3QgcGVyZl9tbWFwX2V2ZW50ICptbWFwX2V2ZW50LAoJCQkJICAgaW50IGV4ZWN1dGFibGUpCnsKCWlmIChldmVudC0+c3RhdGUgPCBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFKQoJCXJldHVybiAwOwoKCWlmICghZXZlbnRfZmlsdGVyX21hdGNoKGV2ZW50KSkKCQlyZXR1cm4gMDsKCglpZiAoKCFleGVjdXRhYmxlICYmIGV2ZW50LT5hdHRyLm1tYXBfZGF0YSkgfHwKCSAgICAoZXhlY3V0YWJsZSAmJiBldmVudC0+YXR0ci5tbWFwKSkKCQlyZXR1cm4gMTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9tbWFwX2N0eChzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgsCgkJCQkgIHN0cnVjdCBwZXJmX21tYXBfZXZlbnQgKm1tYXBfZXZlbnQsCgkJCQkgIGludCBleGVjdXRhYmxlKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQ7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeV9yY3UoZXZlbnQsICZjdHgtPmV2ZW50X2xpc3QsIGV2ZW50X2VudHJ5KSB7CgkJaWYgKHBlcmZfZXZlbnRfbW1hcF9tYXRjaChldmVudCwgbW1hcF9ldmVudCwgZXhlY3V0YWJsZSkpCgkJCXBlcmZfZXZlbnRfbW1hcF9vdXRwdXQoZXZlbnQsIG1tYXBfZXZlbnQpOwoJfQp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X21tYXBfZXZlbnQoc3RydWN0IHBlcmZfbW1hcF9ldmVudCAqbW1hcF9ldmVudCkKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eDsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eDsKCXN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqdm1hID0gbW1hcF9ldmVudC0+dm1hOwoJc3RydWN0IGZpbGUgKmZpbGUgPSB2bWEtPnZtX2ZpbGU7Cgl1bnNpZ25lZCBpbnQgc2l6ZTsKCWNoYXIgdG1wWzE2XTsKCWNoYXIgKmJ1ZiA9IE5VTEw7Cgljb25zdCBjaGFyICpuYW1lOwoJc3RydWN0IHBtdSAqcG11OwoJaW50IGN0eG47CgoJbWVtc2V0KHRtcCwgMCwgc2l6ZW9mKHRtcCkpOwoKCWlmIChmaWxlKSB7CgkJLyoKCQkgKiBkX3BhdGggd29ya3MgZnJvbSB0aGUgZW5kIG9mIHRoZSBidWZmZXIgYmFja3dhcmRzLCBzbyB3ZQoJCSAqIG5lZWQgdG8gYWRkIGVub3VnaCB6ZXJvIGJ5dGVzIGFmdGVyIHRoZSBzdHJpbmcgdG8gaGFuZGxlCgkJICogdGhlIDY0Yml0IGFsaWdubWVudCB3ZSBkbyBsYXRlci4KCQkgKi8KCQlidWYgPSBremFsbG9jKFBBVEhfTUFYICsgc2l6ZW9mKHU2NCksIEdGUF9LRVJORUwpOwoJCWlmICghYnVmKSB7CgkJCW5hbWUgPSBzdHJuY3B5KHRtcCwgIi8vZW5vbWVtIiwgc2l6ZW9mKHRtcCkpOwoJCQlnb3RvIGdvdF9uYW1lOwoJCX0KCQluYW1lID0gZF9wYXRoKCZmaWxlLT5mX3BhdGgsIGJ1ZiwgUEFUSF9NQVgpOwoJCWlmIChJU19FUlIobmFtZSkpIHsKCQkJbmFtZSA9IHN0cm5jcHkodG1wLCAiLy90b29sb25nIiwgc2l6ZW9mKHRtcCkpOwoJCQlnb3RvIGdvdF9uYW1lOwoJCX0KCX0gZWxzZSB7CgkJaWYgKGFyY2hfdm1hX25hbWUobW1hcF9ldmVudC0+dm1hKSkgewoJCQluYW1lID0gc3RybmNweSh0bXAsIGFyY2hfdm1hX25hbWUobW1hcF9ldmVudC0+dm1hKSwKCQkJCSAgICAgICBzaXplb2YodG1wKSk7CgkJCWdvdG8gZ290X25hbWU7CgkJfQoKCQlpZiAoIXZtYS0+dm1fbW0pIHsKCQkJbmFtZSA9IHN0cm5jcHkodG1wLCAiW3Zkc29dIiwgc2l6ZW9mKHRtcCkpOwoJCQlnb3RvIGdvdF9uYW1lOwoJCX0gZWxzZSBpZiAodm1hLT52bV9zdGFydCA8PSB2bWEtPnZtX21tLT5zdGFydF9icmsgJiYKCQkJCXZtYS0+dm1fZW5kID49IHZtYS0+dm1fbW0tPmJyaykgewoJCQluYW1lID0gc3RybmNweSh0bXAsICJbaGVhcF0iLCBzaXplb2YodG1wKSk7CgkJCWdvdG8gZ290X25hbWU7CgkJfSBlbHNlIGlmICh2bWEtPnZtX3N0YXJ0IDw9IHZtYS0+dm1fbW0tPnN0YXJ0X3N0YWNrICYmCgkJCQl2bWEtPnZtX2VuZCA+PSB2bWEtPnZtX21tLT5zdGFydF9zdGFjaykgewoJCQluYW1lID0gc3RybmNweSh0bXAsICJbc3RhY2tdIiwgc2l6ZW9mKHRtcCkpOwoJCQlnb3RvIGdvdF9uYW1lOwoJCX0KCgkJbmFtZSA9IHN0cm5jcHkodG1wLCAiLy9hbm9uIiwgc2l6ZW9mKHRtcCkpOwoJCWdvdG8gZ290X25hbWU7Cgl9Cgpnb3RfbmFtZToKCXNpemUgPSBBTElHTihzdHJsZW4obmFtZSkrMSwgc2l6ZW9mKHU2NCkpOwoKCW1tYXBfZXZlbnQtPmZpbGVfbmFtZSA9IG5hbWU7CgltbWFwX2V2ZW50LT5maWxlX3NpemUgPSBzaXplOwoKCW1tYXBfZXZlbnQtPmV2ZW50X2lkLmhlYWRlci5zaXplID0gc2l6ZW9mKG1tYXBfZXZlbnQtPmV2ZW50X2lkKSArIHNpemU7CgoJcmN1X3JlYWRfbG9jaygpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeV9yY3UocG11LCAmcG11cywgZW50cnkpIHsKCQljcHVjdHggPSBnZXRfY3B1X3B0cihwbXUtPnBtdV9jcHVfY29udGV4dCk7CgkJaWYgKGNwdWN0eC0+YWN0aXZlX3BtdSAhPSBwbXUpCgkJCWdvdG8gbmV4dDsKCQlwZXJmX2V2ZW50X21tYXBfY3R4KCZjcHVjdHgtPmN0eCwgbW1hcF9ldmVudCwKCQkJCQl2bWEtPnZtX2ZsYWdzICYgVk1fRVhFQyk7CgoJCWN0eG4gPSBwbXUtPnRhc2tfY3R4X25yOwoJCWlmIChjdHhuIDwgMCkKCQkJZ290byBuZXh0OwoKCQljdHggPSByY3VfZGVyZWZlcmVuY2UoY3VycmVudC0+cGVyZl9ldmVudF9jdHhwW2N0eG5dKTsKCQlpZiAoY3R4KSB7CgkJCXBlcmZfZXZlbnRfbW1hcF9jdHgoY3R4LCBtbWFwX2V2ZW50LAoJCQkJCXZtYS0+dm1fZmxhZ3MgJiBWTV9FWEVDKTsKCQl9Cm5leHQ6CgkJcHV0X2NwdV9wdHIocG11LT5wbXVfY3B1X2NvbnRleHQpOwoJfQoJcmN1X3JlYWRfdW5sb2NrKCk7CgoJa2ZyZWUoYnVmKTsKfQoKdm9pZCBwZXJmX2V2ZW50X21tYXAoc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEpCnsKCXN0cnVjdCBwZXJmX21tYXBfZXZlbnQgbW1hcF9ldmVudDsKCglpZiAoIWF0b21pY19yZWFkKCZucl9tbWFwX2V2ZW50cykpCgkJcmV0dXJuOwoKCW1tYXBfZXZlbnQgPSAoc3RydWN0IHBlcmZfbW1hcF9ldmVudCl7CgkJLnZtYQk9IHZtYSwKCQkvKiAuZmlsZV9uYW1lICovCgkJLyogLmZpbGVfc2l6ZSAqLwoJCS5ldmVudF9pZCAgPSB7CgkJCS5oZWFkZXIgPSB7CgkJCQkudHlwZSA9IFBFUkZfUkVDT1JEX01NQVAsCgkJCQkubWlzYyA9IFBFUkZfUkVDT1JEX01JU0NfVVNFUiwKCQkJCS8qIC5zaXplICovCgkJCX0sCgkJCS8qIC5waWQgKi8KCQkJLyogLnRpZCAqLwoJCQkuc3RhcnQgID0gdm1hLT52bV9zdGFydCwKCQkJLmxlbiAgICA9IHZtYS0+dm1fZW5kIC0gdm1hLT52bV9zdGFydCwKCQkJLnBnb2ZmICA9ICh1NjQpdm1hLT52bV9wZ29mZiA8PCBQQUdFX1NISUZULAoJCX0sCgl9OwoKCXBlcmZfZXZlbnRfbW1hcF9ldmVudCgmbW1hcF9ldmVudCk7Cn0KCi8qCiAqIElSUSB0aHJvdHRsZSBsb2dnaW5nCiAqLwoKc3RhdGljIHZvaWQgcGVyZl9sb2dfdGhyb3R0bGUoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBpbnQgZW5hYmxlKQp7CglzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlIGhhbmRsZTsKCXN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhIHNhbXBsZTsKCWludCByZXQ7CgoJc3RydWN0IHsKCQlzdHJ1Y3QgcGVyZl9ldmVudF9oZWFkZXIJaGVhZGVyOwoJCXU2NAkJCQl0aW1lOwoJCXU2NAkJCQlpZDsKCQl1NjQJCQkJc3RyZWFtX2lkOwoJfSB0aHJvdHRsZV9ldmVudCA9IHsKCQkuaGVhZGVyID0gewoJCQkudHlwZSA9IFBFUkZfUkVDT1JEX1RIUk9UVExFLAoJCQkubWlzYyA9IDAsCgkJCS5zaXplID0gc2l6ZW9mKHRocm90dGxlX2V2ZW50KSwKCQl9LAoJCS50aW1lCQk9IHBlcmZfY2xvY2soKSwKCQkuaWQJCT0gcHJpbWFyeV9ldmVudF9pZChldmVudCksCgkJLnN0cmVhbV9pZAk9IGV2ZW50LT5pZCwKCX07CgoJaWYgKGVuYWJsZSkKCQl0aHJvdHRsZV9ldmVudC5oZWFkZXIudHlwZSA9IFBFUkZfUkVDT1JEX1VOVEhST1RUTEU7CgoJcGVyZl9ldmVudF9oZWFkZXJfX2luaXRfaWQoJnRocm90dGxlX2V2ZW50LmhlYWRlciwgJnNhbXBsZSwgZXZlbnQpOwoKCXJldCA9IHBlcmZfb3V0cHV0X2JlZ2luKCZoYW5kbGUsIGV2ZW50LAoJCQkJdGhyb3R0bGVfZXZlbnQuaGVhZGVyLnNpemUsIDEsIDApOwoJaWYgKHJldCkKCQlyZXR1cm47CgoJcGVyZl9vdXRwdXRfcHV0KCZoYW5kbGUsIHRocm90dGxlX2V2ZW50KTsKCXBlcmZfZXZlbnRfX291dHB1dF9pZF9zYW1wbGUoZXZlbnQsICZoYW5kbGUsICZzYW1wbGUpOwoJcGVyZl9vdXRwdXRfZW5kKCZoYW5kbGUpOwp9CgovKgogKiBHZW5lcmljIGV2ZW50IG92ZXJmbG93IGhhbmRsaW5nLCBzYW1wbGluZy4KICovCgpzdGF0aWMgaW50IF9fcGVyZl9ldmVudF9vdmVyZmxvdyhzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIGludCBubWksCgkJCQkgICBpbnQgdGhyb3R0bGUsIHN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhICpkYXRhLAoJCQkJICAgc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKCWludCBldmVudHMgPSBhdG9taWNfcmVhZCgmZXZlbnQtPmV2ZW50X2xpbWl0KTsKCXN0cnVjdCBod19wZXJmX2V2ZW50ICpod2MgPSAmZXZlbnQtPmh3OwoJaW50IHJldCA9IDA7CgoJLyoKCSAqIE5vbi1zYW1wbGluZyBjb3VudGVycyBtaWdodCBzdGlsbCB1c2UgdGhlIFBNSSB0byBmb2xkIHNob3J0CgkgKiBoYXJkd2FyZSBjb3VudGVycywgaWdub3JlIHRob3NlLgoJICovCglpZiAodW5saWtlbHkoIWlzX3NhbXBsaW5nX2V2ZW50KGV2ZW50KSkpCgkJcmV0dXJuIDA7CgoJaWYgKCF0aHJvdHRsZSkgewoJCWh3Yy0+aW50ZXJydXB0cysrOwoJfSBlbHNlIHsKCQlpZiAoaHdjLT5pbnRlcnJ1cHRzICE9IE1BWF9JTlRFUlJVUFRTKSB7CgkJCWh3Yy0+aW50ZXJydXB0cysrOwoJCQlpZiAoSFogKiBod2MtPmludGVycnVwdHMgPgoJCQkJCSh1NjQpc3lzY3RsX3BlcmZfZXZlbnRfc2FtcGxlX3JhdGUpIHsKCQkJCWh3Yy0+aW50ZXJydXB0cyA9IE1BWF9JTlRFUlJVUFRTOwoJCQkJcGVyZl9sb2dfdGhyb3R0bGUoZXZlbnQsIDApOwoJCQkJcmV0ID0gMTsKCQkJfQoJCX0gZWxzZSB7CgkJCS8qCgkJCSAqIEtlZXAgcmUtZGlzYWJsaW5nIGV2ZW50cyBldmVuIHRob3VnaCBvbiB0aGUgcHJldmlvdXMKCQkJICogcGFzcyB3ZSBkaXNhYmxlZCBpdCAtIGp1c3QgaW4gY2FzZSB3ZSByYWNlZCB3aXRoIGEKCQkJICogc2NoZWQtaW4gYW5kIHRoZSBldmVudCBnb3QgZW5hYmxlZCBhZ2FpbjoKCQkJICovCgkJCXJldCA9IDE7CgkJfQoJfQoKCWlmIChldmVudC0+YXR0ci5mcmVxKSB7CgkJdTY0IG5vdyA9IHBlcmZfY2xvY2soKTsKCQlzNjQgZGVsdGEgPSBub3cgLSBod2MtPmZyZXFfdGltZV9zdGFtcDsKCgkJaHdjLT5mcmVxX3RpbWVfc3RhbXAgPSBub3c7CgoJCWlmIChkZWx0YSA+IDAgJiYgZGVsdGEgPCAyKlRJQ0tfTlNFQykKCQkJcGVyZl9hZGp1c3RfcGVyaW9kKGV2ZW50LCBkZWx0YSwgaHdjLT5sYXN0X3BlcmlvZCk7Cgl9CgoJLyoKCSAqIFhYWCBldmVudF9saW1pdCBtaWdodCBub3QgcXVpdGUgd29yayBhcyBleHBlY3RlZCBvbiBpbmhlcml0ZWQKCSAqIGV2ZW50cwoJICovCgoJZXZlbnQtPnBlbmRpbmdfa2lsbCA9IFBPTExfSU47CglpZiAoZXZlbnRzICYmIGF0b21pY19kZWNfYW5kX3Rlc3QoJmV2ZW50LT5ldmVudF9saW1pdCkpIHsKCQlyZXQgPSAxOwoJCWV2ZW50LT5wZW5kaW5nX2tpbGwgPSBQT0xMX0hVUDsKCQlpZiAobm1pKSB7CgkJCWV2ZW50LT5wZW5kaW5nX2Rpc2FibGUgPSAxOwoJCQlpcnFfd29ya19xdWV1ZSgmZXZlbnQtPnBlbmRpbmcpOwoJCX0gZWxzZQoJCQlwZXJmX2V2ZW50X2Rpc2FibGUoZXZlbnQpOwoJfQoKCWlmIChldmVudC0+b3ZlcmZsb3dfaGFuZGxlcikKCQlldmVudC0+b3ZlcmZsb3dfaGFuZGxlcihldmVudCwgbm1pLCBkYXRhLCByZWdzKTsKCWVsc2UKCQlwZXJmX2V2ZW50X291dHB1dChldmVudCwgbm1pLCBkYXRhLCByZWdzKTsKCglyZXR1cm4gcmV0Owp9CgppbnQgcGVyZl9ldmVudF9vdmVyZmxvdyhzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIGludCBubWksCgkJCSAgc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgKmRhdGEsCgkJCSAgc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKCXJldHVybiBfX3BlcmZfZXZlbnRfb3ZlcmZsb3coZXZlbnQsIG5taSwgMSwgZGF0YSwgcmVncyk7Cn0KCi8qCiAqIEdlbmVyaWMgc29mdHdhcmUgZXZlbnQgaW5mcmFzdHJ1Y3R1cmUKICovCgpzdHJ1Y3Qgc3dldmVudF9odGFibGUgewoJc3RydWN0IHN3ZXZlbnRfaGxpc3QJCSpzd2V2ZW50X2hsaXN0OwoJc3RydWN0IG11dGV4CQkJaGxpc3RfbXV0ZXg7CglpbnQJCQkJaGxpc3RfcmVmY291bnQ7CgoJLyogUmVjdXJzaW9uIGF2b2lkYW5jZSBpbiBlYWNoIGNvbnRleHRzICovCglpbnQJCQkJcmVjdXJzaW9uW1BFUkZfTlJfQ09OVEVYVFNdOwp9OwoKc3RhdGljIERFRklORV9QRVJfQ1BVKHN0cnVjdCBzd2V2ZW50X2h0YWJsZSwgc3dldmVudF9odGFibGUpOwoKLyoKICogV2UgZGlyZWN0bHkgaW5jcmVtZW50IGV2ZW50LT5jb3VudCBhbmQga2VlcCBhIHNlY29uZCB2YWx1ZSBpbgogKiBldmVudC0+aHcucGVyaW9kX2xlZnQgdG8gY291bnQgaW50ZXJ2YWxzLiBUaGlzIHBlcmlvZCBldmVudAogKiBpcyBrZXB0IGluIHRoZSByYW5nZSBbLXNhbXBsZV9wZXJpb2QsIDBdIHNvIHRoYXQgd2UgY2FuIHVzZSB0aGUKICogc2lnbiBhcyB0cmlnZ2VyLgogKi8KCnN0YXRpYyB1NjQgcGVyZl9zd2V2ZW50X3NldF9wZXJpb2Qoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglzdHJ1Y3QgaHdfcGVyZl9ldmVudCAqaHdjID0gJmV2ZW50LT5odzsKCXU2NCBwZXJpb2QgPSBod2MtPmxhc3RfcGVyaW9kOwoJdTY0IG5yLCBvZmZzZXQ7CglzNjQgb2xkLCB2YWw7CgoJaHdjLT5sYXN0X3BlcmlvZCA9IGh3Yy0+c2FtcGxlX3BlcmlvZDsKCmFnYWluOgoJb2xkID0gdmFsID0gbG9jYWw2NF9yZWFkKCZod2MtPnBlcmlvZF9sZWZ0KTsKCWlmICh2YWwgPCAwKQoJCXJldHVybiAwOwoKCW5yID0gZGl2NjRfdTY0KHBlcmlvZCArIHZhbCwgcGVyaW9kKTsKCW9mZnNldCA9IG5yICogcGVyaW9kOwoJdmFsIC09IG9mZnNldDsKCWlmIChsb2NhbDY0X2NtcHhjaGcoJmh3Yy0+cGVyaW9kX2xlZnQsIG9sZCwgdmFsKSAhPSBvbGQpCgkJZ290byBhZ2FpbjsKCglyZXR1cm4gbnI7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfc3dldmVudF9vdmVyZmxvdyhzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIHU2NCBvdmVyZmxvdywKCQkJCSAgICBpbnQgbm1pLCBzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YSwKCQkJCSAgICBzdHJ1Y3QgcHRfcmVncyAqcmVncykKewoJc3RydWN0IGh3X3BlcmZfZXZlbnQgKmh3YyA9ICZldmVudC0+aHc7CglpbnQgdGhyb3R0bGUgPSAwOwoKCWRhdGEtPnBlcmlvZCA9IGV2ZW50LT5ody5sYXN0X3BlcmlvZDsKCWlmICghb3ZlcmZsb3cpCgkJb3ZlcmZsb3cgPSBwZXJmX3N3ZXZlbnRfc2V0X3BlcmlvZChldmVudCk7CgoJaWYgKGh3Yy0+aW50ZXJydXB0cyA9PSBNQVhfSU5URVJSVVBUUykKCQlyZXR1cm47CgoJZm9yICg7IG92ZXJmbG93OyBvdmVyZmxvdy0tKSB7CgkJaWYgKF9fcGVyZl9ldmVudF9vdmVyZmxvdyhldmVudCwgbm1pLCB0aHJvdHRsZSwKCQkJCQkgICAgZGF0YSwgcmVncykpIHsKCQkJLyoKCQkJICogV2UgaW5oaWJpdCB0aGUgb3ZlcmZsb3cgZnJvbSBoYXBwZW5pbmcgd2hlbgoJCQkgKiBod2MtPmludGVycnVwdHMgPT0gTUFYX0lOVEVSUlVQVFMuCgkJCSAqLwoJCQlicmVhazsKCQl9CgkJdGhyb3R0bGUgPSAxOwoJfQp9CgpzdGF0aWMgdm9pZCBwZXJmX3N3ZXZlbnRfZXZlbnQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCB1NjQgbnIsCgkJCSAgICAgICBpbnQgbm1pLCBzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YSwKCQkJICAgICAgIHN0cnVjdCBwdF9yZWdzICpyZWdzKQp7CglzdHJ1Y3QgaHdfcGVyZl9ldmVudCAqaHdjID0gJmV2ZW50LT5odzsKCglsb2NhbDY0X2FkZChuciwgJmV2ZW50LT5jb3VudCk7CgoJaWYgKCFyZWdzKQoJCXJldHVybjsKCglpZiAoIWlzX3NhbXBsaW5nX2V2ZW50KGV2ZW50KSkKCQlyZXR1cm47CgoJaWYgKG5yID09IDEgJiYgaHdjLT5zYW1wbGVfcGVyaW9kID09IDEgJiYgIWV2ZW50LT5hdHRyLmZyZXEpCgkJcmV0dXJuIHBlcmZfc3dldmVudF9vdmVyZmxvdyhldmVudCwgMSwgbm1pLCBkYXRhLCByZWdzKTsKCglpZiAobG9jYWw2NF9hZGRfbmVnYXRpdmUobnIsICZod2MtPnBlcmlvZF9sZWZ0KSkKCQlyZXR1cm47CgoJcGVyZl9zd2V2ZW50X292ZXJmbG93KGV2ZW50LCAwLCBubWksIGRhdGEsIHJlZ3MpOwp9CgpzdGF0aWMgaW50IHBlcmZfZXhjbHVkZV9ldmVudChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCSAgICAgIHN0cnVjdCBwdF9yZWdzICpyZWdzKQp7CglpZiAoZXZlbnQtPmh3LnN0YXRlICYgUEVSRl9IRVNfU1RPUFBFRCkKCQlyZXR1cm4gMDsKCglpZiAocmVncykgewoJCWlmIChldmVudC0+YXR0ci5leGNsdWRlX3VzZXIgJiYgdXNlcl9tb2RlKHJlZ3MpKQoJCQlyZXR1cm4gMTsKCgkJaWYgKGV2ZW50LT5hdHRyLmV4Y2x1ZGVfa2VybmVsICYmICF1c2VyX21vZGUocmVncykpCgkJCXJldHVybiAxOwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHBlcmZfc3dldmVudF9tYXRjaChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCQllbnVtIHBlcmZfdHlwZV9pZCB0eXBlLAoJCQkJdTMyIGV2ZW50X2lkLAoJCQkJc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgKmRhdGEsCgkJCQlzdHJ1Y3QgcHRfcmVncyAqcmVncykKewoJaWYgKGV2ZW50LT5hdHRyLnR5cGUgIT0gdHlwZSkKCQlyZXR1cm4gMDsKCglpZiAoZXZlbnQtPmF0dHIuY29uZmlnICE9IGV2ZW50X2lkKQoJCXJldHVybiAwOwoKCWlmIChwZXJmX2V4Y2x1ZGVfZXZlbnQoZXZlbnQsIHJlZ3MpKQoJCXJldHVybiAwOwoKCXJldHVybiAxOwp9CgpzdGF0aWMgaW5saW5lIHU2NCBzd2V2ZW50X2hhc2godTY0IHR5cGUsIHUzMiBldmVudF9pZCkKewoJdTY0IHZhbCA9IGV2ZW50X2lkIHwgKHR5cGUgPDwgMzIpOwoKCXJldHVybiBoYXNoXzY0KHZhbCwgU1dFVkVOVF9ITElTVF9CSVRTKTsKfQoKc3RhdGljIGlubGluZSBzdHJ1Y3QgaGxpc3RfaGVhZCAqCl9fZmluZF9zd2V2ZW50X2hlYWQoc3RydWN0IHN3ZXZlbnRfaGxpc3QgKmhsaXN0LCB1NjQgdHlwZSwgdTMyIGV2ZW50X2lkKQp7Cgl1NjQgaGFzaCA9IHN3ZXZlbnRfaGFzaCh0eXBlLCBldmVudF9pZCk7CgoJcmV0dXJuICZobGlzdC0+aGVhZHNbaGFzaF07Cn0KCi8qIEZvciB0aGUgcmVhZCBzaWRlOiBldmVudHMgd2hlbiB0aGV5IHRyaWdnZXIgKi8Kc3RhdGljIGlubGluZSBzdHJ1Y3QgaGxpc3RfaGVhZCAqCmZpbmRfc3dldmVudF9oZWFkX3JjdShzdHJ1Y3Qgc3dldmVudF9odGFibGUgKnN3aGFzaCwgdTY0IHR5cGUsIHUzMiBldmVudF9pZCkKewoJc3RydWN0IHN3ZXZlbnRfaGxpc3QgKmhsaXN0OwoKCWhsaXN0ID0gcmN1X2RlcmVmZXJlbmNlKHN3aGFzaC0+c3dldmVudF9obGlzdCk7CglpZiAoIWhsaXN0KQoJCXJldHVybiBOVUxMOwoKCXJldHVybiBfX2ZpbmRfc3dldmVudF9oZWFkKGhsaXN0LCB0eXBlLCBldmVudF9pZCk7Cn0KCi8qIEZvciB0aGUgZXZlbnQgaGVhZCBpbnNlcnRpb24gYW5kIHJlbW92YWwgaW4gdGhlIGhsaXN0ICovCnN0YXRpYyBpbmxpbmUgc3RydWN0IGhsaXN0X2hlYWQgKgpmaW5kX3N3ZXZlbnRfaGVhZChzdHJ1Y3Qgc3dldmVudF9odGFibGUgKnN3aGFzaCwgc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglzdHJ1Y3Qgc3dldmVudF9obGlzdCAqaGxpc3Q7Cgl1MzIgZXZlbnRfaWQgPSBldmVudC0+YXR0ci5jb25maWc7Cgl1NjQgdHlwZSA9IGV2ZW50LT5hdHRyLnR5cGU7CgoJLyoKCSAqIEV2ZW50IHNjaGVkdWxpbmcgaXMgYWx3YXlzIHNlcmlhbGl6ZWQgYWdhaW5zdCBobGlzdCBhbGxvY2F0aW9uCgkgKiBhbmQgcmVsZWFzZS4gV2hpY2ggbWFrZXMgdGhlIHByb3RlY3RlZCB2ZXJzaW9uIHN1aXRhYmxlIGhlcmUuCgkgKiBUaGUgY29udGV4dCBsb2NrIGd1YXJhbnRlZXMgdGhhdC4KCSAqLwoJaGxpc3QgPSByY3VfZGVyZWZlcmVuY2VfcHJvdGVjdGVkKHN3aGFzaC0+c3dldmVudF9obGlzdCwKCQkJCQkgIGxvY2tkZXBfaXNfaGVsZCgmZXZlbnQtPmN0eC0+bG9jaykpOwoJaWYgKCFobGlzdCkKCQlyZXR1cm4gTlVMTDsKCglyZXR1cm4gX19maW5kX3N3ZXZlbnRfaGVhZChobGlzdCwgdHlwZSwgZXZlbnRfaWQpOwp9CgpzdGF0aWMgdm9pZCBkb19wZXJmX3N3X2V2ZW50KGVudW0gcGVyZl90eXBlX2lkIHR5cGUsIHUzMiBldmVudF9pZCwKCQkJCSAgICB1NjQgbnIsIGludCBubWksCgkJCQkgICAgc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgKmRhdGEsCgkJCQkgICAgc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKCXN0cnVjdCBzd2V2ZW50X2h0YWJsZSAqc3doYXNoID0gJl9fZ2V0X2NwdV92YXIoc3dldmVudF9odGFibGUpOwoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoJc3RydWN0IGhsaXN0X25vZGUgKm5vZGU7CglzdHJ1Y3QgaGxpc3RfaGVhZCAqaGVhZDsKCglyY3VfcmVhZF9sb2NrKCk7CgloZWFkID0gZmluZF9zd2V2ZW50X2hlYWRfcmN1KHN3aGFzaCwgdHlwZSwgZXZlbnRfaWQpOwoJaWYgKCFoZWFkKQoJCWdvdG8gZW5kOwoKCWhsaXN0X2Zvcl9lYWNoX2VudHJ5X3JjdShldmVudCwgbm9kZSwgaGVhZCwgaGxpc3RfZW50cnkpIHsKCQlpZiAocGVyZl9zd2V2ZW50X21hdGNoKGV2ZW50LCB0eXBlLCBldmVudF9pZCwgZGF0YSwgcmVncykpCgkJCXBlcmZfc3dldmVudF9ldmVudChldmVudCwgbnIsIG5taSwgZGF0YSwgcmVncyk7Cgl9CmVuZDoKCXJjdV9yZWFkX3VubG9jaygpOwp9CgppbnQgcGVyZl9zd2V2ZW50X2dldF9yZWN1cnNpb25fY29udGV4dCh2b2lkKQp7CglzdHJ1Y3Qgc3dldmVudF9odGFibGUgKnN3aGFzaCA9ICZfX2dldF9jcHVfdmFyKHN3ZXZlbnRfaHRhYmxlKTsKCglyZXR1cm4gZ2V0X3JlY3Vyc2lvbl9jb250ZXh0KHN3aGFzaC0+cmVjdXJzaW9uKTsKfQpFWFBPUlRfU1lNQk9MX0dQTChwZXJmX3N3ZXZlbnRfZ2V0X3JlY3Vyc2lvbl9jb250ZXh0KTsKCmlubGluZSB2b2lkIHBlcmZfc3dldmVudF9wdXRfcmVjdXJzaW9uX2NvbnRleHQoaW50IHJjdHgpCnsKCXN0cnVjdCBzd2V2ZW50X2h0YWJsZSAqc3doYXNoID0gJl9fZ2V0X2NwdV92YXIoc3dldmVudF9odGFibGUpOwoKCXB1dF9yZWN1cnNpb25fY29udGV4dChzd2hhc2gtPnJlY3Vyc2lvbiwgcmN0eCk7Cn0KCnZvaWQgX19wZXJmX3N3X2V2ZW50KHUzMiBldmVudF9pZCwgdTY0IG5yLCBpbnQgbm1pLAoJCQkgICAgc3RydWN0IHB0X3JlZ3MgKnJlZ3MsIHU2NCBhZGRyKQp7CglzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSBkYXRhOwoJaW50IHJjdHg7CgoJcHJlZW1wdF9kaXNhYmxlX25vdHJhY2UoKTsKCXJjdHggPSBwZXJmX3N3ZXZlbnRfZ2V0X3JlY3Vyc2lvbl9jb250ZXh0KCk7CglpZiAocmN0eCA8IDApCgkJcmV0dXJuOwoKCXBlcmZfc2FtcGxlX2RhdGFfaW5pdCgmZGF0YSwgYWRkcik7CgoJZG9fcGVyZl9zd19ldmVudChQRVJGX1RZUEVfU09GVFdBUkUsIGV2ZW50X2lkLCBuciwgbm1pLCAmZGF0YSwgcmVncyk7CgoJcGVyZl9zd2V2ZW50X3B1dF9yZWN1cnNpb25fY29udGV4dChyY3R4KTsKCXByZWVtcHRfZW5hYmxlX25vdHJhY2UoKTsKfQoKc3RhdGljIHZvaWQgcGVyZl9zd2V2ZW50X3JlYWQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7Cn0KCnN0YXRpYyBpbnQgcGVyZl9zd2V2ZW50X2FkZChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIGludCBmbGFncykKewoJc3RydWN0IHN3ZXZlbnRfaHRhYmxlICpzd2hhc2ggPSAmX19nZXRfY3B1X3Zhcihzd2V2ZW50X2h0YWJsZSk7CglzdHJ1Y3QgaHdfcGVyZl9ldmVudCAqaHdjID0gJmV2ZW50LT5odzsKCXN0cnVjdCBobGlzdF9oZWFkICpoZWFkOwoKCWlmIChpc19zYW1wbGluZ19ldmVudChldmVudCkpIHsKCQlod2MtPmxhc3RfcGVyaW9kID0gaHdjLT5zYW1wbGVfcGVyaW9kOwoJCXBlcmZfc3dldmVudF9zZXRfcGVyaW9kKGV2ZW50KTsKCX0KCglod2MtPnN0YXRlID0gIShmbGFncyAmIFBFUkZfRUZfU1RBUlQpOwoKCWhlYWQgPSBmaW5kX3N3ZXZlbnRfaGVhZChzd2hhc2gsIGV2ZW50KTsKCWlmIChXQVJOX09OX09OQ0UoIWhlYWQpKQoJCXJldHVybiAtRUlOVkFMOwoKCWhsaXN0X2FkZF9oZWFkX3JjdSgmZXZlbnQtPmhsaXN0X2VudHJ5LCBoZWFkKTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgcGVyZl9zd2V2ZW50X2RlbChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIGludCBmbGFncykKewoJaGxpc3RfZGVsX3JjdSgmZXZlbnQtPmhsaXN0X2VudHJ5KTsKfQoKc3RhdGljIHZvaWQgcGVyZl9zd2V2ZW50X3N0YXJ0KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgaW50IGZsYWdzKQp7CglldmVudC0+aHcuc3RhdGUgPSAwOwp9CgpzdGF0aWMgdm9pZCBwZXJmX3N3ZXZlbnRfc3RvcChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIGludCBmbGFncykKewoJZXZlbnQtPmh3LnN0YXRlID0gUEVSRl9IRVNfU1RPUFBFRDsKfQoKLyogRGVyZWYgdGhlIGhsaXN0IGZyb20gdGhlIHVwZGF0ZSBzaWRlICovCnN0YXRpYyBpbmxpbmUgc3RydWN0IHN3ZXZlbnRfaGxpc3QgKgpzd2V2ZW50X2hsaXN0X2RlcmVmKHN0cnVjdCBzd2V2ZW50X2h0YWJsZSAqc3doYXNoKQp7CglyZXR1cm4gcmN1X2RlcmVmZXJlbmNlX3Byb3RlY3RlZChzd2hhc2gtPnN3ZXZlbnRfaGxpc3QsCgkJCQkJIGxvY2tkZXBfaXNfaGVsZCgmc3doYXNoLT5obGlzdF9tdXRleCkpOwp9CgpzdGF0aWMgdm9pZCBzd2V2ZW50X2hsaXN0X3JlbGVhc2VfcmN1KHN0cnVjdCByY3VfaGVhZCAqcmN1X2hlYWQpCnsKCXN0cnVjdCBzd2V2ZW50X2hsaXN0ICpobGlzdDsKCglobGlzdCA9IGNvbnRhaW5lcl9vZihyY3VfaGVhZCwgc3RydWN0IHN3ZXZlbnRfaGxpc3QsIHJjdV9oZWFkKTsKCWtmcmVlKGhsaXN0KTsKfQoKc3RhdGljIHZvaWQgc3dldmVudF9obGlzdF9yZWxlYXNlKHN0cnVjdCBzd2V2ZW50X2h0YWJsZSAqc3doYXNoKQp7CglzdHJ1Y3Qgc3dldmVudF9obGlzdCAqaGxpc3QgPSBzd2V2ZW50X2hsaXN0X2RlcmVmKHN3aGFzaCk7CgoJaWYgKCFobGlzdCkKCQlyZXR1cm47CgoJcmN1X2Fzc2lnbl9wb2ludGVyKHN3aGFzaC0+c3dldmVudF9obGlzdCwgTlVMTCk7CgljYWxsX3JjdSgmaGxpc3QtPnJjdV9oZWFkLCBzd2V2ZW50X2hsaXN0X3JlbGVhc2VfcmN1KTsKfQoKc3RhdGljIHZvaWQgc3dldmVudF9obGlzdF9wdXRfY3B1KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgaW50IGNwdSkKewoJc3RydWN0IHN3ZXZlbnRfaHRhYmxlICpzd2hhc2ggPSAmcGVyX2NwdShzd2V2ZW50X2h0YWJsZSwgY3B1KTsKCgltdXRleF9sb2NrKCZzd2hhc2gtPmhsaXN0X211dGV4KTsKCglpZiAoIS0tc3doYXNoLT5obGlzdF9yZWZjb3VudCkKCQlzd2V2ZW50X2hsaXN0X3JlbGVhc2Uoc3doYXNoKTsKCgltdXRleF91bmxvY2soJnN3aGFzaC0+aGxpc3RfbXV0ZXgpOwp9CgpzdGF0aWMgdm9pZCBzd2V2ZW50X2hsaXN0X3B1dChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCWludCBjcHU7CgoJaWYgKGV2ZW50LT5jcHUgIT0gLTEpIHsKCQlzd2V2ZW50X2hsaXN0X3B1dF9jcHUoZXZlbnQsIGV2ZW50LT5jcHUpOwoJCXJldHVybjsKCX0KCglmb3JfZWFjaF9wb3NzaWJsZV9jcHUoY3B1KQoJCXN3ZXZlbnRfaGxpc3RfcHV0X2NwdShldmVudCwgY3B1KTsKfQoKc3RhdGljIGludCBzd2V2ZW50X2hsaXN0X2dldF9jcHUoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBpbnQgY3B1KQp7CglzdHJ1Y3Qgc3dldmVudF9odGFibGUgKnN3aGFzaCA9ICZwZXJfY3B1KHN3ZXZlbnRfaHRhYmxlLCBjcHUpOwoJaW50IGVyciA9IDA7CgoJbXV0ZXhfbG9jaygmc3doYXNoLT5obGlzdF9tdXRleCk7CgoJaWYgKCFzd2V2ZW50X2hsaXN0X2RlcmVmKHN3aGFzaCkgJiYgY3B1X29ubGluZShjcHUpKSB7CgkJc3RydWN0IHN3ZXZlbnRfaGxpc3QgKmhsaXN0OwoKCQlobGlzdCA9IGt6YWxsb2Moc2l6ZW9mKCpobGlzdCksIEdGUF9LRVJORUwpOwoJCWlmICghaGxpc3QpIHsKCQkJZXJyID0gLUVOT01FTTsKCQkJZ290byBleGl0OwoJCX0KCQlyY3VfYXNzaWduX3BvaW50ZXIoc3doYXNoLT5zd2V2ZW50X2hsaXN0LCBobGlzdCk7Cgl9Cglzd2hhc2gtPmhsaXN0X3JlZmNvdW50Kys7CmV4aXQ6CgltdXRleF91bmxvY2soJnN3aGFzaC0+aGxpc3RfbXV0ZXgpOwoKCXJldHVybiBlcnI7Cn0KCnN0YXRpYyBpbnQgc3dldmVudF9obGlzdF9nZXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglpbnQgZXJyOwoJaW50IGNwdSwgZmFpbGVkX2NwdTsKCglpZiAoZXZlbnQtPmNwdSAhPSAtMSkKCQlyZXR1cm4gc3dldmVudF9obGlzdF9nZXRfY3B1KGV2ZW50LCBldmVudC0+Y3B1KTsKCglnZXRfb25saW5lX2NwdXMoKTsKCWZvcl9lYWNoX3Bvc3NpYmxlX2NwdShjcHUpIHsKCQllcnIgPSBzd2V2ZW50X2hsaXN0X2dldF9jcHUoZXZlbnQsIGNwdSk7CgkJaWYgKGVycikgewoJCQlmYWlsZWRfY3B1ID0gY3B1OwoJCQlnb3RvIGZhaWw7CgkJfQoJfQoJcHV0X29ubGluZV9jcHVzKCk7CgoJcmV0dXJuIDA7CmZhaWw6Cglmb3JfZWFjaF9wb3NzaWJsZV9jcHUoY3B1KSB7CgkJaWYgKGNwdSA9PSBmYWlsZWRfY3B1KQoJCQlicmVhazsKCQlzd2V2ZW50X2hsaXN0X3B1dF9jcHUoZXZlbnQsIGNwdSk7Cgl9CgoJcHV0X29ubGluZV9jcHVzKCk7CglyZXR1cm4gZXJyOwp9CgphdG9taWNfdCBwZXJmX3N3ZXZlbnRfZW5hYmxlZFtQRVJGX0NPVU5UX1NXX01BWF07CgpzdGF0aWMgdm9pZCBzd19wZXJmX2V2ZW50X2Rlc3Ryb3koc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7Cgl1NjQgZXZlbnRfaWQgPSBldmVudC0+YXR0ci5jb25maWc7CgoJV0FSTl9PTihldmVudC0+cGFyZW50KTsKCglqdW1wX2xhYmVsX2RlYygmcGVyZl9zd2V2ZW50X2VuYWJsZWRbZXZlbnRfaWRdKTsKCXN3ZXZlbnRfaGxpc3RfcHV0KGV2ZW50KTsKfQoKc3RhdGljIGludCBwZXJmX3N3ZXZlbnRfaW5pdChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCWludCBldmVudF9pZCA9IGV2ZW50LT5hdHRyLmNvbmZpZzsKCglpZiAoZXZlbnQtPmF0dHIudHlwZSAhPSBQRVJGX1RZUEVfU09GVFdBUkUpCgkJcmV0dXJuIC1FTk9FTlQ7CgoJc3dpdGNoIChldmVudF9pZCkgewoJY2FzZSBQRVJGX0NPVU5UX1NXX0NQVV9DTE9DSzoKCWNhc2UgUEVSRl9DT1VOVF9TV19UQVNLX0NMT0NLOgoJCXJldHVybiAtRU5PRU5UOwoKCWRlZmF1bHQ6CgkJYnJlYWs7Cgl9CgoJaWYgKGV2ZW50X2lkID49IFBFUkZfQ09VTlRfU1dfTUFYKQoJCXJldHVybiAtRU5PRU5UOwoKCWlmICghZXZlbnQtPnBhcmVudCkgewoJCWludCBlcnI7CgoJCWVyciA9IHN3ZXZlbnRfaGxpc3RfZ2V0KGV2ZW50KTsKCQlpZiAoZXJyKQoJCQlyZXR1cm4gZXJyOwoKCQlqdW1wX2xhYmVsX2luYygmcGVyZl9zd2V2ZW50X2VuYWJsZWRbZXZlbnRfaWRdKTsKCQlldmVudC0+ZGVzdHJveSA9IHN3X3BlcmZfZXZlbnRfZGVzdHJveTsKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIHN0cnVjdCBwbXUgcGVyZl9zd2V2ZW50ID0gewoJLnRhc2tfY3R4X25yCT0gcGVyZl9zd19jb250ZXh0LAoKCS5ldmVudF9pbml0CT0gcGVyZl9zd2V2ZW50X2luaXQsCgkuYWRkCQk9IHBlcmZfc3dldmVudF9hZGQsCgkuZGVsCQk9IHBlcmZfc3dldmVudF9kZWwsCgkuc3RhcnQJCT0gcGVyZl9zd2V2ZW50X3N0YXJ0LAoJLnN0b3AJCT0gcGVyZl9zd2V2ZW50X3N0b3AsCgkucmVhZAkJPSBwZXJmX3N3ZXZlbnRfcmVhZCwKfTsKCiNpZmRlZiBDT05GSUdfRVZFTlRfVFJBQ0lORwoKc3RhdGljIGludCBwZXJmX3RwX2ZpbHRlcl9tYXRjaChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCQlzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YSkKewoJdm9pZCAqcmVjb3JkID0gZGF0YS0+cmF3LT5kYXRhOwoKCWlmIChsaWtlbHkoIWV2ZW50LT5maWx0ZXIpIHx8IGZpbHRlcl9tYXRjaF9wcmVkcyhldmVudC0+ZmlsdGVyLCByZWNvcmQpKQoJCXJldHVybiAxOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcGVyZl90cF9ldmVudF9tYXRjaChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCQlzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YSwKCQkJCXN0cnVjdCBwdF9yZWdzICpyZWdzKQp7CgkvKgoJICogQWxsIHRyYWNlcG9pbnRzIGFyZSBmcm9tIGtlcm5lbC1zcGFjZS4KCSAqLwoJaWYgKGV2ZW50LT5hdHRyLmV4Y2x1ZGVfa2VybmVsKQoJCXJldHVybiAwOwoKCWlmICghcGVyZl90cF9maWx0ZXJfbWF0Y2goZXZlbnQsIGRhdGEpKQoJCXJldHVybiAwOwoKCXJldHVybiAxOwp9Cgp2b2lkIHBlcmZfdHBfZXZlbnQodTY0IGFkZHIsIHU2NCBjb3VudCwgdm9pZCAqcmVjb3JkLCBpbnQgZW50cnlfc2l6ZSwKCQkgICBzdHJ1Y3QgcHRfcmVncyAqcmVncywgc3RydWN0IGhsaXN0X2hlYWQgKmhlYWQsIGludCByY3R4KQp7CglzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSBkYXRhOwoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoJc3RydWN0IGhsaXN0X25vZGUgKm5vZGU7CgoJc3RydWN0IHBlcmZfcmF3X3JlY29yZCByYXcgPSB7CgkJLnNpemUgPSBlbnRyeV9zaXplLAoJCS5kYXRhID0gcmVjb3JkLAoJfTsKCglwZXJmX3NhbXBsZV9kYXRhX2luaXQoJmRhdGEsIGFkZHIpOwoJZGF0YS5yYXcgPSAmcmF3OwoKCWhsaXN0X2Zvcl9lYWNoX2VudHJ5X3JjdShldmVudCwgbm9kZSwgaGVhZCwgaGxpc3RfZW50cnkpIHsKCQlpZiAocGVyZl90cF9ldmVudF9tYXRjaChldmVudCwgJmRhdGEsIHJlZ3MpKQoJCQlwZXJmX3N3ZXZlbnRfZXZlbnQoZXZlbnQsIGNvdW50LCAxLCAmZGF0YSwgcmVncyk7Cgl9CgoJcGVyZl9zd2V2ZW50X3B1dF9yZWN1cnNpb25fY29udGV4dChyY3R4KTsKfQpFWFBPUlRfU1lNQk9MX0dQTChwZXJmX3RwX2V2ZW50KTsKCnN0YXRpYyB2b2lkIHRwX3BlcmZfZXZlbnRfZGVzdHJveShzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXBlcmZfdHJhY2VfZGVzdHJveShldmVudCk7Cn0KCnN0YXRpYyBpbnQgcGVyZl90cF9ldmVudF9pbml0KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJaW50IGVycjsKCglpZiAoZXZlbnQtPmF0dHIudHlwZSAhPSBQRVJGX1RZUEVfVFJBQ0VQT0lOVCkKCQlyZXR1cm4gLUVOT0VOVDsKCgllcnIgPSBwZXJmX3RyYWNlX2luaXQoZXZlbnQpOwoJaWYgKGVycikKCQlyZXR1cm4gZXJyOwoKCWV2ZW50LT5kZXN0cm95ID0gdHBfcGVyZl9ldmVudF9kZXN0cm95OwoKCXJldHVybiAwOwp9CgpzdGF0aWMgc3RydWN0IHBtdSBwZXJmX3RyYWNlcG9pbnQgPSB7CgkudGFza19jdHhfbnIJPSBwZXJmX3N3X2NvbnRleHQsCgoJLmV2ZW50X2luaXQJPSBwZXJmX3RwX2V2ZW50X2luaXQsCgkuYWRkCQk9IHBlcmZfdHJhY2VfYWRkLAoJLmRlbAkJPSBwZXJmX3RyYWNlX2RlbCwKCS5zdGFydAkJPSBwZXJmX3N3ZXZlbnRfc3RhcnQsCgkuc3RvcAkJPSBwZXJmX3N3ZXZlbnRfc3RvcCwKCS5yZWFkCQk9IHBlcmZfc3dldmVudF9yZWFkLAp9OwoKc3RhdGljIGlubGluZSB2b2lkIHBlcmZfdHBfcmVnaXN0ZXIodm9pZCkKewoJcGVyZl9wbXVfcmVnaXN0ZXIoJnBlcmZfdHJhY2Vwb2ludCwgInRyYWNlcG9pbnQiLCBQRVJGX1RZUEVfVFJBQ0VQT0lOVCk7Cn0KCnN0YXRpYyBpbnQgcGVyZl9ldmVudF9zZXRfZmlsdGVyKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgdm9pZCBfX3VzZXIgKmFyZykKewoJY2hhciAqZmlsdGVyX3N0cjsKCWludCByZXQ7CgoJaWYgKGV2ZW50LT5hdHRyLnR5cGUgIT0gUEVSRl9UWVBFX1RSQUNFUE9JTlQpCgkJcmV0dXJuIC1FSU5WQUw7CgoJZmlsdGVyX3N0ciA9IHN0cm5kdXBfdXNlcihhcmcsIFBBR0VfU0laRSk7CglpZiAoSVNfRVJSKGZpbHRlcl9zdHIpKQoJCXJldHVybiBQVFJfRVJSKGZpbHRlcl9zdHIpOwoKCXJldCA9IGZ0cmFjZV9wcm9maWxlX3NldF9maWx0ZXIoZXZlbnQsIGV2ZW50LT5hdHRyLmNvbmZpZywgZmlsdGVyX3N0cik7CgoJa2ZyZWUoZmlsdGVyX3N0cik7CglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X2ZyZWVfZmlsdGVyKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJZnRyYWNlX3Byb2ZpbGVfZnJlZV9maWx0ZXIoZXZlbnQpOwp9CgojZWxzZQoKc3RhdGljIGlubGluZSB2b2lkIHBlcmZfdHBfcmVnaXN0ZXIodm9pZCkKewp9CgpzdGF0aWMgaW50IHBlcmZfZXZlbnRfc2V0X2ZpbHRlcihzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIHZvaWQgX191c2VyICphcmcpCnsKCXJldHVybiAtRU5PRU5UOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X2ZyZWVfZmlsdGVyKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewp9CgojZW5kaWYgLyogQ09ORklHX0VWRU5UX1RSQUNJTkcgKi8KCiNpZmRlZiBDT05GSUdfSEFWRV9IV19CUkVBS1BPSU5UCnZvaWQgcGVyZl9icF9ldmVudChzdHJ1Y3QgcGVyZl9ldmVudCAqYnAsIHZvaWQgKmRhdGEpCnsKCXN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhIHNhbXBsZTsKCXN0cnVjdCBwdF9yZWdzICpyZWdzID0gZGF0YTsKCglwZXJmX3NhbXBsZV9kYXRhX2luaXQoJnNhbXBsZSwgYnAtPmF0dHIuYnBfYWRkcik7CgoJaWYgKCFicC0+aHcuc3RhdGUgJiYgIXBlcmZfZXhjbHVkZV9ldmVudChicCwgcmVncykpCgkJcGVyZl9zd2V2ZW50X2V2ZW50KGJwLCAxLCAxLCAmc2FtcGxlLCByZWdzKTsKfQojZW5kaWYKCi8qCiAqIGhydGltZXIgYmFzZWQgc3dldmVudCBjYWxsYmFjawogKi8KCnN0YXRpYyBlbnVtIGhydGltZXJfcmVzdGFydCBwZXJmX3N3ZXZlbnRfaHJ0aW1lcihzdHJ1Y3QgaHJ0aW1lciAqaHJ0aW1lcikKewoJZW51bSBocnRpbWVyX3Jlc3RhcnQgcmV0ID0gSFJUSU1FUl9SRVNUQVJUOwoJc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgZGF0YTsKCXN0cnVjdCBwdF9yZWdzICpyZWdzOwoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoJdTY0IHBlcmlvZDsKCglldmVudCA9IGNvbnRhaW5lcl9vZihocnRpbWVyLCBzdHJ1Y3QgcGVyZl9ldmVudCwgaHcuaHJ0aW1lcik7CglldmVudC0+cG11LT5yZWFkKGV2ZW50KTsKCglwZXJmX3NhbXBsZV9kYXRhX2luaXQoJmRhdGEsIDApOwoJZGF0YS5wZXJpb2QgPSBldmVudC0+aHcubGFzdF9wZXJpb2Q7CglyZWdzID0gZ2V0X2lycV9yZWdzKCk7CgoJaWYgKHJlZ3MgJiYgIXBlcmZfZXhjbHVkZV9ldmVudChldmVudCwgcmVncykpIHsKCQlpZiAoIShldmVudC0+YXR0ci5leGNsdWRlX2lkbGUgJiYgY3VycmVudC0+cGlkID09IDApKQoJCQlpZiAocGVyZl9ldmVudF9vdmVyZmxvdyhldmVudCwgMCwgJmRhdGEsIHJlZ3MpKQoJCQkJcmV0ID0gSFJUSU1FUl9OT1JFU1RBUlQ7Cgl9CgoJcGVyaW9kID0gbWF4X3QodTY0LCAxMDAwMCwgZXZlbnQtPmh3LnNhbXBsZV9wZXJpb2QpOwoJaHJ0aW1lcl9mb3J3YXJkX25vdyhocnRpbWVyLCBuc190b19rdGltZShwZXJpb2QpKTsKCglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgdm9pZCBwZXJmX3N3ZXZlbnRfc3RhcnRfaHJ0aW1lcihzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXN0cnVjdCBod19wZXJmX2V2ZW50ICpod2MgPSAmZXZlbnQtPmh3OwoJczY0IHBlcmlvZDsKCglpZiAoIWlzX3NhbXBsaW5nX2V2ZW50KGV2ZW50KSkKCQlyZXR1cm47CgoJaHJ0aW1lcl9pbml0KCZod2MtPmhydGltZXIsIENMT0NLX01PTk9UT05JQywgSFJUSU1FUl9NT0RFX1JFTCk7Cglod2MtPmhydGltZXIuZnVuY3Rpb24gPSBwZXJmX3N3ZXZlbnRfaHJ0aW1lcjsKCglwZXJpb2QgPSBsb2NhbDY0X3JlYWQoJmh3Yy0+cGVyaW9kX2xlZnQpOwoJaWYgKHBlcmlvZCkgewoJCWlmIChwZXJpb2QgPCAwKQoJCQlwZXJpb2QgPSAxMDAwMDsKCgkJbG9jYWw2NF9zZXQoJmh3Yy0+cGVyaW9kX2xlZnQsIDApOwoJfSBlbHNlIHsKCQlwZXJpb2QgPSBtYXhfdCh1NjQsIDEwMDAwLCBod2MtPnNhbXBsZV9wZXJpb2QpOwoJfQoJX19ocnRpbWVyX3N0YXJ0X3JhbmdlX25zKCZod2MtPmhydGltZXIsCgkJCQluc190b19rdGltZShwZXJpb2QpLCAwLAoJCQkJSFJUSU1FUl9NT0RFX1JFTF9QSU5ORUQsIDApOwp9CgpzdGF0aWMgdm9pZCBwZXJmX3N3ZXZlbnRfY2FuY2VsX2hydGltZXIoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglzdHJ1Y3QgaHdfcGVyZl9ldmVudCAqaHdjID0gJmV2ZW50LT5odzsKCglpZiAoaXNfc2FtcGxpbmdfZXZlbnQoZXZlbnQpKSB7CgkJa3RpbWVfdCByZW1haW5pbmcgPSBocnRpbWVyX2dldF9yZW1haW5pbmcoJmh3Yy0+aHJ0aW1lcik7CgkJbG9jYWw2NF9zZXQoJmh3Yy0+cGVyaW9kX2xlZnQsIGt0aW1lX3RvX25zKHJlbWFpbmluZykpOwoKCQlocnRpbWVyX2NhbmNlbCgmaHdjLT5ocnRpbWVyKTsKCX0KfQoKLyoKICogU29mdHdhcmUgZXZlbnQ6IGNwdSB3YWxsIHRpbWUgY2xvY2sKICovCgpzdGF0aWMgdm9pZCBjcHVfY2xvY2tfZXZlbnRfdXBkYXRlKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJczY0IHByZXY7Cgl1NjQgbm93OwoKCW5vdyA9IGxvY2FsX2Nsb2NrKCk7CglwcmV2ID0gbG9jYWw2NF94Y2hnKCZldmVudC0+aHcucHJldl9jb3VudCwgbm93KTsKCWxvY2FsNjRfYWRkKG5vdyAtIHByZXYsICZldmVudC0+Y291bnQpOwp9CgpzdGF0aWMgdm9pZCBjcHVfY2xvY2tfZXZlbnRfc3RhcnQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBpbnQgZmxhZ3MpCnsKCWxvY2FsNjRfc2V0KCZldmVudC0+aHcucHJldl9jb3VudCwgbG9jYWxfY2xvY2soKSk7CglwZXJmX3N3ZXZlbnRfc3RhcnRfaHJ0aW1lcihldmVudCk7Cn0KCnN0YXRpYyB2b2lkIGNwdV9jbG9ja19ldmVudF9zdG9wKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgaW50IGZsYWdzKQp7CglwZXJmX3N3ZXZlbnRfY2FuY2VsX2hydGltZXIoZXZlbnQpOwoJY3B1X2Nsb2NrX2V2ZW50X3VwZGF0ZShldmVudCk7Cn0KCnN0YXRpYyBpbnQgY3B1X2Nsb2NrX2V2ZW50X2FkZChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIGludCBmbGFncykKewoJaWYgKGZsYWdzICYgUEVSRl9FRl9TVEFSVCkKCQljcHVfY2xvY2tfZXZlbnRfc3RhcnQoZXZlbnQsIGZsYWdzKTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgY3B1X2Nsb2NrX2V2ZW50X2RlbChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIGludCBmbGFncykKewoJY3B1X2Nsb2NrX2V2ZW50X3N0b3AoZXZlbnQsIGZsYWdzKTsKfQoKc3RhdGljIHZvaWQgY3B1X2Nsb2NrX2V2ZW50X3JlYWQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CgljcHVfY2xvY2tfZXZlbnRfdXBkYXRlKGV2ZW50KTsKfQoKc3RhdGljIGludCBjcHVfY2xvY2tfZXZlbnRfaW5pdChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCWlmIChldmVudC0+YXR0ci50eXBlICE9IFBFUkZfVFlQRV9TT0ZUV0FSRSkKCQlyZXR1cm4gLUVOT0VOVDsKCglpZiAoZXZlbnQtPmF0dHIuY29uZmlnICE9IFBFUkZfQ09VTlRfU1dfQ1BVX0NMT0NLKQoJCXJldHVybiAtRU5PRU5UOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgc3RydWN0IHBtdSBwZXJmX2NwdV9jbG9jayA9IHsKCS50YXNrX2N0eF9ucgk9IHBlcmZfc3dfY29udGV4dCwKCgkuZXZlbnRfaW5pdAk9IGNwdV9jbG9ja19ldmVudF9pbml0LAoJLmFkZAkJPSBjcHVfY2xvY2tfZXZlbnRfYWRkLAoJLmRlbAkJPSBjcHVfY2xvY2tfZXZlbnRfZGVsLAoJLnN0YXJ0CQk9IGNwdV9jbG9ja19ldmVudF9zdGFydCwKCS5zdG9wCQk9IGNwdV9jbG9ja19ldmVudF9zdG9wLAoJLnJlYWQJCT0gY3B1X2Nsb2NrX2V2ZW50X3JlYWQsCn07CgovKgogKiBTb2Z0d2FyZSBldmVudDogdGFzayB0aW1lIGNsb2NrCiAqLwoKc3RhdGljIHZvaWQgdGFza19jbG9ja19ldmVudF91cGRhdGUoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCB1NjQgbm93KQp7Cgl1NjQgcHJldjsKCXM2NCBkZWx0YTsKCglwcmV2ID0gbG9jYWw2NF94Y2hnKCZldmVudC0+aHcucHJldl9jb3VudCwgbm93KTsKCWRlbHRhID0gbm93IC0gcHJldjsKCWxvY2FsNjRfYWRkKGRlbHRhLCAmZXZlbnQtPmNvdW50KTsKfQoKc3RhdGljIHZvaWQgdGFza19jbG9ja19ldmVudF9zdGFydChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIGludCBmbGFncykKewoJbG9jYWw2NF9zZXQoJmV2ZW50LT5ody5wcmV2X2NvdW50LCBldmVudC0+Y3R4LT50aW1lKTsKCXBlcmZfc3dldmVudF9zdGFydF9ocnRpbWVyKGV2ZW50KTsKfQoKc3RhdGljIHZvaWQgdGFza19jbG9ja19ldmVudF9zdG9wKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgaW50IGZsYWdzKQp7CglwZXJmX3N3ZXZlbnRfY2FuY2VsX2hydGltZXIoZXZlbnQpOwoJdGFza19jbG9ja19ldmVudF91cGRhdGUoZXZlbnQsIGV2ZW50LT5jdHgtPnRpbWUpOwp9CgpzdGF0aWMgaW50IHRhc2tfY2xvY2tfZXZlbnRfYWRkKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgaW50IGZsYWdzKQp7CglpZiAoZmxhZ3MgJiBQRVJGX0VGX1NUQVJUKQoJCXRhc2tfY2xvY2tfZXZlbnRfc3RhcnQoZXZlbnQsIGZsYWdzKTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgdGFza19jbG9ja19ldmVudF9kZWwoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBpbnQgZmxhZ3MpCnsKCXRhc2tfY2xvY2tfZXZlbnRfc3RvcChldmVudCwgUEVSRl9FRl9VUERBVEUpOwp9CgpzdGF0aWMgdm9pZCB0YXNrX2Nsb2NrX2V2ZW50X3JlYWQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7Cgl1NjQgdGltZTsKCglpZiAoIWluX25taSgpKSB7CgkJdXBkYXRlX2NvbnRleHRfdGltZShldmVudC0+Y3R4KTsKCQl0aW1lID0gZXZlbnQtPmN0eC0+dGltZTsKCX0gZWxzZSB7CgkJdTY0IG5vdyA9IHBlcmZfY2xvY2soKTsKCQl1NjQgZGVsdGEgPSBub3cgLSBldmVudC0+Y3R4LT50aW1lc3RhbXA7CgkJdGltZSA9IGV2ZW50LT5jdHgtPnRpbWUgKyBkZWx0YTsKCX0KCgl0YXNrX2Nsb2NrX2V2ZW50X3VwZGF0ZShldmVudCwgdGltZSk7Cn0KCnN0YXRpYyBpbnQgdGFza19jbG9ja19ldmVudF9pbml0KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJaWYgKGV2ZW50LT5hdHRyLnR5cGUgIT0gUEVSRl9UWVBFX1NPRlRXQVJFKQoJCXJldHVybiAtRU5PRU5UOwoKCWlmIChldmVudC0+YXR0ci5jb25maWcgIT0gUEVSRl9DT1VOVF9TV19UQVNLX0NMT0NLKQoJCXJldHVybiAtRU5PRU5UOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgc3RydWN0IHBtdSBwZXJmX3Rhc2tfY2xvY2sgPSB7CgkudGFza19jdHhfbnIJPSBwZXJmX3N3X2NvbnRleHQsCgoJLmV2ZW50X2luaXQJPSB0YXNrX2Nsb2NrX2V2ZW50X2luaXQsCgkuYWRkCQk9IHRhc2tfY2xvY2tfZXZlbnRfYWRkLAoJLmRlbAkJPSB0YXNrX2Nsb2NrX2V2ZW50X2RlbCwKCS5zdGFydAkJPSB0YXNrX2Nsb2NrX2V2ZW50X3N0YXJ0LAoJLnN0b3AJCT0gdGFza19jbG9ja19ldmVudF9zdG9wLAoJLnJlYWQJCT0gdGFza19jbG9ja19ldmVudF9yZWFkLAp9OwoKc3RhdGljIHZvaWQgcGVyZl9wbXVfbm9wX3ZvaWQoc3RydWN0IHBtdSAqcG11KQp7Cn0KCnN0YXRpYyBpbnQgcGVyZl9wbXVfbm9wX2ludChzdHJ1Y3QgcG11ICpwbXUpCnsKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBwZXJmX3BtdV9zdGFydF90eG4oc3RydWN0IHBtdSAqcG11KQp7CglwZXJmX3BtdV9kaXNhYmxlKHBtdSk7Cn0KCnN0YXRpYyBpbnQgcGVyZl9wbXVfY29tbWl0X3R4bihzdHJ1Y3QgcG11ICpwbXUpCnsKCXBlcmZfcG11X2VuYWJsZShwbXUpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfcG11X2NhbmNlbF90eG4oc3RydWN0IHBtdSAqcG11KQp7CglwZXJmX3BtdV9lbmFibGUocG11KTsKfQoKLyoKICogRW5zdXJlcyBhbGwgY29udGV4dHMgd2l0aCB0aGUgc2FtZSB0YXNrX2N0eF9uciBoYXZlIHRoZSBzYW1lCiAqIHBtdV9jcHVfY29udGV4dCB0b28uCiAqLwpzdGF0aWMgdm9pZCAqZmluZF9wbXVfY29udGV4dChpbnQgY3R4bikKewoJc3RydWN0IHBtdSAqcG11OwoKCWlmIChjdHhuIDwgMCkKCQlyZXR1cm4gTlVMTDsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5KHBtdSwgJnBtdXMsIGVudHJ5KSB7CgkJaWYgKHBtdS0+dGFza19jdHhfbnIgPT0gY3R4bikKCQkJcmV0dXJuIHBtdS0+cG11X2NwdV9jb250ZXh0OwoJfQoKCXJldHVybiBOVUxMOwp9CgpzdGF0aWMgdm9pZCB1cGRhdGVfcG11X2NvbnRleHQoc3RydWN0IHBtdSAqcG11LCBzdHJ1Y3QgcG11ICpvbGRfcG11KQp7CglpbnQgY3B1OwoKCWZvcl9lYWNoX3Bvc3NpYmxlX2NwdShjcHUpIHsKCQlzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4OwoKCQljcHVjdHggPSBwZXJfY3B1X3B0cihwbXUtPnBtdV9jcHVfY29udGV4dCwgY3B1KTsKCgkJaWYgKGNwdWN0eC0+YWN0aXZlX3BtdSA9PSBvbGRfcG11KQoJCQljcHVjdHgtPmFjdGl2ZV9wbXUgPSBwbXU7Cgl9Cn0KCnN0YXRpYyB2b2lkIGZyZWVfcG11X2NvbnRleHQoc3RydWN0IHBtdSAqcG11KQp7CglzdHJ1Y3QgcG11ICppOwoKCW11dGV4X2xvY2soJnBtdXNfbG9jayk7CgkvKgoJICogTGlrZSBhIHJlYWwgbGFtZSByZWZjb3VudC4KCSAqLwoJbGlzdF9mb3JfZWFjaF9lbnRyeShpLCAmcG11cywgZW50cnkpIHsKCQlpZiAoaS0+cG11X2NwdV9jb250ZXh0ID09IHBtdS0+cG11X2NwdV9jb250ZXh0KSB7CgkJCXVwZGF0ZV9wbXVfY29udGV4dChpLCBwbXUpOwoJCQlnb3RvIG91dDsKCQl9Cgl9CgoJZnJlZV9wZXJjcHUocG11LT5wbXVfY3B1X2NvbnRleHQpOwpvdXQ6CgltdXRleF91bmxvY2soJnBtdXNfbG9jayk7Cn0Kc3RhdGljIHN0cnVjdCBpZHIgcG11X2lkcjsKCnN0YXRpYyBzc2l6ZV90CnR5cGVfc2hvdyhzdHJ1Y3QgZGV2aWNlICpkZXYsIHN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLCBjaGFyICpwYWdlKQp7CglzdHJ1Y3QgcG11ICpwbXUgPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsKCglyZXR1cm4gc25wcmludGYocGFnZSwgUEFHRV9TSVpFLTEsICIlZFxuIiwgcG11LT50eXBlKTsKfQoKc3RhdGljIHN0cnVjdCBkZXZpY2VfYXR0cmlidXRlIHBtdV9kZXZfYXR0cnNbXSA9IHsKICAgICAgIF9fQVRUUl9STyh0eXBlKSwKICAgICAgIF9fQVRUUl9OVUxMLAp9OwoKc3RhdGljIGludCBwbXVfYnVzX3J1bm5pbmc7CnN0YXRpYyBzdHJ1Y3QgYnVzX3R5cGUgcG11X2J1cyA9IHsKCS5uYW1lCQk9ICJldmVudF9zb3VyY2UiLAoJLmRldl9hdHRycwk9IHBtdV9kZXZfYXR0cnMsCn07CgpzdGF0aWMgdm9pZCBwbXVfZGV2X3JlbGVhc2Uoc3RydWN0IGRldmljZSAqZGV2KQp7CglrZnJlZShkZXYpOwp9CgpzdGF0aWMgaW50IHBtdV9kZXZfYWxsb2Moc3RydWN0IHBtdSAqcG11KQp7CglpbnQgcmV0ID0gLUVOT01FTTsKCglwbXUtPmRldiA9IGt6YWxsb2Moc2l6ZW9mKHN0cnVjdCBkZXZpY2UpLCBHRlBfS0VSTkVMKTsKCWlmICghcG11LT5kZXYpCgkJZ290byBvdXQ7CgoJZGV2aWNlX2luaXRpYWxpemUocG11LT5kZXYpOwoJcmV0ID0gZGV2X3NldF9uYW1lKHBtdS0+ZGV2LCAiJXMiLCBwbXUtPm5hbWUpOwoJaWYgKHJldCkKCQlnb3RvIGZyZWVfZGV2OwoKCWRldl9zZXRfZHJ2ZGF0YShwbXUtPmRldiwgcG11KTsKCXBtdS0+ZGV2LT5idXMgPSAmcG11X2J1czsKCXBtdS0+ZGV2LT5yZWxlYXNlID0gcG11X2Rldl9yZWxlYXNlOwoJcmV0ID0gZGV2aWNlX2FkZChwbXUtPmRldik7CglpZiAocmV0KQoJCWdvdG8gZnJlZV9kZXY7CgpvdXQ6CglyZXR1cm4gcmV0OwoKZnJlZV9kZXY6CglwdXRfZGV2aWNlKHBtdS0+ZGV2KTsKCWdvdG8gb3V0Owp9CgpzdGF0aWMgc3RydWN0IGxvY2tfY2xhc3Nfa2V5IGNwdWN0eF9tdXRleDsKCmludCBwZXJmX3BtdV9yZWdpc3RlcihzdHJ1Y3QgcG11ICpwbXUsIGNoYXIgKm5hbWUsIGludCB0eXBlKQp7CglpbnQgY3B1LCByZXQ7CgoJbXV0ZXhfbG9jaygmcG11c19sb2NrKTsKCXJldCA9IC1FTk9NRU07CglwbXUtPnBtdV9kaXNhYmxlX2NvdW50ID0gYWxsb2NfcGVyY3B1KGludCk7CglpZiAoIXBtdS0+cG11X2Rpc2FibGVfY291bnQpCgkJZ290byB1bmxvY2s7CgoJcG11LT50eXBlID0gLTE7CglpZiAoIW5hbWUpCgkJZ290byBza2lwX3R5cGU7CglwbXUtPm5hbWUgPSBuYW1lOwoKCWlmICh0eXBlIDwgMCkgewoJCWludCBlcnIgPSBpZHJfcHJlX2dldCgmcG11X2lkciwgR0ZQX0tFUk5FTCk7CgkJaWYgKCFlcnIpCgkJCWdvdG8gZnJlZV9wZGM7CgoJCWVyciA9IGlkcl9nZXRfbmV3X2Fib3ZlKCZwbXVfaWRyLCBwbXUsIFBFUkZfVFlQRV9NQVgsICZ0eXBlKTsKCQlpZiAoZXJyKSB7CgkJCXJldCA9IGVycjsKCQkJZ290byBmcmVlX3BkYzsKCQl9Cgl9CglwbXUtPnR5cGUgPSB0eXBlOwoKCWlmIChwbXVfYnVzX3J1bm5pbmcpIHsKCQlyZXQgPSBwbXVfZGV2X2FsbG9jKHBtdSk7CgkJaWYgKHJldCkKCQkJZ290byBmcmVlX2lkcjsKCX0KCnNraXBfdHlwZToKCXBtdS0+cG11X2NwdV9jb250ZXh0ID0gZmluZF9wbXVfY29udGV4dChwbXUtPnRhc2tfY3R4X25yKTsKCWlmIChwbXUtPnBtdV9jcHVfY29udGV4dCkKCQlnb3RvIGdvdF9jcHVfY29udGV4dDsKCglwbXUtPnBtdV9jcHVfY29udGV4dCA9IGFsbG9jX3BlcmNwdShzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCk7CglpZiAoIXBtdS0+cG11X2NwdV9jb250ZXh0KQoJCWdvdG8gZnJlZV9kZXY7CgoJZm9yX2VhY2hfcG9zc2libGVfY3B1KGNwdSkgewoJCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHg7CgoJCWNwdWN0eCA9IHBlcl9jcHVfcHRyKHBtdS0+cG11X2NwdV9jb250ZXh0LCBjcHUpOwoJCV9fcGVyZl9ldmVudF9pbml0X2NvbnRleHQoJmNwdWN0eC0+Y3R4KTsKCQlsb2NrZGVwX3NldF9jbGFzcygmY3B1Y3R4LT5jdHgubXV0ZXgsICZjcHVjdHhfbXV0ZXgpOwoJCWNwdWN0eC0+Y3R4LnR5cGUgPSBjcHVfY29udGV4dDsKCQljcHVjdHgtPmN0eC5wbXUgPSBwbXU7CgkJY3B1Y3R4LT5qaWZmaWVzX2ludGVydmFsID0gMTsKCQlJTklUX0xJU1RfSEVBRCgmY3B1Y3R4LT5yb3RhdGlvbl9saXN0KTsKCQljcHVjdHgtPmFjdGl2ZV9wbXUgPSBwbXU7Cgl9Cgpnb3RfY3B1X2NvbnRleHQ6CglpZiAoIXBtdS0+c3RhcnRfdHhuKSB7CgkJaWYgKHBtdS0+cG11X2VuYWJsZSkgewoJCQkvKgoJCQkgKiBJZiB3ZSBoYXZlIHBtdV9lbmFibGUvcG11X2Rpc2FibGUgY2FsbHMsIGluc3RhbGwKCQkJICogdHJhbnNhY3Rpb24gc3R1YnMgdGhhdCB1c2UgdGhhdCB0byB0cnkgYW5kIGJhdGNoCgkJCSAqIGhhcmR3YXJlIGFjY2Vzc2VzLgoJCQkgKi8KCQkJcG11LT5zdGFydF90eG4gID0gcGVyZl9wbXVfc3RhcnRfdHhuOwoJCQlwbXUtPmNvbW1pdF90eG4gPSBwZXJmX3BtdV9jb21taXRfdHhuOwoJCQlwbXUtPmNhbmNlbF90eG4gPSBwZXJmX3BtdV9jYW5jZWxfdHhuOwoJCX0gZWxzZSB7CgkJCXBtdS0+c3RhcnRfdHhuICA9IHBlcmZfcG11X25vcF92b2lkOwoJCQlwbXUtPmNvbW1pdF90eG4gPSBwZXJmX3BtdV9ub3BfaW50OwoJCQlwbXUtPmNhbmNlbF90eG4gPSBwZXJmX3BtdV9ub3Bfdm9pZDsKCQl9Cgl9CgoJaWYgKCFwbXUtPnBtdV9lbmFibGUpIHsKCQlwbXUtPnBtdV9lbmFibGUgID0gcGVyZl9wbXVfbm9wX3ZvaWQ7CgkJcG11LT5wbXVfZGlzYWJsZSA9IHBlcmZfcG11X25vcF92b2lkOwoJfQoKCWxpc3RfYWRkX3JjdSgmcG11LT5lbnRyeSwgJnBtdXMpOwoJcmV0ID0gMDsKdW5sb2NrOgoJbXV0ZXhfdW5sb2NrKCZwbXVzX2xvY2spOwoKCXJldHVybiByZXQ7CgpmcmVlX2RldjoKCWRldmljZV9kZWwocG11LT5kZXYpOwoJcHV0X2RldmljZShwbXUtPmRldik7CgpmcmVlX2lkcjoKCWlmIChwbXUtPnR5cGUgPj0gUEVSRl9UWVBFX01BWCkKCQlpZHJfcmVtb3ZlKCZwbXVfaWRyLCBwbXUtPnR5cGUpOwoKZnJlZV9wZGM6CglmcmVlX3BlcmNwdShwbXUtPnBtdV9kaXNhYmxlX2NvdW50KTsKCWdvdG8gdW5sb2NrOwp9Cgp2b2lkIHBlcmZfcG11X3VucmVnaXN0ZXIoc3RydWN0IHBtdSAqcG11KQp7CgltdXRleF9sb2NrKCZwbXVzX2xvY2spOwoJbGlzdF9kZWxfcmN1KCZwbXUtPmVudHJ5KTsKCW11dGV4X3VubG9jaygmcG11c19sb2NrKTsKCgkvKgoJICogV2UgZGVyZWZlcmVuY2UgdGhlIHBtdSBsaXN0IHVuZGVyIGJvdGggU1JDVSBhbmQgcmVndWxhciBSQ1UsIHNvCgkgKiBzeW5jaHJvbml6ZSBhZ2FpbnN0IGJvdGggb2YgdGhvc2UuCgkgKi8KCXN5bmNocm9uaXplX3NyY3UoJnBtdXNfc3JjdSk7CglzeW5jaHJvbml6ZV9yY3UoKTsKCglmcmVlX3BlcmNwdShwbXUtPnBtdV9kaXNhYmxlX2NvdW50KTsKCWlmIChwbXUtPnR5cGUgPj0gUEVSRl9UWVBFX01BWCkKCQlpZHJfcmVtb3ZlKCZwbXVfaWRyLCBwbXUtPnR5cGUpOwoJZGV2aWNlX2RlbChwbXUtPmRldik7CglwdXRfZGV2aWNlKHBtdS0+ZGV2KTsKCWZyZWVfcG11X2NvbnRleHQocG11KTsKfQoKc3RydWN0IHBtdSAqcGVyZl9pbml0X2V2ZW50KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJc3RydWN0IHBtdSAqcG11ID0gTlVMTDsKCWludCBpZHg7CgoJaWR4ID0gc3JjdV9yZWFkX2xvY2soJnBtdXNfc3JjdSk7CgoJcmN1X3JlYWRfbG9jaygpOwoJcG11ID0gaWRyX2ZpbmQoJnBtdV9pZHIsIGV2ZW50LT5hdHRyLnR5cGUpOwoJcmN1X3JlYWRfdW5sb2NrKCk7CglpZiAocG11KQoJCWdvdG8gdW5sb2NrOwoKCWxpc3RfZm9yX2VhY2hfZW50cnlfcmN1KHBtdSwgJnBtdXMsIGVudHJ5KSB7CgkJaW50IHJldCA9IHBtdS0+ZXZlbnRfaW5pdChldmVudCk7CgkJaWYgKCFyZXQpCgkJCWdvdG8gdW5sb2NrOwoKCQlpZiAocmV0ICE9IC1FTk9FTlQpIHsKCQkJcG11ID0gRVJSX1BUUihyZXQpOwoJCQlnb3RvIHVubG9jazsKCQl9Cgl9CglwbXUgPSBFUlJfUFRSKC1FTk9FTlQpOwp1bmxvY2s6CglzcmN1X3JlYWRfdW5sb2NrKCZwbXVzX3NyY3UsIGlkeCk7CgoJcmV0dXJuIHBtdTsKfQoKLyoKICogQWxsb2NhdGUgYW5kIGluaXRpYWxpemUgYSBldmVudCBzdHJ1Y3R1cmUKICovCnN0YXRpYyBzdHJ1Y3QgcGVyZl9ldmVudCAqCnBlcmZfZXZlbnRfYWxsb2Moc3RydWN0IHBlcmZfZXZlbnRfYXR0ciAqYXR0ciwgaW50IGNwdSwKCQkgc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrLAoJCSBzdHJ1Y3QgcGVyZl9ldmVudCAqZ3JvdXBfbGVhZGVyLAoJCSBzdHJ1Y3QgcGVyZl9ldmVudCAqcGFyZW50X2V2ZW50LAoJCSBwZXJmX292ZXJmbG93X2hhbmRsZXJfdCBvdmVyZmxvd19oYW5kbGVyKQp7CglzdHJ1Y3QgcG11ICpwbXU7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQ7CglzdHJ1Y3QgaHdfcGVyZl9ldmVudCAqaHdjOwoJbG9uZyBlcnI7CgoJaWYgKCh1bnNpZ25lZCljcHUgPj0gbnJfY3B1X2lkcykgewoJCWlmICghdGFzayB8fCBjcHUgIT0gLTEpCgkJCXJldHVybiBFUlJfUFRSKC1FSU5WQUwpOwoJfQoKCWV2ZW50ID0ga3phbGxvYyhzaXplb2YoKmV2ZW50KSwgR0ZQX0tFUk5FTCk7CglpZiAoIWV2ZW50KQoJCXJldHVybiBFUlJfUFRSKC1FTk9NRU0pOwoKCS8qCgkgKiBTaW5nbGUgZXZlbnRzIGFyZSB0aGVpciBvd24gZ3JvdXAgbGVhZGVycywgd2l0aCBhbgoJICogZW1wdHkgc2libGluZyBsaXN0OgoJICovCglpZiAoIWdyb3VwX2xlYWRlcikKCQlncm91cF9sZWFkZXIgPSBldmVudDsKCgltdXRleF9pbml0KCZldmVudC0+Y2hpbGRfbXV0ZXgpOwoJSU5JVF9MSVNUX0hFQUQoJmV2ZW50LT5jaGlsZF9saXN0KTsKCglJTklUX0xJU1RfSEVBRCgmZXZlbnQtPmdyb3VwX2VudHJ5KTsKCUlOSVRfTElTVF9IRUFEKCZldmVudC0+ZXZlbnRfZW50cnkpOwoJSU5JVF9MSVNUX0hFQUQoJmV2ZW50LT5zaWJsaW5nX2xpc3QpOwoJaW5pdF93YWl0cXVldWVfaGVhZCgmZXZlbnQtPndhaXRxKTsKCWluaXRfaXJxX3dvcmsoJmV2ZW50LT5wZW5kaW5nLCBwZXJmX3BlbmRpbmdfZXZlbnQpOwoKCW11dGV4X2luaXQoJmV2ZW50LT5tbWFwX211dGV4KTsKCglldmVudC0+Y3B1CQk9IGNwdTsKCWV2ZW50LT5hdHRyCQk9ICphdHRyOwoJZXZlbnQtPmdyb3VwX2xlYWRlcgk9IGdyb3VwX2xlYWRlcjsKCWV2ZW50LT5wbXUJCT0gTlVMTDsKCWV2ZW50LT5vbmNwdQkJPSAtMTsKCglldmVudC0+cGFyZW50CQk9IHBhcmVudF9ldmVudDsKCglldmVudC0+bnMJCT0gZ2V0X3BpZF9ucyhjdXJyZW50LT5uc3Byb3h5LT5waWRfbnMpOwoJZXZlbnQtPmlkCQk9IGF0b21pYzY0X2luY19yZXR1cm4oJnBlcmZfZXZlbnRfaWQpOwoKCWV2ZW50LT5zdGF0ZQkJPSBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFOwoKCWlmICh0YXNrKSB7CgkJZXZlbnQtPmF0dGFjaF9zdGF0ZSA9IFBFUkZfQVRUQUNIX1RBU0s7CiNpZmRlZiBDT05GSUdfSEFWRV9IV19CUkVBS1BPSU5UCgkJLyoKCQkgKiBod19icmVha3BvaW50IGlzIGEgYml0IGRpZmZpY3VsdCBoZXJlLi4KCQkgKi8KCQlpZiAoYXR0ci0+dHlwZSA9PSBQRVJGX1RZUEVfQlJFQUtQT0lOVCkKCQkJZXZlbnQtPmh3LmJwX3RhcmdldCA9IHRhc2s7CiNlbmRpZgoJfQoKCWlmICghb3ZlcmZsb3dfaGFuZGxlciAmJiBwYXJlbnRfZXZlbnQpCgkJb3ZlcmZsb3dfaGFuZGxlciA9IHBhcmVudF9ldmVudC0+b3ZlcmZsb3dfaGFuZGxlcjsKCglldmVudC0+b3ZlcmZsb3dfaGFuZGxlcgk9IG92ZXJmbG93X2hhbmRsZXI7CgoJaWYgKGF0dHItPmRpc2FibGVkKQoJCWV2ZW50LT5zdGF0ZSA9IFBFUkZfRVZFTlRfU1RBVEVfT0ZGOwoKCXBtdSA9IE5VTEw7CgoJaHdjID0gJmV2ZW50LT5odzsKCWh3Yy0+c2FtcGxlX3BlcmlvZCA9IGF0dHItPnNhbXBsZV9wZXJpb2Q7CglpZiAoYXR0ci0+ZnJlcSAmJiBhdHRyLT5zYW1wbGVfZnJlcSkKCQlod2MtPnNhbXBsZV9wZXJpb2QgPSAxOwoJaHdjLT5sYXN0X3BlcmlvZCA9IGh3Yy0+c2FtcGxlX3BlcmlvZDsKCglsb2NhbDY0X3NldCgmaHdjLT5wZXJpb2RfbGVmdCwgaHdjLT5zYW1wbGVfcGVyaW9kKTsKCgkvKgoJICogd2UgY3VycmVudGx5IGRvIG5vdCBzdXBwb3J0IFBFUkZfRk9STUFUX0dST1VQIG9uIGluaGVyaXRlZCBldmVudHMKCSAqLwoJaWYgKGF0dHItPmluaGVyaXQgJiYgKGF0dHItPnJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfR1JPVVApKQoJCWdvdG8gZG9uZTsKCglwbXUgPSBwZXJmX2luaXRfZXZlbnQoZXZlbnQpOwoKZG9uZToKCWVyciA9IDA7CglpZiAoIXBtdSkKCQllcnIgPSAtRUlOVkFMOwoJZWxzZSBpZiAoSVNfRVJSKHBtdSkpCgkJZXJyID0gUFRSX0VSUihwbXUpOwoKCWlmIChlcnIpIHsKCQlpZiAoZXZlbnQtPm5zKQoJCQlwdXRfcGlkX25zKGV2ZW50LT5ucyk7CgkJa2ZyZWUoZXZlbnQpOwoJCXJldHVybiBFUlJfUFRSKGVycik7Cgl9CgoJZXZlbnQtPnBtdSA9IHBtdTsKCglpZiAoIWV2ZW50LT5wYXJlbnQpIHsKCQlpZiAoZXZlbnQtPmF0dGFjaF9zdGF0ZSAmIFBFUkZfQVRUQUNIX1RBU0spCgkJCWp1bXBfbGFiZWxfaW5jKCZwZXJmX3Rhc2tfZXZlbnRzKTsKCQlpZiAoZXZlbnQtPmF0dHIubW1hcCB8fCBldmVudC0+YXR0ci5tbWFwX2RhdGEpCgkJCWF0b21pY19pbmMoJm5yX21tYXBfZXZlbnRzKTsKCQlpZiAoZXZlbnQtPmF0dHIuY29tbSkKCQkJYXRvbWljX2luYygmbnJfY29tbV9ldmVudHMpOwoJCWlmIChldmVudC0+YXR0ci50YXNrKQoJCQlhdG9taWNfaW5jKCZucl90YXNrX2V2ZW50cyk7CgkJaWYgKGV2ZW50LT5hdHRyLnNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfQ0FMTENIQUlOKSB7CgkJCWVyciA9IGdldF9jYWxsY2hhaW5fYnVmZmVycygpOwoJCQlpZiAoZXJyKSB7CgkJCQlmcmVlX2V2ZW50KGV2ZW50KTsKCQkJCXJldHVybiBFUlJfUFRSKGVycik7CgkJCX0KCQl9Cgl9CgoJcmV0dXJuIGV2ZW50Owp9CgpzdGF0aWMgaW50IHBlcmZfY29weV9hdHRyKHN0cnVjdCBwZXJmX2V2ZW50X2F0dHIgX191c2VyICp1YXR0ciwKCQkJICBzdHJ1Y3QgcGVyZl9ldmVudF9hdHRyICphdHRyKQp7Cgl1MzIgc2l6ZTsKCWludCByZXQ7CgoJaWYgKCFhY2Nlc3Nfb2soVkVSSUZZX1dSSVRFLCB1YXR0ciwgUEVSRl9BVFRSX1NJWkVfVkVSMCkpCgkJcmV0dXJuIC1FRkFVTFQ7CgoJLyoKCSAqIHplcm8gdGhlIGZ1bGwgc3RydWN0dXJlLCBzbyB0aGF0IGEgc2hvcnQgY29weSB3aWxsIGJlIG5pY2UuCgkgKi8KCW1lbXNldChhdHRyLCAwLCBzaXplb2YoKmF0dHIpKTsKCglyZXQgPSBnZXRfdXNlcihzaXplLCAmdWF0dHItPnNpemUpOwoJaWYgKHJldCkKCQlyZXR1cm4gcmV0OwoKCWlmIChzaXplID4gUEFHRV9TSVpFKQkvKiBzaWxseSBsYXJnZSAqLwoJCWdvdG8gZXJyX3NpemU7CgoJaWYgKCFzaXplKQkJLyogYWJpIGNvbXBhdCAqLwoJCXNpemUgPSBQRVJGX0FUVFJfU0laRV9WRVIwOwoKCWlmIChzaXplIDwgUEVSRl9BVFRSX1NJWkVfVkVSMCkKCQlnb3RvIGVycl9zaXplOwoKCS8qCgkgKiBJZiB3ZSdyZSBoYW5kZWQgYSBiaWdnZXIgc3RydWN0IHRoYW4gd2Uga25vdyBvZiwKCSAqIGVuc3VyZSBhbGwgdGhlIHVua25vd24gYml0cyBhcmUgMCAtIGkuZS4gbmV3CgkgKiB1c2VyLXNwYWNlIGRvZXMgbm90IHJlbHkgb24gYW55IGtlcm5lbCBmZWF0dXJlCgkgKiBleHRlbnNpb25zIHdlIGRvbnQga25vdyBhYm91dCB5ZXQuCgkgKi8KCWlmIChzaXplID4gc2l6ZW9mKCphdHRyKSkgewoJCXVuc2lnbmVkIGNoYXIgX191c2VyICphZGRyOwoJCXVuc2lnbmVkIGNoYXIgX191c2VyICplbmQ7CgkJdW5zaWduZWQgY2hhciB2YWw7CgoJCWFkZHIgPSAodm9pZCBfX3VzZXIgKil1YXR0ciArIHNpemVvZigqYXR0cik7CgkJZW5kICA9ICh2b2lkIF9fdXNlciAqKXVhdHRyICsgc2l6ZTsKCgkJZm9yICg7IGFkZHIgPCBlbmQ7IGFkZHIrKykgewoJCQlyZXQgPSBnZXRfdXNlcih2YWwsIGFkZHIpOwoJCQlpZiAocmV0KQoJCQkJcmV0dXJuIHJldDsKCQkJaWYgKHZhbCkKCQkJCWdvdG8gZXJyX3NpemU7CgkJfQoJCXNpemUgPSBzaXplb2YoKmF0dHIpOwoJfQoKCXJldCA9IGNvcHlfZnJvbV91c2VyKGF0dHIsIHVhdHRyLCBzaXplKTsKCWlmIChyZXQpCgkJcmV0dXJuIC1FRkFVTFQ7CgoJLyoKCSAqIElmIHRoZSB0eXBlIGV4aXN0cywgdGhlIGNvcnJlc3BvbmRpbmcgY3JlYXRpb24gd2lsbCB2ZXJpZnkKCSAqIHRoZSBhdHRyLT5jb25maWcuCgkgKi8KCWlmIChhdHRyLT50eXBlID49IFBFUkZfVFlQRV9NQVgpCgkJcmV0dXJuIC1FSU5WQUw7CgoJaWYgKGF0dHItPl9fcmVzZXJ2ZWRfMSkKCQlyZXR1cm4gLUVJTlZBTDsKCglpZiAoYXR0ci0+c2FtcGxlX3R5cGUgJiB+KFBFUkZfU0FNUExFX01BWC0xKSkKCQlyZXR1cm4gLUVJTlZBTDsKCglpZiAoYXR0ci0+cmVhZF9mb3JtYXQgJiB+KFBFUkZfRk9STUFUX01BWC0xKSkKCQlyZXR1cm4gLUVJTlZBTDsKCm91dDoKCXJldHVybiByZXQ7CgplcnJfc2l6ZToKCXB1dF91c2VyKHNpemVvZigqYXR0ciksICZ1YXR0ci0+c2l6ZSk7CglyZXQgPSAtRTJCSUc7Cglnb3RvIG91dDsKfQoKc3RhdGljIGludApwZXJmX2V2ZW50X3NldF9vdXRwdXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBzdHJ1Y3QgcGVyZl9ldmVudCAqb3V0cHV0X2V2ZW50KQp7CglzdHJ1Y3QgcGVyZl9idWZmZXIgKmJ1ZmZlciA9IE5VTEwsICpvbGRfYnVmZmVyID0gTlVMTDsKCWludCByZXQgPSAtRUlOVkFMOwoKCWlmICghb3V0cHV0X2V2ZW50KQoJCWdvdG8gc2V0OwoKCS8qIGRvbid0IGFsbG93IGNpcmN1bGFyIHJlZmVyZW5jZXMgKi8KCWlmIChldmVudCA9PSBvdXRwdXRfZXZlbnQpCgkJZ290byBvdXQ7CgoJLyoKCSAqIERvbid0IGFsbG93IGNyb3NzLWNwdSBidWZmZXJzCgkgKi8KCWlmIChvdXRwdXRfZXZlbnQtPmNwdSAhPSBldmVudC0+Y3B1KQoJCWdvdG8gb3V0OwoKCS8qCgkgKiBJZiBpdHMgbm90IGEgcGVyLWNwdSBidWZmZXIsIGl0IG11c3QgYmUgdGhlIHNhbWUgdGFzay4KCSAqLwoJaWYgKG91dHB1dF9ldmVudC0+Y3B1ID09IC0xICYmIG91dHB1dF9ldmVudC0+Y3R4ICE9IGV2ZW50LT5jdHgpCgkJZ290byBvdXQ7CgpzZXQ6CgltdXRleF9sb2NrKCZldmVudC0+bW1hcF9tdXRleCk7CgkvKiBDYW4ndCByZWRpcmVjdCBvdXRwdXQgaWYgd2UndmUgZ290IGFuIGFjdGl2ZSBtbWFwKCkgKi8KCWlmIChhdG9taWNfcmVhZCgmZXZlbnQtPm1tYXBfY291bnQpKQoJCWdvdG8gdW5sb2NrOwoKCWlmIChvdXRwdXRfZXZlbnQpIHsKCQkvKiBnZXQgdGhlIGJ1ZmZlciB3ZSB3YW50IHRvIHJlZGlyZWN0IHRvICovCgkJYnVmZmVyID0gcGVyZl9idWZmZXJfZ2V0KG91dHB1dF9ldmVudCk7CgkJaWYgKCFidWZmZXIpCgkJCWdvdG8gdW5sb2NrOwoJfQoKCW9sZF9idWZmZXIgPSBldmVudC0+YnVmZmVyOwoJcmN1X2Fzc2lnbl9wb2ludGVyKGV2ZW50LT5idWZmZXIsIGJ1ZmZlcik7CglyZXQgPSAwOwp1bmxvY2s6CgltdXRleF91bmxvY2soJmV2ZW50LT5tbWFwX211dGV4KTsKCglpZiAob2xkX2J1ZmZlcikKCQlwZXJmX2J1ZmZlcl9wdXQob2xkX2J1ZmZlcik7Cm91dDoKCXJldHVybiByZXQ7Cn0KCi8qKgogKiBzeXNfcGVyZl9ldmVudF9vcGVuIC0gb3BlbiBhIHBlcmZvcm1hbmNlIGV2ZW50LCBhc3NvY2lhdGUgaXQgdG8gYSB0YXNrL2NwdQogKgogKiBAYXR0cl91cHRyOglldmVudF9pZCB0eXBlIGF0dHJpYnV0ZXMgZm9yIG1vbml0b3Jpbmcvc2FtcGxpbmcKICogQHBpZDoJCXRhcmdldCBwaWQKICogQGNwdToJCXRhcmdldCBjcHUKICogQGdyb3VwX2ZkOgkJZ3JvdXAgbGVhZGVyIGV2ZW50IGZkCiAqLwpTWVNDQUxMX0RFRklORTUocGVyZl9ldmVudF9vcGVuLAoJCXN0cnVjdCBwZXJmX2V2ZW50X2F0dHIgX191c2VyICosIGF0dHJfdXB0ciwKCQlwaWRfdCwgcGlkLCBpbnQsIGNwdSwgaW50LCBncm91cF9mZCwgdW5zaWduZWQgbG9uZywgZmxhZ3MpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpncm91cF9sZWFkZXIgPSBOVUxMLCAqb3V0cHV0X2V2ZW50ID0gTlVMTDsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgKnNpYmxpbmc7CglzdHJ1Y3QgcGVyZl9ldmVudF9hdHRyIGF0dHI7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHg7CglzdHJ1Y3QgZmlsZSAqZXZlbnRfZmlsZSA9IE5VTEw7CglzdHJ1Y3QgZmlsZSAqZ3JvdXBfZmlsZSA9IE5VTEw7CglzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2sgPSBOVUxMOwoJc3RydWN0IHBtdSAqcG11OwoJaW50IGV2ZW50X2ZkOwoJaW50IG1vdmVfZ3JvdXAgPSAwOwoJaW50IGZwdXRfbmVlZGVkID0gMDsKCWludCBlcnI7CgoJLyogZm9yIGZ1dHVyZSBleHBhbmRhYmlsaXR5Li4uICovCglpZiAoZmxhZ3MgJiB+KFBFUkZfRkxBR19GRF9OT19HUk9VUCB8IFBFUkZfRkxBR19GRF9PVVRQVVQpKQoJCXJldHVybiAtRUlOVkFMOwoKCWVyciA9IHBlcmZfY29weV9hdHRyKGF0dHJfdXB0ciwgJmF0dHIpOwoJaWYgKGVycikKCQlyZXR1cm4gZXJyOwoKCWlmICghYXR0ci5leGNsdWRlX2tlcm5lbCkgewoJCWlmIChwZXJmX3BhcmFub2lkX2tlcm5lbCgpICYmICFjYXBhYmxlKENBUF9TWVNfQURNSU4pKQoJCQlyZXR1cm4gLUVBQ0NFUzsKCX0KCglpZiAoYXR0ci5mcmVxKSB7CgkJaWYgKGF0dHIuc2FtcGxlX2ZyZXEgPiBzeXNjdGxfcGVyZl9ldmVudF9zYW1wbGVfcmF0ZSkKCQkJcmV0dXJuIC1FSU5WQUw7Cgl9CgoJZXZlbnRfZmQgPSBnZXRfdW51c2VkX2ZkX2ZsYWdzKE9fUkRXUik7CglpZiAoZXZlbnRfZmQgPCAwKQoJCXJldHVybiBldmVudF9mZDsKCglpZiAoZ3JvdXBfZmQgIT0gLTEpIHsKCQlncm91cF9sZWFkZXIgPSBwZXJmX2ZnZXRfbGlnaHQoZ3JvdXBfZmQsICZmcHV0X25lZWRlZCk7CgkJaWYgKElTX0VSUihncm91cF9sZWFkZXIpKSB7CgkJCWVyciA9IFBUUl9FUlIoZ3JvdXBfbGVhZGVyKTsKCQkJZ290byBlcnJfZmQ7CgkJfQoJCWdyb3VwX2ZpbGUgPSBncm91cF9sZWFkZXItPmZpbHA7CgkJaWYgKGZsYWdzICYgUEVSRl9GTEFHX0ZEX09VVFBVVCkKCQkJb3V0cHV0X2V2ZW50ID0gZ3JvdXBfbGVhZGVyOwoJCWlmIChmbGFncyAmIFBFUkZfRkxBR19GRF9OT19HUk9VUCkKCQkJZ3JvdXBfbGVhZGVyID0gTlVMTDsKCX0KCglpZiAocGlkICE9IC0xKSB7CgkJdGFzayA9IGZpbmRfbGl2ZWx5X3Rhc2tfYnlfdnBpZChwaWQpOwoJCWlmIChJU19FUlIodGFzaykpIHsKCQkJZXJyID0gUFRSX0VSUih0YXNrKTsKCQkJZ290byBlcnJfZ3JvdXBfZmQ7CgkJfQoJfQoKCWV2ZW50ID0gcGVyZl9ldmVudF9hbGxvYygmYXR0ciwgY3B1LCB0YXNrLCBncm91cF9sZWFkZXIsIE5VTEwsIE5VTEwpOwoJaWYgKElTX0VSUihldmVudCkpIHsKCQllcnIgPSBQVFJfRVJSKGV2ZW50KTsKCQlnb3RvIGVycl90YXNrOwoJfQoKCS8qCgkgKiBTcGVjaWFsIGNhc2Ugc29mdHdhcmUgZXZlbnRzIGFuZCBhbGxvdyB0aGVtIHRvIGJlIHBhcnQgb2YKCSAqIGFueSBoYXJkd2FyZSBncm91cC4KCSAqLwoJcG11ID0gZXZlbnQtPnBtdTsKCglpZiAoZ3JvdXBfbGVhZGVyICYmCgkgICAgKGlzX3NvZnR3YXJlX2V2ZW50KGV2ZW50KSAhPSBpc19zb2Z0d2FyZV9ldmVudChncm91cF9sZWFkZXIpKSkgewoJCWlmIChpc19zb2Z0d2FyZV9ldmVudChldmVudCkpIHsKCQkJLyoKCQkJICogSWYgZXZlbnQgYW5kIGdyb3VwX2xlYWRlciBhcmUgbm90IGJvdGggYSBzb2Z0d2FyZQoJCQkgKiBldmVudCwgYW5kIGV2ZW50IGlzLCB0aGVuIGdyb3VwIGxlYWRlciBpcyBub3QuCgkJCSAqCgkJCSAqIEFsbG93IHRoZSBhZGRpdGlvbiBvZiBzb2Z0d2FyZSBldmVudHMgdG8gIXNvZnR3YXJlCgkJCSAqIGdyb3VwcywgdGhpcyBpcyBzYWZlIGJlY2F1c2Ugc29mdHdhcmUgZXZlbnRzIG5ldmVyCgkJCSAqIGZhaWwgdG8gc2NoZWR1bGUuCgkJCSAqLwoJCQlwbXUgPSBncm91cF9sZWFkZXItPnBtdTsKCQl9IGVsc2UgaWYgKGlzX3NvZnR3YXJlX2V2ZW50KGdyb3VwX2xlYWRlcikgJiYKCQkJICAgKGdyb3VwX2xlYWRlci0+Z3JvdXBfZmxhZ3MgJiBQRVJGX0dST1VQX1NPRlRXQVJFKSkgewoJCQkvKgoJCQkgKiBJbiBjYXNlIHRoZSBncm91cCBpcyBhIHB1cmUgc29mdHdhcmUgZ3JvdXAsIGFuZCB3ZQoJCQkgKiB0cnkgdG8gYWRkIGEgaGFyZHdhcmUgZXZlbnQsIG1vdmUgdGhlIHdob2xlIGdyb3VwIHRvCgkJCSAqIHRoZSBoYXJkd2FyZSBjb250ZXh0LgoJCQkgKi8KCQkJbW92ZV9ncm91cCA9IDE7CgkJfQoJfQoKCS8qCgkgKiBHZXQgdGhlIHRhcmdldCBjb250ZXh0ICh0YXNrIG9yIHBlcmNwdSk6CgkgKi8KCWN0eCA9IGZpbmRfZ2V0X2NvbnRleHQocG11LCB0YXNrLCBjcHUpOwoJaWYgKElTX0VSUihjdHgpKSB7CgkJZXJyID0gUFRSX0VSUihjdHgpOwoJCWdvdG8gZXJyX2FsbG9jOwoJfQoKCS8qCgkgKiBMb29rIHVwIHRoZSBncm91cCBsZWFkZXIgKHdlIHdpbGwgYXR0YWNoIHRoaXMgZXZlbnQgdG8gaXQpOgoJICovCglpZiAoZ3JvdXBfbGVhZGVyKSB7CgkJZXJyID0gLUVJTlZBTDsKCgkJLyoKCQkgKiBEbyBub3QgYWxsb3cgYSByZWN1cnNpdmUgaGllcmFyY2h5ICh0aGlzIG5ldyBzaWJsaW5nCgkJICogYmVjb21pbmcgcGFydCBvZiBhbm90aGVyIGdyb3VwLXNpYmxpbmcpOgoJCSAqLwoJCWlmIChncm91cF9sZWFkZXItPmdyb3VwX2xlYWRlciAhPSBncm91cF9sZWFkZXIpCgkJCWdvdG8gZXJyX2NvbnRleHQ7CgkJLyoKCQkgKiBEbyBub3QgYWxsb3cgdG8gYXR0YWNoIHRvIGEgZ3JvdXAgaW4gYSBkaWZmZXJlbnQKCQkgKiB0YXNrIG9yIENQVSBjb250ZXh0OgoJCSAqLwoJCWlmIChtb3ZlX2dyb3VwKSB7CgkJCWlmIChncm91cF9sZWFkZXItPmN0eC0+dHlwZSAhPSBjdHgtPnR5cGUpCgkJCQlnb3RvIGVycl9jb250ZXh0OwoJCX0gZWxzZSB7CgkJCWlmIChncm91cF9sZWFkZXItPmN0eCAhPSBjdHgpCgkJCQlnb3RvIGVycl9jb250ZXh0OwoJCX0KCgkJLyoKCQkgKiBPbmx5IGEgZ3JvdXAgbGVhZGVyIGNhbiBiZSBleGNsdXNpdmUgb3IgcGlubmVkCgkJICovCgkJaWYgKGF0dHIuZXhjbHVzaXZlIHx8IGF0dHIucGlubmVkKQoJCQlnb3RvIGVycl9jb250ZXh0OwoJfQoKCWlmIChvdXRwdXRfZXZlbnQpIHsKCQllcnIgPSBwZXJmX2V2ZW50X3NldF9vdXRwdXQoZXZlbnQsIG91dHB1dF9ldmVudCk7CgkJaWYgKGVycikKCQkJZ290byBlcnJfY29udGV4dDsKCX0KCglldmVudF9maWxlID0gYW5vbl9pbm9kZV9nZXRmaWxlKCJbcGVyZl9ldmVudF0iLCAmcGVyZl9mb3BzLCBldmVudCwgT19SRFdSKTsKCWlmIChJU19FUlIoZXZlbnRfZmlsZSkpIHsKCQllcnIgPSBQVFJfRVJSKGV2ZW50X2ZpbGUpOwoJCWdvdG8gZXJyX2NvbnRleHQ7Cgl9CgoJaWYgKG1vdmVfZ3JvdXApIHsKCQlzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpnY3R4ID0gZ3JvdXBfbGVhZGVyLT5jdHg7CgoJCW11dGV4X2xvY2soJmdjdHgtPm11dGV4KTsKCQlwZXJmX3JlbW92ZV9mcm9tX2NvbnRleHQoZ3JvdXBfbGVhZGVyKTsKCQlsaXN0X2Zvcl9lYWNoX2VudHJ5KHNpYmxpbmcsICZncm91cF9sZWFkZXItPnNpYmxpbmdfbGlzdCwKCQkJCSAgICBncm91cF9lbnRyeSkgewoJCQlwZXJmX3JlbW92ZV9mcm9tX2NvbnRleHQoc2libGluZyk7CgkJCXB1dF9jdHgoZ2N0eCk7CgkJfQoJCW11dGV4X3VubG9jaygmZ2N0eC0+bXV0ZXgpOwoJCXB1dF9jdHgoZ2N0eCk7Cgl9CgoJZXZlbnQtPmZpbHAgPSBldmVudF9maWxlOwoJV0FSTl9PTl9PTkNFKGN0eC0+cGFyZW50X2N0eCk7CgltdXRleF9sb2NrKCZjdHgtPm11dGV4KTsKCglpZiAobW92ZV9ncm91cCkgewoJCXBlcmZfaW5zdGFsbF9pbl9jb250ZXh0KGN0eCwgZ3JvdXBfbGVhZGVyLCBjcHUpOwoJCWdldF9jdHgoY3R4KTsKCQlsaXN0X2Zvcl9lYWNoX2VudHJ5KHNpYmxpbmcsICZncm91cF9sZWFkZXItPnNpYmxpbmdfbGlzdCwKCQkJCSAgICBncm91cF9lbnRyeSkgewoJCQlwZXJmX2luc3RhbGxfaW5fY29udGV4dChjdHgsIHNpYmxpbmcsIGNwdSk7CgkJCWdldF9jdHgoY3R4KTsKCQl9Cgl9CgoJcGVyZl9pbnN0YWxsX2luX2NvbnRleHQoY3R4LCBldmVudCwgY3B1KTsKCSsrY3R4LT5nZW5lcmF0aW9uOwoJcGVyZl91bnBpbl9jb250ZXh0KGN0eCk7CgltdXRleF91bmxvY2soJmN0eC0+bXV0ZXgpOwoKCWV2ZW50LT5vd25lciA9IGN1cnJlbnQ7CgoJbXV0ZXhfbG9jaygmY3VycmVudC0+cGVyZl9ldmVudF9tdXRleCk7CglsaXN0X2FkZF90YWlsKCZldmVudC0+b3duZXJfZW50cnksICZjdXJyZW50LT5wZXJmX2V2ZW50X2xpc3QpOwoJbXV0ZXhfdW5sb2NrKCZjdXJyZW50LT5wZXJmX2V2ZW50X211dGV4KTsKCgkvKgoJICogUHJlY2FsY3VsYXRlIHNhbXBsZV9kYXRhIHNpemVzCgkgKi8KCXBlcmZfZXZlbnRfX2hlYWRlcl9zaXplKGV2ZW50KTsKCXBlcmZfZXZlbnRfX2lkX2hlYWRlcl9zaXplKGV2ZW50KTsKCgkvKgoJICogRHJvcCB0aGUgcmVmZXJlbmNlIG9uIHRoZSBncm91cF9ldmVudCBhZnRlciBwbGFjaW5nIHRoZQoJICogbmV3IGV2ZW50IG9uIHRoZSBzaWJsaW5nX2xpc3QuIFRoaXMgZW5zdXJlcyBkZXN0cnVjdGlvbgoJICogb2YgdGhlIGdyb3VwIGxlYWRlciB3aWxsIGZpbmQgdGhlIHBvaW50ZXIgdG8gaXRzZWxmIGluCgkgKiBwZXJmX2dyb3VwX2RldGFjaCgpLgoJICovCglmcHV0X2xpZ2h0KGdyb3VwX2ZpbGUsIGZwdXRfbmVlZGVkKTsKCWZkX2luc3RhbGwoZXZlbnRfZmQsIGV2ZW50X2ZpbGUpOwoJcmV0dXJuIGV2ZW50X2ZkOwoKZXJyX2NvbnRleHQ6CglwZXJmX3VucGluX2NvbnRleHQoY3R4KTsKCXB1dF9jdHgoY3R4KTsKZXJyX2FsbG9jOgoJZnJlZV9ldmVudChldmVudCk7CmVycl90YXNrOgoJaWYgKHRhc2spCgkJcHV0X3Rhc2tfc3RydWN0KHRhc2spOwplcnJfZ3JvdXBfZmQ6CglmcHV0X2xpZ2h0KGdyb3VwX2ZpbGUsIGZwdXRfbmVlZGVkKTsKZXJyX2ZkOgoJcHV0X3VudXNlZF9mZChldmVudF9mZCk7CglyZXR1cm4gZXJyOwp9CgovKioKICogcGVyZl9ldmVudF9jcmVhdGVfa2VybmVsX2NvdW50ZXIKICoKICogQGF0dHI6IGF0dHJpYnV0ZXMgb2YgdGhlIGNvdW50ZXIgdG8gY3JlYXRlCiAqIEBjcHU6IGNwdSBpbiB3aGljaCB0aGUgY291bnRlciBpcyBib3VuZAogKiBAdGFzazogdGFzayB0byBwcm9maWxlIChOVUxMIGZvciBwZXJjcHUpCiAqLwpzdHJ1Y3QgcGVyZl9ldmVudCAqCnBlcmZfZXZlbnRfY3JlYXRlX2tlcm5lbF9jb3VudGVyKHN0cnVjdCBwZXJmX2V2ZW50X2F0dHIgKmF0dHIsIGludCBjcHUsCgkJCQkgc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrLAoJCQkJIHBlcmZfb3ZlcmZsb3dfaGFuZGxlcl90IG92ZXJmbG93X2hhbmRsZXIpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eDsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCWludCBlcnI7CgoJLyoKCSAqIEdldCB0aGUgdGFyZ2V0IGNvbnRleHQgKHRhc2sgb3IgcGVyY3B1KToKCSAqLwoKCWV2ZW50ID0gcGVyZl9ldmVudF9hbGxvYyhhdHRyLCBjcHUsIHRhc2ssIE5VTEwsIE5VTEwsIG92ZXJmbG93X2hhbmRsZXIpOwoJaWYgKElTX0VSUihldmVudCkpIHsKCQllcnIgPSBQVFJfRVJSKGV2ZW50KTsKCQlnb3RvIGVycjsKCX0KCgljdHggPSBmaW5kX2dldF9jb250ZXh0KGV2ZW50LT5wbXUsIHRhc2ssIGNwdSk7CglpZiAoSVNfRVJSKGN0eCkpIHsKCQllcnIgPSBQVFJfRVJSKGN0eCk7CgkJZ290byBlcnJfZnJlZTsKCX0KCglldmVudC0+ZmlscCA9IE5VTEw7CglXQVJOX09OX09OQ0UoY3R4LT5wYXJlbnRfY3R4KTsKCW11dGV4X2xvY2soJmN0eC0+bXV0ZXgpOwoJcGVyZl9pbnN0YWxsX2luX2NvbnRleHQoY3R4LCBldmVudCwgY3B1KTsKCSsrY3R4LT5nZW5lcmF0aW9uOwoJcGVyZl91bnBpbl9jb250ZXh0KGN0eCk7CgltdXRleF91bmxvY2soJmN0eC0+bXV0ZXgpOwoKCXJldHVybiBldmVudDsKCmVycl9mcmVlOgoJZnJlZV9ldmVudChldmVudCk7CmVycjoKCXJldHVybiBFUlJfUFRSKGVycik7Cn0KRVhQT1JUX1NZTUJPTF9HUEwocGVyZl9ldmVudF9jcmVhdGVfa2VybmVsX2NvdW50ZXIpOwoKc3RhdGljIHZvaWQgc3luY19jaGlsZF9ldmVudChzdHJ1Y3QgcGVyZl9ldmVudCAqY2hpbGRfZXZlbnQsCgkJCSAgICAgICBzdHJ1Y3QgdGFza19zdHJ1Y3QgKmNoaWxkKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqcGFyZW50X2V2ZW50ID0gY2hpbGRfZXZlbnQtPnBhcmVudDsKCXU2NCBjaGlsZF92YWw7CgoJaWYgKGNoaWxkX2V2ZW50LT5hdHRyLmluaGVyaXRfc3RhdCkKCQlwZXJmX2V2ZW50X3JlYWRfZXZlbnQoY2hpbGRfZXZlbnQsIGNoaWxkKTsKCgljaGlsZF92YWwgPSBwZXJmX2V2ZW50X2NvdW50KGNoaWxkX2V2ZW50KTsKCgkvKgoJICogQWRkIGJhY2sgdGhlIGNoaWxkJ3MgY291bnQgdG8gdGhlIHBhcmVudCdzIGNvdW50OgoJICovCglhdG9taWM2NF9hZGQoY2hpbGRfdmFsLCAmcGFyZW50X2V2ZW50LT5jaGlsZF9jb3VudCk7CglhdG9taWM2NF9hZGQoY2hpbGRfZXZlbnQtPnRvdGFsX3RpbWVfZW5hYmxlZCwKCQkgICAgICZwYXJlbnRfZXZlbnQtPmNoaWxkX3RvdGFsX3RpbWVfZW5hYmxlZCk7CglhdG9taWM2NF9hZGQoY2hpbGRfZXZlbnQtPnRvdGFsX3RpbWVfcnVubmluZywKCQkgICAgICZwYXJlbnRfZXZlbnQtPmNoaWxkX3RvdGFsX3RpbWVfcnVubmluZyk7CgoJLyoKCSAqIFJlbW92ZSB0aGlzIGV2ZW50IGZyb20gdGhlIHBhcmVudCdzIGxpc3QKCSAqLwoJV0FSTl9PTl9PTkNFKHBhcmVudF9ldmVudC0+Y3R4LT5wYXJlbnRfY3R4KTsKCW11dGV4X2xvY2soJnBhcmVudF9ldmVudC0+Y2hpbGRfbXV0ZXgpOwoJbGlzdF9kZWxfaW5pdCgmY2hpbGRfZXZlbnQtPmNoaWxkX2xpc3QpOwoJbXV0ZXhfdW5sb2NrKCZwYXJlbnRfZXZlbnQtPmNoaWxkX211dGV4KTsKCgkvKgoJICogUmVsZWFzZSB0aGUgcGFyZW50IGV2ZW50LCBpZiB0aGlzIHdhcyB0aGUgbGFzdAoJICogcmVmZXJlbmNlIHRvIGl0LgoJICovCglmcHV0KHBhcmVudF9ldmVudC0+ZmlscCk7Cn0KCnN0YXRpYyB2b2lkCl9fcGVyZl9ldmVudF9leGl0X3Rhc2soc3RydWN0IHBlcmZfZXZlbnQgKmNoaWxkX2V2ZW50LAoJCQkgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY2hpbGRfY3R4LAoJCQkgc3RydWN0IHRhc2tfc3RydWN0ICpjaGlsZCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKnBhcmVudF9ldmVudDsKCglwZXJmX3JlbW92ZV9mcm9tX2NvbnRleHQoY2hpbGRfZXZlbnQpOwoKCXBhcmVudF9ldmVudCA9IGNoaWxkX2V2ZW50LT5wYXJlbnQ7CgkvKgoJICogSXQgY2FuIGhhcHBlbiB0aGF0IHBhcmVudCBleGl0cyBmaXJzdCwgYW5kIGhhcyBldmVudHMKCSAqIHRoYXQgYXJlIHN0aWxsIGFyb3VuZCBkdWUgdG8gdGhlIGNoaWxkIHJlZmVyZW5jZS4gVGhlc2UKCSAqIGV2ZW50cyBuZWVkIHRvIGJlIHphcHBlZCAtIGJ1dCBvdGhlcndpc2UgbGluZ2VyLgoJICovCglpZiAocGFyZW50X2V2ZW50KSB7CgkJc3luY19jaGlsZF9ldmVudChjaGlsZF9ldmVudCwgY2hpbGQpOwoJCWZyZWVfZXZlbnQoY2hpbGRfZXZlbnQpOwoJfQp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X2V4aXRfdGFza19jb250ZXh0KHN0cnVjdCB0YXNrX3N0cnVjdCAqY2hpbGQsIGludCBjdHhuKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqY2hpbGRfZXZlbnQsICp0bXA7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjaGlsZF9jdHg7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCWlmIChsaWtlbHkoIWNoaWxkLT5wZXJmX2V2ZW50X2N0eHBbY3R4bl0pKSB7CgkJcGVyZl9ldmVudF90YXNrKGNoaWxkLCBOVUxMLCAwKTsKCQlyZXR1cm47Cgl9CgoJbG9jYWxfaXJxX3NhdmUoZmxhZ3MpOwoJLyoKCSAqIFdlIGNhbid0IHJlc2NoZWR1bGUgaGVyZSBiZWNhdXNlIGludGVycnVwdHMgYXJlIGRpc2FibGVkLAoJICogYW5kIGVpdGhlciBjaGlsZCBpcyBjdXJyZW50IG9yIGl0IGlzIGEgdGFzayB0aGF0IGNhbid0IGJlCgkgKiBzY2hlZHVsZWQsIHNvIHdlIGFyZSBub3cgc2FmZSBmcm9tIHJlc2NoZWR1bGluZyBjaGFuZ2luZwoJICogb3VyIGNvbnRleHQuCgkgKi8KCWNoaWxkX2N0eCA9IHJjdV9kZXJlZmVyZW5jZV9yYXcoY2hpbGQtPnBlcmZfZXZlbnRfY3R4cFtjdHhuXSk7Cgl0YXNrX2N0eF9zY2hlZF9vdXQoY2hpbGRfY3R4LCBFVkVOVF9BTEwpOwoKCS8qCgkgKiBUYWtlIHRoZSBjb250ZXh0IGxvY2sgaGVyZSBzbyB0aGF0IGlmIGZpbmRfZ2V0X2NvbnRleHQgaXMKCSAqIHJlYWRpbmcgY2hpbGQtPnBlcmZfZXZlbnRfY3R4cCwgd2Ugd2FpdCB1bnRpbCBpdCBoYXMKCSAqIGluY3JlbWVudGVkIHRoZSBjb250ZXh0J3MgcmVmY291bnQgYmVmb3JlIHdlIGRvIHB1dF9jdHggYmVsb3cuCgkgKi8KCXJhd19zcGluX2xvY2soJmNoaWxkX2N0eC0+bG9jayk7CgljaGlsZC0+cGVyZl9ldmVudF9jdHhwW2N0eG5dID0gTlVMTDsKCS8qCgkgKiBJZiB0aGlzIGNvbnRleHQgaXMgYSBjbG9uZTsgdW5jbG9uZSBpdCBzbyBpdCBjYW4ndCBnZXQKCSAqIHN3YXBwZWQgdG8gYW5vdGhlciBwcm9jZXNzIHdoaWxlIHdlJ3JlIHJlbW92aW5nIGFsbAoJICogdGhlIGV2ZW50cyBmcm9tIGl0LgoJICovCgl1bmNsb25lX2N0eChjaGlsZF9jdHgpOwoJdXBkYXRlX2NvbnRleHRfdGltZShjaGlsZF9jdHgpOwoJcmF3X3NwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNoaWxkX2N0eC0+bG9jaywgZmxhZ3MpOwoKCS8qCgkgKiBSZXBvcnQgdGhlIHRhc2sgZGVhZCBhZnRlciB1bnNjaGVkdWxpbmcgdGhlIGV2ZW50cyBzbyB0aGF0IHdlCgkgKiB3b24ndCBnZXQgYW55IHNhbXBsZXMgYWZ0ZXIgUEVSRl9SRUNPUkRfRVhJVC4gV2UgY2FuIGhvd2V2ZXIgc3RpbGwKCSAqIGdldCBhIGZldyBQRVJGX1JFQ09SRF9SRUFEIGV2ZW50cy4KCSAqLwoJcGVyZl9ldmVudF90YXNrKGNoaWxkLCBjaGlsZF9jdHgsIDApOwoKCS8qCgkgKiBXZSBjYW4gcmVjdXJzZSBvbiB0aGUgc2FtZSBsb2NrIHR5cGUgdGhyb3VnaDoKCSAqCgkgKiAgIF9fcGVyZl9ldmVudF9leGl0X3Rhc2soKQoJICogICAgIHN5bmNfY2hpbGRfZXZlbnQoKQoJICogICAgICAgZnB1dChwYXJlbnRfZXZlbnQtPmZpbHApCgkgKiAgICAgICAgIHBlcmZfcmVsZWFzZSgpCgkgKiAgICAgICAgICAgbXV0ZXhfbG9jaygmY3R4LT5tdXRleCkKCSAqCgkgKiBCdXQgc2luY2UgaXRzIHRoZSBwYXJlbnQgY29udGV4dCBpdCB3b24ndCBiZSB0aGUgc2FtZSBpbnN0YW5jZS4KCSAqLwoJbXV0ZXhfbG9jaygmY2hpbGRfY3R4LT5tdXRleCk7CgphZ2FpbjoKCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShjaGlsZF9ldmVudCwgdG1wLCAmY2hpbGRfY3R4LT5waW5uZWRfZ3JvdXBzLAoJCQkJIGdyb3VwX2VudHJ5KQoJCV9fcGVyZl9ldmVudF9leGl0X3Rhc2soY2hpbGRfZXZlbnQsIGNoaWxkX2N0eCwgY2hpbGQpOwoKCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShjaGlsZF9ldmVudCwgdG1wLCAmY2hpbGRfY3R4LT5mbGV4aWJsZV9ncm91cHMsCgkJCQkgZ3JvdXBfZW50cnkpCgkJX19wZXJmX2V2ZW50X2V4aXRfdGFzayhjaGlsZF9ldmVudCwgY2hpbGRfY3R4LCBjaGlsZCk7CgoJLyoKCSAqIElmIHRoZSBsYXN0IGV2ZW50IHdhcyBhIGdyb3VwIGV2ZW50LCBpdCB3aWxsIGhhdmUgYXBwZW5kZWQgYWxsCgkgKiBpdHMgc2libGluZ3MgdG8gdGhlIGxpc3QsIGJ1dCB3ZSBvYnRhaW5lZCAndG1wJyBiZWZvcmUgdGhhdCB3aGljaAoJICogd2lsbCBzdGlsbCBwb2ludCB0byB0aGUgbGlzdCBoZWFkIHRlcm1pbmF0aW5nIHRoZSBpdGVyYXRpb24uCgkgKi8KCWlmICghbGlzdF9lbXB0eSgmY2hpbGRfY3R4LT5waW5uZWRfZ3JvdXBzKSB8fAoJICAgICFsaXN0X2VtcHR5KCZjaGlsZF9jdHgtPmZsZXhpYmxlX2dyb3VwcykpCgkJZ290byBhZ2FpbjsKCgltdXRleF91bmxvY2soJmNoaWxkX2N0eC0+bXV0ZXgpOwoKCXB1dF9jdHgoY2hpbGRfY3R4KTsKfQoKLyoKICogV2hlbiBhIGNoaWxkIHRhc2sgZXhpdHMsIGZlZWQgYmFjayBldmVudCB2YWx1ZXMgdG8gcGFyZW50IGV2ZW50cy4KICovCnZvaWQgcGVyZl9ldmVudF9leGl0X3Rhc2soc3RydWN0IHRhc2tfc3RydWN0ICpjaGlsZCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCAqdG1wOwoJaW50IGN0eG47CgoJbXV0ZXhfbG9jaygmY2hpbGQtPnBlcmZfZXZlbnRfbXV0ZXgpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGV2ZW50LCB0bXAsICZjaGlsZC0+cGVyZl9ldmVudF9saXN0LAoJCQkJIG93bmVyX2VudHJ5KSB7CgkJbGlzdF9kZWxfaW5pdCgmZXZlbnQtPm93bmVyX2VudHJ5KTsKCgkJLyoKCQkgKiBFbnN1cmUgdGhlIGxpc3QgZGVsZXRpb24gaXMgdmlzaWJsZSBiZWZvcmUgd2UgY2xlYXIKCQkgKiB0aGUgb3duZXIsIGNsb3NlcyBhIHJhY2UgYWdhaW5zdCBwZXJmX3JlbGVhc2UoKSB3aGVyZQoJCSAqIHdlIG5lZWQgdG8gc2VyaWFsaXplIG9uIHRoZSBvd25lci0+cGVyZl9ldmVudF9tdXRleC4KCQkgKi8KCQlzbXBfd21iKCk7CgkJZXZlbnQtPm93bmVyID0gTlVMTDsKCX0KCW11dGV4X3VubG9jaygmY2hpbGQtPnBlcmZfZXZlbnRfbXV0ZXgpOwoKCWZvcl9lYWNoX3Rhc2tfY29udGV4dF9ucihjdHhuKQoJCXBlcmZfZXZlbnRfZXhpdF90YXNrX2NvbnRleHQoY2hpbGQsIGN0eG4pOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2ZyZWVfZXZlbnQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkgICAgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqcGFyZW50ID0gZXZlbnQtPnBhcmVudDsKCglpZiAoV0FSTl9PTl9PTkNFKCFwYXJlbnQpKQoJCXJldHVybjsKCgltdXRleF9sb2NrKCZwYXJlbnQtPmNoaWxkX211dGV4KTsKCWxpc3RfZGVsX2luaXQoJmV2ZW50LT5jaGlsZF9saXN0KTsKCW11dGV4X3VubG9jaygmcGFyZW50LT5jaGlsZF9tdXRleCk7CgoJZnB1dChwYXJlbnQtPmZpbHApOwoKCXBlcmZfZ3JvdXBfZGV0YWNoKGV2ZW50KTsKCWxpc3RfZGVsX2V2ZW50KGV2ZW50LCBjdHgpOwoJZnJlZV9ldmVudChldmVudCk7Cn0KCi8qCiAqIGZyZWUgYW4gdW5leHBvc2VkLCB1bnVzZWQgY29udGV4dCBhcyBjcmVhdGVkIGJ5IGluaGVyaXRhbmNlIGJ5CiAqIHBlcmZfZXZlbnRfaW5pdF90YXNrIGJlbG93LCB1c2VkIGJ5IGZvcmsoKSBpbiBjYXNlIG9mIGZhaWwuCiAqLwp2b2lkIHBlcmZfZXZlbnRfZnJlZV90YXNrKHN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzaykKewoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4OwoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCAqdG1wOwoJaW50IGN0eG47CgoJZm9yX2VhY2hfdGFza19jb250ZXh0X25yKGN0eG4pIHsKCQljdHggPSB0YXNrLT5wZXJmX2V2ZW50X2N0eHBbY3R4bl07CgkJaWYgKCFjdHgpCgkJCWNvbnRpbnVlOwoKCQltdXRleF9sb2NrKCZjdHgtPm11dGV4KTsKYWdhaW46CgkJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGV2ZW50LCB0bXAsICZjdHgtPnBpbm5lZF9ncm91cHMsCgkJCQlncm91cF9lbnRyeSkKCQkJcGVyZl9mcmVlX2V2ZW50KGV2ZW50LCBjdHgpOwoKCQlsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoZXZlbnQsIHRtcCwgJmN0eC0+ZmxleGlibGVfZ3JvdXBzLAoJCQkJZ3JvdXBfZW50cnkpCgkJCXBlcmZfZnJlZV9ldmVudChldmVudCwgY3R4KTsKCgkJaWYgKCFsaXN0X2VtcHR5KCZjdHgtPnBpbm5lZF9ncm91cHMpIHx8CgkJCQkhbGlzdF9lbXB0eSgmY3R4LT5mbGV4aWJsZV9ncm91cHMpKQoJCQlnb3RvIGFnYWluOwoKCQltdXRleF91bmxvY2soJmN0eC0+bXV0ZXgpOwoKCQlwdXRfY3R4KGN0eCk7Cgl9Cn0KCnZvaWQgcGVyZl9ldmVudF9kZWxheWVkX3B1dChzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2spCnsKCWludCBjdHhuOwoKCWZvcl9lYWNoX3Rhc2tfY29udGV4dF9ucihjdHhuKQoJCVdBUk5fT05fT05DRSh0YXNrLT5wZXJmX2V2ZW50X2N0eHBbY3R4bl0pOwp9CgovKgogKiBpbmhlcml0IGEgZXZlbnQgZnJvbSBwYXJlbnQgdGFzayB0byBjaGlsZCB0YXNrOgogKi8Kc3RhdGljIHN0cnVjdCBwZXJmX2V2ZW50ICoKaW5oZXJpdF9ldmVudChzdHJ1Y3QgcGVyZl9ldmVudCAqcGFyZW50X2V2ZW50LAoJICAgICAgc3RydWN0IHRhc2tfc3RydWN0ICpwYXJlbnQsCgkgICAgICBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpwYXJlbnRfY3R4LAoJICAgICAgc3RydWN0IHRhc2tfc3RydWN0ICpjaGlsZCwKCSAgICAgIHN0cnVjdCBwZXJmX2V2ZW50ICpncm91cF9sZWFkZXIsCgkgICAgICBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjaGlsZF9jdHgpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpjaGlsZF9ldmVudDsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJLyoKCSAqIEluc3RlYWQgb2YgY3JlYXRpbmcgcmVjdXJzaXZlIGhpZXJhcmNoaWVzIG9mIGV2ZW50cywKCSAqIHdlIGxpbmsgaW5oZXJpdGVkIGV2ZW50cyBiYWNrIHRvIHRoZSBvcmlnaW5hbCBwYXJlbnQsCgkgKiB3aGljaCBoYXMgYSBmaWxwIGZvciBzdXJlLCB3aGljaCB3ZSB1c2UgYXMgdGhlIHJlZmVyZW5jZQoJICogY291bnQ6CgkgKi8KCWlmIChwYXJlbnRfZXZlbnQtPnBhcmVudCkKCQlwYXJlbnRfZXZlbnQgPSBwYXJlbnRfZXZlbnQtPnBhcmVudDsKCgljaGlsZF9ldmVudCA9IHBlcmZfZXZlbnRfYWxsb2MoJnBhcmVudF9ldmVudC0+YXR0ciwKCQkJCQkgICBwYXJlbnRfZXZlbnQtPmNwdSwKCQkJCQkgICBjaGlsZCwKCQkJCQkgICBncm91cF9sZWFkZXIsIHBhcmVudF9ldmVudCwKCQkJCQkgICBOVUxMKTsKCWlmIChJU19FUlIoY2hpbGRfZXZlbnQpKQoJCXJldHVybiBjaGlsZF9ldmVudDsKCWdldF9jdHgoY2hpbGRfY3R4KTsKCgkvKgoJICogTWFrZSB0aGUgY2hpbGQgc3RhdGUgZm9sbG93IHRoZSBzdGF0ZSBvZiB0aGUgcGFyZW50IGV2ZW50LAoJICogbm90IGl0cyBhdHRyLmRpc2FibGVkIGJpdC4gIFdlIGhvbGQgdGhlIHBhcmVudCdzIG11dGV4LAoJICogc28gd2Ugd29uJ3QgcmFjZSB3aXRoIHBlcmZfZXZlbnRfe2VuLCBkaXN9YWJsZV9mYW1pbHkuCgkgKi8KCWlmIChwYXJlbnRfZXZlbnQtPnN0YXRlID49IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUpCgkJY2hpbGRfZXZlbnQtPnN0YXRlID0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRTsKCWVsc2UKCQljaGlsZF9ldmVudC0+c3RhdGUgPSBQRVJGX0VWRU5UX1NUQVRFX09GRjsKCglpZiAocGFyZW50X2V2ZW50LT5hdHRyLmZyZXEpIHsKCQl1NjQgc2FtcGxlX3BlcmlvZCA9IHBhcmVudF9ldmVudC0+aHcuc2FtcGxlX3BlcmlvZDsKCQlzdHJ1Y3QgaHdfcGVyZl9ldmVudCAqaHdjID0gJmNoaWxkX2V2ZW50LT5odzsKCgkJaHdjLT5zYW1wbGVfcGVyaW9kID0gc2FtcGxlX3BlcmlvZDsKCQlod2MtPmxhc3RfcGVyaW9kICAgPSBzYW1wbGVfcGVyaW9kOwoKCQlsb2NhbDY0X3NldCgmaHdjLT5wZXJpb2RfbGVmdCwgc2FtcGxlX3BlcmlvZCk7Cgl9CgoJY2hpbGRfZXZlbnQtPmN0eCA9IGNoaWxkX2N0eDsKCWNoaWxkX2V2ZW50LT5vdmVyZmxvd19oYW5kbGVyID0gcGFyZW50X2V2ZW50LT5vdmVyZmxvd19oYW5kbGVyOwoKCS8qCgkgKiBQcmVjYWxjdWxhdGUgc2FtcGxlX2RhdGEgc2l6ZXMKCSAqLwoJcGVyZl9ldmVudF9faGVhZGVyX3NpemUoY2hpbGRfZXZlbnQpOwoJcGVyZl9ldmVudF9faWRfaGVhZGVyX3NpemUoY2hpbGRfZXZlbnQpOwoKCS8qCgkgKiBMaW5rIGl0IHVwIGluIHRoZSBjaGlsZCdzIGNvbnRleHQ6CgkgKi8KCXJhd19zcGluX2xvY2tfaXJxc2F2ZSgmY2hpbGRfY3R4LT5sb2NrLCBmbGFncyk7CglhZGRfZXZlbnRfdG9fY3R4KGNoaWxkX2V2ZW50LCBjaGlsZF9jdHgpOwoJcmF3X3NwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNoaWxkX2N0eC0+bG9jaywgZmxhZ3MpOwoKCS8qCgkgKiBHZXQgYSByZWZlcmVuY2UgdG8gdGhlIHBhcmVudCBmaWxwIC0gd2Ugd2lsbCBmcHV0IGl0CgkgKiB3aGVuIHRoZSBjaGlsZCBldmVudCBleGl0cy4gVGhpcyBpcyBzYWZlIHRvIGRvIGJlY2F1c2UKCSAqIHdlIGFyZSBpbiB0aGUgcGFyZW50IGFuZCB3ZSBrbm93IHRoYXQgdGhlIGZpbHAgc3RpbGwKCSAqIGV4aXN0cyBhbmQgaGFzIGEgbm9uemVybyBjb3VudDoKCSAqLwoJYXRvbWljX2xvbmdfaW5jKCZwYXJlbnRfZXZlbnQtPmZpbHAtPmZfY291bnQpOwoKCS8qCgkgKiBMaW5rIHRoaXMgaW50byB0aGUgcGFyZW50IGV2ZW50J3MgY2hpbGQgbGlzdAoJICovCglXQVJOX09OX09OQ0UocGFyZW50X2V2ZW50LT5jdHgtPnBhcmVudF9jdHgpOwoJbXV0ZXhfbG9jaygmcGFyZW50X2V2ZW50LT5jaGlsZF9tdXRleCk7CglsaXN0X2FkZF90YWlsKCZjaGlsZF9ldmVudC0+Y2hpbGRfbGlzdCwgJnBhcmVudF9ldmVudC0+Y2hpbGRfbGlzdCk7CgltdXRleF91bmxvY2soJnBhcmVudF9ldmVudC0+Y2hpbGRfbXV0ZXgpOwoKCXJldHVybiBjaGlsZF9ldmVudDsKfQoKc3RhdGljIGludCBpbmhlcml0X2dyb3VwKHN0cnVjdCBwZXJmX2V2ZW50ICpwYXJlbnRfZXZlbnQsCgkgICAgICBzdHJ1Y3QgdGFza19zdHJ1Y3QgKnBhcmVudCwKCSAgICAgIHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKnBhcmVudF9jdHgsCgkgICAgICBzdHJ1Y3QgdGFza19zdHJ1Y3QgKmNoaWxkLAoJICAgICAgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY2hpbGRfY3R4KQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqbGVhZGVyOwoJc3RydWN0IHBlcmZfZXZlbnQgKnN1YjsKCXN0cnVjdCBwZXJmX2V2ZW50ICpjaGlsZF9jdHI7CgoJbGVhZGVyID0gaW5oZXJpdF9ldmVudChwYXJlbnRfZXZlbnQsIHBhcmVudCwgcGFyZW50X2N0eCwKCQkJCSBjaGlsZCwgTlVMTCwgY2hpbGRfY3R4KTsKCWlmIChJU19FUlIobGVhZGVyKSkKCQlyZXR1cm4gUFRSX0VSUihsZWFkZXIpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShzdWIsICZwYXJlbnRfZXZlbnQtPnNpYmxpbmdfbGlzdCwgZ3JvdXBfZW50cnkpIHsKCQljaGlsZF9jdHIgPSBpbmhlcml0X2V2ZW50KHN1YiwgcGFyZW50LCBwYXJlbnRfY3R4LAoJCQkJCSAgICBjaGlsZCwgbGVhZGVyLCBjaGlsZF9jdHgpOwoJCWlmIChJU19FUlIoY2hpbGRfY3RyKSkKCQkJcmV0dXJuIFBUUl9FUlIoY2hpbGRfY3RyKTsKCX0KCXJldHVybiAwOwp9CgpzdGF0aWMgaW50CmluaGVyaXRfdGFza19ncm91cChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIHN0cnVjdCB0YXNrX3N0cnVjdCAqcGFyZW50LAoJCSAgIHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKnBhcmVudF9jdHgsCgkJICAgc3RydWN0IHRhc2tfc3RydWN0ICpjaGlsZCwgaW50IGN0eG4sCgkJICAgaW50ICppbmhlcml0ZWRfYWxsKQp7CglpbnQgcmV0OwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY2hpbGRfY3R4OwoKCWlmICghZXZlbnQtPmF0dHIuaW5oZXJpdCkgewoJCSppbmhlcml0ZWRfYWxsID0gMDsKCQlyZXR1cm4gMDsKCX0KCgljaGlsZF9jdHggPSBjaGlsZC0+cGVyZl9ldmVudF9jdHhwW2N0eG5dOwoJaWYgKCFjaGlsZF9jdHgpIHsKCQkvKgoJCSAqIFRoaXMgaXMgZXhlY3V0ZWQgZnJvbSB0aGUgcGFyZW50IHRhc2sgY29udGV4dCwgc28KCQkgKiBpbmhlcml0IGV2ZW50cyB0aGF0IGhhdmUgYmVlbiBtYXJrZWQgZm9yIGNsb25pbmcuCgkJICogRmlyc3QgYWxsb2NhdGUgYW5kIGluaXRpYWxpemUgYSBjb250ZXh0IGZvciB0aGUKCQkgKiBjaGlsZC4KCQkgKi8KCgkJY2hpbGRfY3R4ID0gYWxsb2NfcGVyZl9jb250ZXh0KGV2ZW50LT5wbXUsIGNoaWxkKTsKCQlpZiAoIWNoaWxkX2N0eCkKCQkJcmV0dXJuIC1FTk9NRU07CgoJCWNoaWxkLT5wZXJmX2V2ZW50X2N0eHBbY3R4bl0gPSBjaGlsZF9jdHg7Cgl9CgoJcmV0ID0gaW5oZXJpdF9ncm91cChldmVudCwgcGFyZW50LCBwYXJlbnRfY3R4LAoJCQkgICAgY2hpbGQsIGNoaWxkX2N0eCk7CgoJaWYgKHJldCkKCQkqaW5oZXJpdGVkX2FsbCA9IDA7CgoJcmV0dXJuIHJldDsKfQoKLyoKICogSW5pdGlhbGl6ZSB0aGUgcGVyZl9ldmVudCBjb250ZXh0IGluIHRhc2tfc3RydWN0CiAqLwppbnQgcGVyZl9ldmVudF9pbml0X2NvbnRleHQoc3RydWN0IHRhc2tfc3RydWN0ICpjaGlsZCwgaW50IGN0eG4pCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmNoaWxkX2N0eCwgKnBhcmVudF9jdHg7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjbG9uZWRfY3R4OwoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoJc3RydWN0IHRhc2tfc3RydWN0ICpwYXJlbnQgPSBjdXJyZW50OwoJaW50IGluaGVyaXRlZF9hbGwgPSAxOwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCWludCByZXQgPSAwOwoKCWlmIChsaWtlbHkoIXBhcmVudC0+cGVyZl9ldmVudF9jdHhwW2N0eG5dKSkKCQlyZXR1cm4gMDsKCgkvKgoJICogSWYgdGhlIHBhcmVudCdzIGNvbnRleHQgaXMgYSBjbG9uZSwgcGluIGl0IHNvIGl0IHdvbid0IGdldAoJICogc3dhcHBlZCB1bmRlciB1cy4KCSAqLwoJcGFyZW50X2N0eCA9IHBlcmZfcGluX3Rhc2tfY29udGV4dChwYXJlbnQsIGN0eG4pOwoKCS8qCgkgKiBObyBuZWVkIHRvIGNoZWNrIGlmIHBhcmVudF9jdHggIT0gTlVMTCBoZXJlOyBzaW5jZSB3ZSBzYXcKCSAqIGl0IG5vbi1OVUxMIGVhcmxpZXIsIHRoZSBvbmx5IHJlYXNvbiBmb3IgaXQgdG8gYmVjb21lIE5VTEwKCSAqIGlzIGlmIHdlIGV4aXQsIGFuZCBzaW5jZSB3ZSdyZSBjdXJyZW50bHkgaW4gdGhlIG1pZGRsZSBvZgoJICogYSBmb3JrIHdlIGNhbid0IGJlIGV4aXRpbmcgYXQgdGhlIHNhbWUgdGltZS4KCSAqLwoKCS8qCgkgKiBMb2NrIHRoZSBwYXJlbnQgbGlzdC4gTm8gbmVlZCB0byBsb2NrIHRoZSBjaGlsZCAtIG5vdCBQSUQKCSAqIGhhc2hlZCB5ZXQgYW5kIG5vdCBydW5uaW5nLCBzbyBub2JvZHkgY2FuIGFjY2VzcyBpdC4KCSAqLwoJbXV0ZXhfbG9jaygmcGFyZW50X2N0eC0+bXV0ZXgpOwoKCS8qCgkgKiBXZSBkb250IGhhdmUgdG8gZGlzYWJsZSBOTUlzIC0gd2UgYXJlIG9ubHkgbG9va2luZyBhdAoJICogdGhlIGxpc3QsIG5vdCBtYW5pcHVsYXRpbmcgaXQ6CgkgKi8KCWxpc3RfZm9yX2VhY2hfZW50cnkoZXZlbnQsICZwYXJlbnRfY3R4LT5waW5uZWRfZ3JvdXBzLCBncm91cF9lbnRyeSkgewoJCXJldCA9IGluaGVyaXRfdGFza19ncm91cChldmVudCwgcGFyZW50LCBwYXJlbnRfY3R4LAoJCQkJCSBjaGlsZCwgY3R4biwgJmluaGVyaXRlZF9hbGwpOwoJCWlmIChyZXQpCgkJCWJyZWFrOwoJfQoKCS8qCgkgKiBXZSBjYW4ndCBob2xkIGN0eC0+bG9jayB3aGVuIGl0ZXJhdGluZyB0aGUgLT5mbGV4aWJsZV9ncm91cCBsaXN0IGR1ZQoJICogdG8gYWxsb2NhdGlvbnMsIGJ1dCB3ZSBuZWVkIHRvIHByZXZlbnQgcm90YXRpb24gYmVjYXVzZQoJICogcm90YXRlX2N0eCgpIHdpbGwgY2hhbmdlIHRoZSBsaXN0IGZyb20gaW50ZXJydXB0IGNvbnRleHQuCgkgKi8KCXJhd19zcGluX2xvY2tfaXJxc2F2ZSgmcGFyZW50X2N0eC0+bG9jaywgZmxhZ3MpOwoJcGFyZW50X2N0eC0+cm90YXRlX2Rpc2FibGUgPSAxOwoJcmF3X3NwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnBhcmVudF9jdHgtPmxvY2ssIGZsYWdzKTsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGV2ZW50LCAmcGFyZW50X2N0eC0+ZmxleGlibGVfZ3JvdXBzLCBncm91cF9lbnRyeSkgewoJCXJldCA9IGluaGVyaXRfdGFza19ncm91cChldmVudCwgcGFyZW50LCBwYXJlbnRfY3R4LAoJCQkJCSBjaGlsZCwgY3R4biwgJmluaGVyaXRlZF9hbGwpOwoJCWlmIChyZXQpCgkJCWJyZWFrOwoJfQoKCXJhd19zcGluX2xvY2tfaXJxc2F2ZSgmcGFyZW50X2N0eC0+bG9jaywgZmxhZ3MpOwoJcGFyZW50X2N0eC0+cm90YXRlX2Rpc2FibGUgPSAwOwoKCWNoaWxkX2N0eCA9IGNoaWxkLT5wZXJmX2V2ZW50X2N0eHBbY3R4bl07CgoJaWYgKGNoaWxkX2N0eCAmJiBpbmhlcml0ZWRfYWxsKSB7CgkJLyoKCQkgKiBNYXJrIHRoZSBjaGlsZCBjb250ZXh0IGFzIGEgY2xvbmUgb2YgdGhlIHBhcmVudAoJCSAqIGNvbnRleHQsIG9yIG9mIHdoYXRldmVyIHRoZSBwYXJlbnQgaXMgYSBjbG9uZSBvZi4KCQkgKgoJCSAqIE5vdGUgdGhhdCBpZiB0aGUgcGFyZW50IGlzIGEgY2xvbmUsIHRoZSBob2xkaW5nIG9mCgkJICogcGFyZW50X2N0eC0+bG9jayBhdm9pZHMgaXQgZnJvbSBiZWluZyB1bmNsb25lZC4KCQkgKi8KCQljbG9uZWRfY3R4ID0gcGFyZW50X2N0eC0+cGFyZW50X2N0eDsKCQlpZiAoY2xvbmVkX2N0eCkgewoJCQljaGlsZF9jdHgtPnBhcmVudF9jdHggPSBjbG9uZWRfY3R4OwoJCQljaGlsZF9jdHgtPnBhcmVudF9nZW4gPSBwYXJlbnRfY3R4LT5wYXJlbnRfZ2VuOwoJCX0gZWxzZSB7CgkJCWNoaWxkX2N0eC0+cGFyZW50X2N0eCA9IHBhcmVudF9jdHg7CgkJCWNoaWxkX2N0eC0+cGFyZW50X2dlbiA9IHBhcmVudF9jdHgtPmdlbmVyYXRpb247CgkJfQoJCWdldF9jdHgoY2hpbGRfY3R4LT5wYXJlbnRfY3R4KTsKCX0KCglyYXdfc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmcGFyZW50X2N0eC0+bG9jaywgZmxhZ3MpOwoJbXV0ZXhfdW5sb2NrKCZwYXJlbnRfY3R4LT5tdXRleCk7CgoJcGVyZl91bnBpbl9jb250ZXh0KHBhcmVudF9jdHgpOwoJcHV0X2N0eChwYXJlbnRfY3R4KTsKCglyZXR1cm4gcmV0Owp9CgovKgogKiBJbml0aWFsaXplIHRoZSBwZXJmX2V2ZW50IGNvbnRleHQgaW4gdGFza19zdHJ1Y3QKICovCmludCBwZXJmX2V2ZW50X2luaXRfdGFzayhzdHJ1Y3QgdGFza19zdHJ1Y3QgKmNoaWxkKQp7CglpbnQgY3R4biwgcmV0OwoKCW1lbXNldChjaGlsZC0+cGVyZl9ldmVudF9jdHhwLCAwLCBzaXplb2YoY2hpbGQtPnBlcmZfZXZlbnRfY3R4cCkpOwoJbXV0ZXhfaW5pdCgmY2hpbGQtPnBlcmZfZXZlbnRfbXV0ZXgpOwoJSU5JVF9MSVNUX0hFQUQoJmNoaWxkLT5wZXJmX2V2ZW50X2xpc3QpOwoKCWZvcl9lYWNoX3Rhc2tfY29udGV4dF9ucihjdHhuKSB7CgkJcmV0ID0gcGVyZl9ldmVudF9pbml0X2NvbnRleHQoY2hpbGQsIGN0eG4pOwoJCWlmIChyZXQpCgkJCXJldHVybiByZXQ7Cgl9CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIF9faW5pdCBwZXJmX2V2ZW50X2luaXRfYWxsX2NwdXModm9pZCkKewoJc3RydWN0IHN3ZXZlbnRfaHRhYmxlICpzd2hhc2g7CglpbnQgY3B1OwoKCWZvcl9lYWNoX3Bvc3NpYmxlX2NwdShjcHUpIHsKCQlzd2hhc2ggPSAmcGVyX2NwdShzd2V2ZW50X2h0YWJsZSwgY3B1KTsKCQltdXRleF9pbml0KCZzd2hhc2gtPmhsaXN0X211dGV4KTsKCQlJTklUX0xJU1RfSEVBRCgmcGVyX2NwdShyb3RhdGlvbl9saXN0LCBjcHUpKTsKCX0KfQoKc3RhdGljIHZvaWQgX19jcHVpbml0IHBlcmZfZXZlbnRfaW5pdF9jcHUoaW50IGNwdSkKewoJc3RydWN0IHN3ZXZlbnRfaHRhYmxlICpzd2hhc2ggPSAmcGVyX2NwdShzd2V2ZW50X2h0YWJsZSwgY3B1KTsKCgltdXRleF9sb2NrKCZzd2hhc2gtPmhsaXN0X211dGV4KTsKCWlmIChzd2hhc2gtPmhsaXN0X3JlZmNvdW50ID4gMCkgewoJCXN0cnVjdCBzd2V2ZW50X2hsaXN0ICpobGlzdDsKCgkJaGxpc3QgPSBremFsbG9jX25vZGUoc2l6ZW9mKCpobGlzdCksIEdGUF9LRVJORUwsIGNwdV90b19ub2RlKGNwdSkpOwoJCVdBUk5fT04oIWhsaXN0KTsKCQlyY3VfYXNzaWduX3BvaW50ZXIoc3doYXNoLT5zd2V2ZW50X2hsaXN0LCBobGlzdCk7Cgl9CgltdXRleF91bmxvY2soJnN3aGFzaC0+aGxpc3RfbXV0ZXgpOwp9CgojaWYgZGVmaW5lZCBDT05GSUdfSE9UUExVR19DUFUgfHwgZGVmaW5lZCBDT05GSUdfS0VYRUMKc3RhdGljIHZvaWQgcGVyZl9wbXVfcm90YXRlX3N0b3Aoc3RydWN0IHBtdSAqcG11KQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4ID0gdGhpc19jcHVfcHRyKHBtdS0+cG11X2NwdV9jb250ZXh0KTsKCglXQVJOX09OKCFpcnFzX2Rpc2FibGVkKCkpOwoKCWxpc3RfZGVsX2luaXQoJmNwdWN0eC0+cm90YXRpb25fbGlzdCk7Cn0KCnN0YXRpYyB2b2lkIF9fcGVyZl9ldmVudF9leGl0X2NvbnRleHQodm9pZCAqX19pbmZvKQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSBfX2luZm87CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsICp0bXA7CgoJcGVyZl9wbXVfcm90YXRlX3N0b3AoY3R4LT5wbXUpOwoKCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShldmVudCwgdG1wLCAmY3R4LT5waW5uZWRfZ3JvdXBzLCBncm91cF9lbnRyeSkKCQlfX3BlcmZfcmVtb3ZlX2Zyb21fY29udGV4dChldmVudCk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoZXZlbnQsIHRtcCwgJmN0eC0+ZmxleGlibGVfZ3JvdXBzLCBncm91cF9lbnRyeSkKCQlfX3BlcmZfcmVtb3ZlX2Zyb21fY29udGV4dChldmVudCk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfZXhpdF9jcHVfY29udGV4dChpbnQgY3B1KQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHg7CglzdHJ1Y3QgcG11ICpwbXU7CglpbnQgaWR4OwoKCWlkeCA9IHNyY3VfcmVhZF9sb2NrKCZwbXVzX3NyY3UpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeV9yY3UocG11LCAmcG11cywgZW50cnkpIHsKCQljdHggPSAmcGVyX2NwdV9wdHIocG11LT5wbXVfY3B1X2NvbnRleHQsIGNwdSktPmN0eDsKCgkJbXV0ZXhfbG9jaygmY3R4LT5tdXRleCk7CgkJc21wX2NhbGxfZnVuY3Rpb25fc2luZ2xlKGNwdSwgX19wZXJmX2V2ZW50X2V4aXRfY29udGV4dCwgY3R4LCAxKTsKCQltdXRleF91bmxvY2soJmN0eC0+bXV0ZXgpOwoJfQoJc3JjdV9yZWFkX3VubG9jaygmcG11c19zcmN1LCBpZHgpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X2V4aXRfY3B1KGludCBjcHUpCnsKCXN0cnVjdCBzd2V2ZW50X2h0YWJsZSAqc3doYXNoID0gJnBlcl9jcHUoc3dldmVudF9odGFibGUsIGNwdSk7CgoJbXV0ZXhfbG9jaygmc3doYXNoLT5obGlzdF9tdXRleCk7Cglzd2V2ZW50X2hsaXN0X3JlbGVhc2Uoc3doYXNoKTsKCW11dGV4X3VubG9jaygmc3doYXNoLT5obGlzdF9tdXRleCk7CgoJcGVyZl9ldmVudF9leGl0X2NwdV9jb250ZXh0KGNwdSk7Cn0KI2Vsc2UKc3RhdGljIGlubGluZSB2b2lkIHBlcmZfZXZlbnRfZXhpdF9jcHUoaW50IGNwdSkgeyB9CiNlbmRpZgoKc3RhdGljIGludApwZXJmX3JlYm9vdChzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgKm5vdGlmaWVyLCB1bnNpZ25lZCBsb25nIHZhbCwgdm9pZCAqdikKewoJaW50IGNwdTsKCglmb3JfZWFjaF9vbmxpbmVfY3B1KGNwdSkKCQlwZXJmX2V2ZW50X2V4aXRfY3B1KGNwdSk7CgoJcmV0dXJuIE5PVElGWV9PSzsKfQoKLyoKICogUnVuIHRoZSBwZXJmIHJlYm9vdCBub3RpZmllciBhdCB0aGUgdmVyeSBsYXN0IHBvc3NpYmxlIG1vbWVudCBzbyB0aGF0CiAqIHRoZSBnZW5lcmljIHdhdGNoZG9nIGNvZGUgcnVucyBhcyBsb25nIGFzIHBvc3NpYmxlLgogKi8Kc3RhdGljIHN0cnVjdCBub3RpZmllcl9ibG9jayBwZXJmX3JlYm9vdF9ub3RpZmllciA9IHsKCS5ub3RpZmllcl9jYWxsID0gcGVyZl9yZWJvb3QsCgkucHJpb3JpdHkgPSBJTlRfTUlOLAp9OwoKc3RhdGljIGludCBfX2NwdWluaXQKcGVyZl9jcHVfbm90aWZ5KHN0cnVjdCBub3RpZmllcl9ibG9jayAqc2VsZiwgdW5zaWduZWQgbG9uZyBhY3Rpb24sIHZvaWQgKmhjcHUpCnsKCXVuc2lnbmVkIGludCBjcHUgPSAobG9uZyloY3B1OwoKCXN3aXRjaCAoYWN0aW9uICYgfkNQVV9UQVNLU19GUk9aRU4pIHsKCgljYXNlIENQVV9VUF9QUkVQQVJFOgoJY2FzZSBDUFVfRE9XTl9GQUlMRUQ6CgkJcGVyZl9ldmVudF9pbml0X2NwdShjcHUpOwoJCWJyZWFrOwoKCWNhc2UgQ1BVX1VQX0NBTkNFTEVEOgoJY2FzZSBDUFVfRE9XTl9QUkVQQVJFOgoJCXBlcmZfZXZlbnRfZXhpdF9jcHUoY3B1KTsKCQlicmVhazsKCglkZWZhdWx0OgoJCWJyZWFrOwoJfQoKCXJldHVybiBOT1RJRllfT0s7Cn0KCnZvaWQgX19pbml0IHBlcmZfZXZlbnRfaW5pdCh2b2lkKQp7CglpbnQgcmV0OwoKCWlkcl9pbml0KCZwbXVfaWRyKTsKCglwZXJmX2V2ZW50X2luaXRfYWxsX2NwdXMoKTsKCWluaXRfc3JjdV9zdHJ1Y3QoJnBtdXNfc3JjdSk7CglwZXJmX3BtdV9yZWdpc3RlcigmcGVyZl9zd2V2ZW50LCAic29mdHdhcmUiLCBQRVJGX1RZUEVfU09GVFdBUkUpOwoJcGVyZl9wbXVfcmVnaXN0ZXIoJnBlcmZfY3B1X2Nsb2NrLCBOVUxMLCAtMSk7CglwZXJmX3BtdV9yZWdpc3RlcigmcGVyZl90YXNrX2Nsb2NrLCBOVUxMLCAtMSk7CglwZXJmX3RwX3JlZ2lzdGVyKCk7CglwZXJmX2NwdV9ub3RpZmllcihwZXJmX2NwdV9ub3RpZnkpOwoJcmVnaXN0ZXJfcmVib290X25vdGlmaWVyKCZwZXJmX3JlYm9vdF9ub3RpZmllcik7CgoJcmV0ID0gaW5pdF9od19icmVha3BvaW50KCk7CglXQVJOKHJldCwgImh3X2JyZWFrcG9pbnQgaW5pdGlhbGl6YXRpb24gZmFpbGVkIHdpdGg6ICVkIiwgcmV0KTsKfQoKc3RhdGljIGludCBfX2luaXQgcGVyZl9ldmVudF9zeXNmc19pbml0KHZvaWQpCnsKCXN0cnVjdCBwbXUgKnBtdTsKCWludCByZXQ7CgoJbXV0ZXhfbG9jaygmcG11c19sb2NrKTsKCglyZXQgPSBidXNfcmVnaXN0ZXIoJnBtdV9idXMpOwoJaWYgKHJldCkKCQlnb3RvIHVubG9jazsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5KHBtdSwgJnBtdXMsIGVudHJ5KSB7CgkJaWYgKCFwbXUtPm5hbWUgfHwgcG11LT50eXBlIDwgMCkKCQkJY29udGludWU7CgoJCXJldCA9IHBtdV9kZXZfYWxsb2MocG11KTsKCQlXQVJOKHJldCwgIkZhaWxlZCB0byByZWdpc3RlciBwbXU6ICVzLCByZWFzb24gJWRcbiIsIHBtdS0+bmFtZSwgcmV0KTsKCX0KCXBtdV9idXNfcnVubmluZyA9IDE7CglyZXQgPSAwOwoKdW5sb2NrOgoJbXV0ZXhfdW5sb2NrKCZwbXVzX2xvY2spOwoKCXJldHVybiByZXQ7Cn0KZGV2aWNlX2luaXRjYWxsKHBlcmZfZXZlbnRfc3lzZnNfaW5pdCk7Cg==