From mboxrd@z Thu Jan 1 00:00:00 1970 From: Alex Belits Subject: Re: [EXT] Re: [PATCH 06/12] task_isolation: arch/arm64: enable task isolation functionality Date: Sun, 8 Mar 2020 04:48:01 +0000 Message-ID: <3726a1fd89b12970d1bc79600d8fd6a9145bf5bc.camel@marvell.com> References: <4473787e1b6bc3cc226067e8d122092a678b63de.camel@marvell.com> <20200304163103.GJ3575@lakrids.cambridge.arm.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <20200304163103.GJ3575@lakrids.cambridge.arm.com> Content-Language: en-US Content-ID: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=m.gmane-mx.org@lists.infradead.org To: "mark.rutland@arm.com" Cc: "linux-arch@vger.kernel.org" , "catalin.marinas@arm.com" , "peterz@infradead.org" , Prasun Kapoor , "frederic@kernel.org" , "linux-kernel@vger.kernel.org" , "rostedt@goodmis.org" , "davem@davemloft.net" , "netdev@vger.kernel.org" , "linux-api@vger.kernel.org" , "tglx@linutronix.de" , "will@kernel.org" , "mingo@kernel.org" , "linux-arm-kernel@lists.infradead.org" List-Id: linux-arch.vger.kernel.org On Wed, 2020-03-04 at 16:31 +0000, Mark Rutland wrote: > Hi Alex, > > For patches affecting arm64, please CC LAKML and the arm64 > maintainers > (Will and Catalin). I've Cc'd the maintainers here. Thanks. Added them to Cc:. > > On Wed, Mar 04, 2020 at 04:10:28PM +0000, Alex Belits wrote: > > From: Chris Metcalf > > > > In do_notify_resume(), call task_isolation_start() for > > TIF_TASK_ISOLATION tasks. Add _TIF_TASK_ISOLATION to > > _TIF_WORK_MASK, > > and define a local NOTIFY_RESUME_LOOP_FLAGS to check in the loop, > > since we don't clear _TIF_TASK_ISOLATION in the loop. > > > > We tweak syscall_trace_enter() slightly to carry the "flags" > > value from current_thread_info()->flags for each of the tests, > > rather than doing a volatile read from memory for each one. This > > avoids a small overhead for each test, and in particular avoids > > that overhead for TIF_NOHZ when TASK_ISOLATION is not enabled. > > Stale commit message? > > Looking at the patch below, this doesn't seem to be the case; it just > calls test_thread_flag(TIF_TASK_ISOLATION). Right. I had to revert to a simple check to match the current implementation of this function. > We instrument the smp_send_reschedule() routine so that itchecks for > > isolated tasks and generates a suitable warning if needed. > > > > Finally, report on page faults in task-isolation processes in > > do_page_faults(). > > > > Signed-off-by: Alex Belits > > The From line says this was from Chris Metcalf, but he's missing from > the Sign-off chain here, which isn't right. I have posted updated patches with properly preserved sign-off lines and descriptions of updates. > > arch/arm64/include/asm/thread_info.h | 5 ++++- > > arch/arm64/kernel/ptrace.c | 10 ++++++++++ > > arch/arm64/kernel/signal.c | 13 ++++++++++++- > > arch/arm64/kernel/smp.c | 7 +++++++ > > arch/arm64/mm/fault.c | 5 +++++ > > 6 files changed, 39 insertions(+), 2 deletions(-) > > > > diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig > > index 0b30e884e088..93b6aabc8be9 100644 > > --- a/arch/arm64/Kconfig > > +++ b/arch/arm64/Kconfig > > @@ -129,6 +129,7 @@ config ARM64 > > select HAVE_ARCH_PREL32_RELOCATIONS > > select HAVE_ARCH_SECCOMP_FILTER > > select HAVE_ARCH_STACKLEAK > > + select HAVE_ARCH_TASK_ISOLATION > > select HAVE_ARCH_THREAD_STRUCT_WHITELIST > > select HAVE_ARCH_TRACEHOOK > > select HAVE_ARCH_TRANSPARENT_HUGEPAGE > > diff --git a/arch/arm64/include/asm/thread_info.h > > b/arch/arm64/include/asm/thread_info.h > > index f0cec4160136..7563098eb5b2 100644 > > --- a/arch/arm64/include/asm/thread_info.h > > +++ b/arch/arm64/include/asm/thread_info.h > > @@ -63,6 +63,7 @@ void arch_release_task_struct(struct task_struct > > *tsk); > > #define TIF_FOREIGN_FPSTATE 3 /* CPU's FP state is not > > current's */ > > #define TIF_UPROBE 4 /* uprobe breakpoint or singlestep > > */ > > #define TIF_FSCHECK 5 /* Check FS is USER_DS on > > return */ > > +#define TIF_TASK_ISOLATION 6 > > #define TIF_NOHZ 7 > > #define TIF_SYSCALL_TRACE 8 /* syscall trace active */ > > #define TIF_SYSCALL_AUDIT 9 /* syscall auditing */ > > @@ -83,6 +84,7 @@ void arch_release_task_struct(struct task_struct > > *tsk); > > #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) > > #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) > > #define _TIF_FOREIGN_FPSTATE (1 << TIF_FOREIGN_FPSTATE) > > +#define _TIF_TASK_ISOLATION (1 << TIF_TASK_ISOLATION) > > #define _TIF_NOHZ (1 << TIF_NOHZ) > > #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) > > #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) > > @@ -96,7 +98,8 @@ void arch_release_task_struct(struct task_struct > > *tsk); > > > > #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | > > _TIF_SIGPENDING | \ > > _TIF_NOTIFY_RESUME | > > _TIF_FOREIGN_FPSTATE | \ > > - _TIF_UPROBE | _TIF_FSCHECK) > > + _TIF_UPROBE | _TIF_FSCHECK | \ > > + _TIF_TASK_ISOLATION) > > > > #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | > > _TIF_SYSCALL_AUDIT | \ > > _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP > > | \ > > diff --git a/arch/arm64/kernel/ptrace.c > > b/arch/arm64/kernel/ptrace.c > > index cd6e5fa48b9c..b35b9b0c594c 100644 > > --- a/arch/arm64/kernel/ptrace.c > > +++ b/arch/arm64/kernel/ptrace.c > > @@ -29,6 +29,7 @@ > > #include > > #include > > #include > > +#include > > > > #include > > #include > > @@ -1836,6 +1837,15 @@ int syscall_trace_enter(struct pt_regs > > *regs) > > return -1; > > } > > > > + /* > > + * In task isolation mode, we may prevent the syscall from > > + * running, and if so we also deliver a signal to the process. > > + */ > > + if (test_thread_flag(TIF_TASK_ISOLATION)) { > > + if (task_isolation_syscall(regs->syscallno) == -1) > > + return -1; > > + } > > As above, this doesn't match the commit message. > > AFAICT, task_isolation_syscall() always returns either 0 or -1, which > isn't great as an API. I see secure_computing() seems to do the same, > and it'd be nice to clean that up to either be a real erro code or a > boolean. Boolean may make more sense considering that we are not dealing with errors returned by some operation the fact that calls were made from the wrong state. > > > > > + > > /* Do the secure computing after ptrace; failures should be > > fast. */ > > if (secure_computing() == -1) > > return -1; > > diff --git a/arch/arm64/kernel/signal.c > > b/arch/arm64/kernel/signal.c > > index 339882db5a91..d488c91a4877 100644 > > --- a/arch/arm64/kernel/signal.c > > +++ b/arch/arm64/kernel/signal.c > > @@ -20,6 +20,7 @@ > > #include > > #include > > #include > > +#include > > > > #include > > #include > > @@ -898,6 +899,11 @@ static void do_signal(struct pt_regs *regs) > > restore_saved_sigmask(); > > } > > > > +#define NOTIFY_RESUME_LOOP_FLAGS \ > > + (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \ > > + _TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE | \ > > + _TIF_UPROBE | _TIF_FSCHECK) > > + > > asmlinkage void do_notify_resume(struct pt_regs *regs, > > unsigned long thread_flags) > > { > > @@ -908,6 +914,8 @@ asmlinkage void do_notify_resume(struct pt_regs > > *regs, > > */ > > trace_hardirqs_off(); > > > > + task_isolation_check_run_cleanup(); > > + > > do { > > /* Check valid user FS if needed */ > > addr_limit_user_check(); > > @@ -938,7 +946,10 @@ asmlinkage void do_notify_resume(struct > > pt_regs *regs, > > > > local_daif_mask(); > > thread_flags = READ_ONCE(current_thread_info()->flags); > > - } while (thread_flags & _TIF_WORK_MASK); > > + } while (thread_flags & NOTIFY_RESUME_LOOP_FLAGS); > > + > > + if (thread_flags & _TIF_TASK_ISOLATION) > > + task_isolation_start(); > > } > > > > unsigned long __ro_after_init signal_minsigstksz; > > diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c > > index d4ed9a19d8fe..00f0f77adea0 100644 > > --- a/arch/arm64/kernel/smp.c > > +++ b/arch/arm64/kernel/smp.c > > @@ -32,6 +32,7 @@ > > #include > > #include > > #include > > +#include > > > > #include > > #include > > @@ -818,6 +819,7 @@ void arch_send_call_function_single_ipi(int > > cpu) > > #ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL > > void arch_send_wakeup_ipi_mask(const struct cpumask *mask) > > { > > + task_isolation_remote_cpumask(mask, "wakeup IPI"); > > smp_cross_call(mask, IPI_WAKEUP); > > } > > #endif > > @@ -886,6 +888,9 @@ void handle_IPI(int ipinr, struct pt_regs > > *regs) > > __inc_irq_stat(cpu, ipi_irqs[ipinr]); > > } > > > > + task_isolation_interrupt("IPI type %d (%s)", ipinr, > > + ipinr < NR_IPI ? ipi_types[ipinr] : > > "unknown"); > > + > > Are these tracing hooks? > > Surely they aren't necessary for functional correctness? This is necessary to properly break isolation and send a signal when something disturbed the isolated task, and to tell the user (likely a developer), why this happened. There are some legitimate reasons for breaking isolation (for example, a signal that terminates the process) and very large number of possible things that should not happen to an isolated task -- page fault caused by access to unmapped addresses, syscall issued by the task in isolated state, interrupt directed to the core running isolated task, timer remaining there, or kernel trying to run something on that core. It was very helpful to know what exactly happened, and if not this reporting, I would have hard time debugging the drivers and subsystems that called their functions and scheduled their threads all over the place. So both reliable breaking of isolation and reporting the cause is important. > > > switch (ipinr) { > > case IPI_RESCHEDULE: > > scheduler_ipi(); > > @@ -948,12 +953,14 @@ void handle_IPI(int ipinr, struct pt_regs > > *regs) > > > > void smp_send_reschedule(int cpu) > > { > > + task_isolation_remote(cpu, "reschedule IPI"); > > smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE); > > } > > > > #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST > > void tick_broadcast(const struct cpumask *mask) > > { > > + task_isolation_remote_cpumask(mask, "timer IPI"); > > smp_cross_call(mask, IPI_TIMER); > > } > > #endif > > diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c > > index 85566d32958f..fc4b42c81c4f 100644 > > --- a/arch/arm64/mm/fault.c > > +++ b/arch/arm64/mm/fault.c > > @@ -23,6 +23,7 @@ > > #include > > #include > > #include > > +#include > > > > #include > > #include > > @@ -543,6 +544,10 @@ static int __kprobes do_page_fault(unsigned > > long addr, unsigned int esr, > > */ > > if (likely(!(fault & (VM_FAULT_ERROR | VM_FAULT_BADMAP | > > VM_FAULT_BADACCESS)))) { > > + /* No signal was generated, but notify task-isolation > > tasks. */ > > + if (user_mode(regs)) > > + task_isolation_interrupt("page fault at %#lx", > > addr); > > + > > We check user_mode(regs) much earlier in this function to set > FAULT_FLAG_USER. Is there some reason this cannot live there? > > Also, this seems to be a tracing hook -- is this necessary? This is another point where task isolation state is broken, task receives a signal and the reason is logged. If not isolation, task would not know that anything happened, but it is important for isolation. In general if isolated task is supposed to be running on a CPU core, it has to stay in userspace. So if for some reason a kernel code is running on that CPU core, this is either a task leaving isolation on its own or isolation is broken and the task should be notified about it. The only problem is how to properly and reliably explain why this happened. Thanks! -- Alex From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx0b-0016f401.pphosted.com ([67.231.156.173]:53006 "EHLO mx0b-0016f401.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726259AbgCHEsz (ORCPT ); Sat, 7 Mar 2020 23:48:55 -0500 From: Alex Belits Subject: Re: [EXT] Re: [PATCH 06/12] task_isolation: arch/arm64: enable task isolation functionality Date: Sun, 8 Mar 2020 04:48:01 +0000 Message-ID: <3726a1fd89b12970d1bc79600d8fd6a9145bf5bc.camel@marvell.com> References: <4473787e1b6bc3cc226067e8d122092a678b63de.camel@marvell.com> <20200304163103.GJ3575@lakrids.cambridge.arm.com> In-Reply-To: <20200304163103.GJ3575@lakrids.cambridge.arm.com> Content-Language: en-US Content-Type: text/plain; charset="utf-8" Content-ID: Content-Transfer-Encoding: base64 MIME-Version: 1.0 Sender: linux-arch-owner@vger.kernel.org List-ID: To: "mark.rutland@arm.com" Cc: "mingo@kernel.org" , "peterz@infradead.org" , "rostedt@goodmis.org" , "frederic@kernel.org" , Prasun Kapoor , "tglx@linutronix.de" , "linux-api@vger.kernel.org" , "linux-kernel@vger.kernel.org" , "catalin.marinas@arm.com" , "linux-arm-kernel@lists.infradead.org" , "netdev@vger.kernel.org" , "davem@davemloft.net" , "linux-arch@vger.kernel.org" , "will@kernel.org" Message-ID: <20200308044801.aN_NE9aivgMv8lmlrNHpHlljeJ0FOVhaRgx83rmttUU@z> T24gV2VkLCAyMDIwLTAzLTA0IGF0IDE2OjMxICswMDAwLCBNYXJrIFJ1dGxhbmQgd3JvdGU6DQo+ IEhpIEFsZXgsDQo+IA0KPiBGb3IgcGF0Y2hlcyBhZmZlY3RpbmcgYXJtNjQsIHBsZWFzZSBDQyBM QUtNTCBhbmQgdGhlIGFybTY0DQo+IG1haW50YWluZXJzDQo+IChXaWxsIGFuZCBDYXRhbGluKS4g SSd2ZSBDYydkIHRoZSBtYWludGFpbmVycyBoZXJlLg0KDQpUaGFua3MuIEFkZGVkIHRoZW0gdG8g Q2M6Lg0KDQo+IA0KPiBPbiBXZWQsIE1hciAwNCwgMjAyMCBhdCAwNDoxMDoyOFBNICswMDAwLCBB bGV4IEJlbGl0cyB3cm90ZToNCj4gPiBGcm9tOiBDaHJpcyBNZXRjYWxmIDxjbWV0Y2FsZkBtZWxs YW5veC5jb20+DQo+ID4gDQo+ID4gSW4gZG9fbm90aWZ5X3Jlc3VtZSgpLCBjYWxsIHRhc2tfaXNv bGF0aW9uX3N0YXJ0KCkgZm9yDQo+ID4gVElGX1RBU0tfSVNPTEFUSU9OIHRhc2tzLiBBZGQgX1RJ Rl9UQVNLX0lTT0xBVElPTiB0bw0KPiA+IF9USUZfV09SS19NQVNLLA0KPiA+IGFuZCBkZWZpbmUg YSBsb2NhbCBOT1RJRllfUkVTVU1FX0xPT1BfRkxBR1MgdG8gY2hlY2sgaW4gdGhlIGxvb3AsDQo+ ID4gc2luY2Ugd2UgZG9uJ3QgY2xlYXIgX1RJRl9UQVNLX0lTT0xBVElPTiBpbiB0aGUgbG9vcC4N Cj4gPiANCj4gPiBXZSB0d2VhayBzeXNjYWxsX3RyYWNlX2VudGVyKCkgc2xpZ2h0bHkgdG8gY2Fy cnkgdGhlICJmbGFncyINCj4gPiB2YWx1ZSBmcm9tIGN1cnJlbnRfdGhyZWFkX2luZm8oKS0+Zmxh Z3MgZm9yIGVhY2ggb2YgdGhlIHRlc3RzLA0KPiA+IHJhdGhlciB0aGFuIGRvaW5nIGEgdm9sYXRp bGUgcmVhZCBmcm9tIG1lbW9yeSBmb3IgZWFjaCBvbmUuIFRoaXMNCj4gPiBhdm9pZHMgYSBzbWFs bCBvdmVyaGVhZCBmb3IgZWFjaCB0ZXN0LCBhbmQgaW4gcGFydGljdWxhciBhdm9pZHMNCj4gPiB0 aGF0IG92ZXJoZWFkIGZvciBUSUZfTk9IWiB3aGVuIFRBU0tfSVNPTEFUSU9OIGlzIG5vdCBlbmFi bGVkLg0KPiANCj4gU3RhbGUgY29tbWl0IG1lc3NhZ2U/DQo+IA0KPiBMb29raW5nIGF0IHRoZSBw YXRjaCBiZWxvdywgdGhpcyBkb2Vzbid0IHNlZW0gdG8gYmUgdGhlIGNhc2U7IGl0IGp1c3QNCj4g Y2FsbHMgdGVzdF90aHJlYWRfZmxhZyhUSUZfVEFTS19JU09MQVRJT04pLg0KDQpSaWdodC4gSSBo YWQgdG8gcmV2ZXJ0IHRvIGEgc2ltcGxlIGNoZWNrIHRvIG1hdGNoIHRoZSBjdXJyZW50DQppbXBs ZW1lbnRhdGlvbiBvZiB0aGlzIGZ1bmN0aW9uLg0KDQo+IA0KV2UgaW5zdHJ1bWVudCB0aGUgc21w X3NlbmRfcmVzY2hlZHVsZSgpIHJvdXRpbmUgc28gdGhhdA0KaXRjaGVja3MgZm9yDQo+ID4gaXNv bGF0ZWQgdGFza3MgYW5kIGdlbmVyYXRlcyBhIHN1aXRhYmxlIHdhcm5pbmcgaWYgbmVlZGVkLg0K PiA+IA0KPiA+IEZpbmFsbHksIHJlcG9ydCBvbiBwYWdlIGZhdWx0cyBpbiB0YXNrLWlzb2xhdGlv biBwcm9jZXNzZXMgaW4NCj4gPiBkb19wYWdlX2ZhdWx0cygpLg0KPiA+IA0KPiA+IFNpZ25lZC1v ZmYtYnk6IEFsZXggQmVsaXRzIDxhYmVsaXRzQG1hcnZlbGwuY29tPg0KPiANCj4gVGhlIEZyb20g bGluZSBzYXlzIHRoaXMgd2FzIGZyb20gQ2hyaXMgTWV0Y2FsZiwgYnV0IGhlJ3MgbWlzc2luZyBm cm9tDQo+IHRoZSBTaWduLW9mZiBjaGFpbiBoZXJlLCB3aGljaCBpc24ndCByaWdodC4NCg0KSSBo YXZlIHBvc3RlZCB1cGRhdGVkIHBhdGNoZXMgd2l0aCBwcm9wZXJseSBwcmVzZXJ2ZWQgc2lnbi1v ZmYgbGluZXMNCmFuZCBkZXNjcmlwdGlvbnMgb2YgdXBkYXRlcy4NCg0KPiA+ICBhcmNoL2FybTY0 L2luY2x1ZGUvYXNtL3RocmVhZF9pbmZvLmggfCAgNSArKysrLQ0KPiA+ICBhcmNoL2FybTY0L2tl cm5lbC9wdHJhY2UuYyAgICAgICAgICAgfCAxMCArKysrKysrKysrDQo+ID4gIGFyY2gvYXJtNjQv a2VybmVsL3NpZ25hbC5jICAgICAgICAgICB8IDEzICsrKysrKysrKysrKy0NCj4gPiAgYXJjaC9h cm02NC9rZXJuZWwvc21wLmMgICAgICAgICAgICAgIHwgIDcgKysrKysrKw0KPiA+ICBhcmNoL2Fy bTY0L21tL2ZhdWx0LmMgICAgICAgICAgICAgICAgfCAgNSArKysrKw0KPiA+ICA2IGZpbGVzIGNo YW5nZWQsIDM5IGluc2VydGlvbnMoKyksIDIgZGVsZXRpb25zKC0pDQo+ID4gDQo+ID4gZGlmZiAt LWdpdCBhL2FyY2gvYXJtNjQvS2NvbmZpZyBiL2FyY2gvYXJtNjQvS2NvbmZpZw0KPiA+IGluZGV4 IDBiMzBlODg0ZTA4OC4uOTNiNmFhYmM4YmU5IDEwMDY0NA0KPiA+IC0tLSBhL2FyY2gvYXJtNjQv S2NvbmZpZw0KPiA+ICsrKyBiL2FyY2gvYXJtNjQvS2NvbmZpZw0KPiA+IEBAIC0xMjksNiArMTI5 LDcgQEAgY29uZmlnIEFSTTY0DQo+ID4gIAlzZWxlY3QgSEFWRV9BUkNIX1BSRUwzMl9SRUxPQ0FU SU9OUw0KPiA+ICAJc2VsZWN0IEhBVkVfQVJDSF9TRUNDT01QX0ZJTFRFUg0KPiA+ICAJc2VsZWN0 IEhBVkVfQVJDSF9TVEFDS0xFQUsNCj4gPiArCXNlbGVjdCBIQVZFX0FSQ0hfVEFTS19JU09MQVRJ T04NCj4gPiAgCXNlbGVjdCBIQVZFX0FSQ0hfVEhSRUFEX1NUUlVDVF9XSElURUxJU1QNCj4gPiAg CXNlbGVjdCBIQVZFX0FSQ0hfVFJBQ0VIT09LDQo+ID4gIAlzZWxlY3QgSEFWRV9BUkNIX1RSQU5T UEFSRU5UX0hVR0VQQUdFDQo+ID4gZGlmZiAtLWdpdCBhL2FyY2gvYXJtNjQvaW5jbHVkZS9hc20v dGhyZWFkX2luZm8uaA0KPiA+IGIvYXJjaC9hcm02NC9pbmNsdWRlL2FzbS90aHJlYWRfaW5mby5o DQo+ID4gaW5kZXggZjBjZWM0MTYwMTM2Li43NTYzMDk4ZWI1YjIgMTAwNjQ0DQo+ID4gLS0tIGEv YXJjaC9hcm02NC9pbmNsdWRlL2FzbS90aHJlYWRfaW5mby5oDQo+ID4gKysrIGIvYXJjaC9hcm02 NC9pbmNsdWRlL2FzbS90aHJlYWRfaW5mby5oDQo+ID4gQEAgLTYzLDYgKzYzLDcgQEAgdm9pZCBh cmNoX3JlbGVhc2VfdGFza19zdHJ1Y3Qoc3RydWN0IHRhc2tfc3RydWN0DQo+ID4gKnRzayk7DQo+ ID4gICNkZWZpbmUgVElGX0ZPUkVJR05fRlBTVEFURQkzCS8qIENQVSdzIEZQIHN0YXRlIGlzIG5v dA0KPiA+IGN1cnJlbnQncyAqLw0KPiA+ICAjZGVmaW5lIFRJRl9VUFJPQkUJCTQJLyogdXByb2Jl IGJyZWFrcG9pbnQgb3Igc2luZ2xlc3RlcA0KPiA+ICovDQo+ID4gICNkZWZpbmUgVElGX0ZTQ0hF Q0sJCTUJLyogQ2hlY2sgRlMgaXMgVVNFUl9EUyBvbg0KPiA+IHJldHVybiAqLw0KPiA+ICsjZGVm aW5lIFRJRl9UQVNLX0lTT0xBVElPTgk2DQo+ID4gICNkZWZpbmUgVElGX05PSFoJCTcNCj4gPiAg I2RlZmluZSBUSUZfU1lTQ0FMTF9UUkFDRQk4CS8qIHN5c2NhbGwgdHJhY2UgYWN0aXZlICovDQo+ ID4gICNkZWZpbmUgVElGX1NZU0NBTExfQVVESVQJOQkvKiBzeXNjYWxsIGF1ZGl0aW5nICovDQo+ ID4gQEAgLTgzLDYgKzg0LDcgQEAgdm9pZCBhcmNoX3JlbGVhc2VfdGFza19zdHJ1Y3Qoc3RydWN0 IHRhc2tfc3RydWN0DQo+ID4gKnRzayk7DQo+ID4gICNkZWZpbmUgX1RJRl9ORUVEX1JFU0NIRUQJ KDEgPDwgVElGX05FRURfUkVTQ0hFRCkNCj4gPiAgI2RlZmluZSBfVElGX05PVElGWV9SRVNVTUUJ KDEgPDwgVElGX05PVElGWV9SRVNVTUUpDQo+ID4gICNkZWZpbmUgX1RJRl9GT1JFSUdOX0ZQU1RB VEUJKDEgPDwgVElGX0ZPUkVJR05fRlBTVEFURSkNCj4gPiArI2RlZmluZSBfVElGX1RBU0tfSVNP TEFUSU9OCSgxIDw8IFRJRl9UQVNLX0lTT0xBVElPTikNCj4gPiAgI2RlZmluZSBfVElGX05PSFoJ CSgxIDw8IFRJRl9OT0haKQ0KPiA+ICAjZGVmaW5lIF9USUZfU1lTQ0FMTF9UUkFDRQkoMSA8PCBU SUZfU1lTQ0FMTF9UUkFDRSkNCj4gPiAgI2RlZmluZSBfVElGX1NZU0NBTExfQVVESVQJKDEgPDwg VElGX1NZU0NBTExfQVVESVQpDQo+ID4gQEAgLTk2LDcgKzk4LDggQEAgdm9pZCBhcmNoX3JlbGVh c2VfdGFza19zdHJ1Y3Qoc3RydWN0IHRhc2tfc3RydWN0DQo+ID4gKnRzayk7DQo+ID4gIA0KPiA+ ICAjZGVmaW5lIF9USUZfV09SS19NQVNLCQkoX1RJRl9ORUVEX1JFU0NIRUQgfA0KPiA+IF9USUZf U0lHUEVORElORyB8IFwNCj4gPiAgCQkJCSBfVElGX05PVElGWV9SRVNVTUUgfA0KPiA+IF9USUZf Rk9SRUlHTl9GUFNUQVRFIHwgXA0KPiA+IC0JCQkJIF9USUZfVVBST0JFIHwgX1RJRl9GU0NIRUNL KQ0KPiA+ICsJCQkJIF9USUZfVVBST0JFIHwgX1RJRl9GU0NIRUNLIHwgXA0KPiA+ICsJCQkJIF9U SUZfVEFTS19JU09MQVRJT04pDQo+ID4gIA0KPiA+ICAjZGVmaW5lIF9USUZfU1lTQ0FMTF9XT1JL CShfVElGX1NZU0NBTExfVFJBQ0UgfA0KPiA+IF9USUZfU1lTQ0FMTF9BVURJVCB8IFwNCj4gPiAg CQkJCSBfVElGX1NZU0NBTExfVFJBQ0VQT0lOVCB8IF9USUZfU0VDQ09NUA0KPiA+IHwgXA0KPiA+ IGRpZmYgLS1naXQgYS9hcmNoL2FybTY0L2tlcm5lbC9wdHJhY2UuYw0KPiA+IGIvYXJjaC9hcm02 NC9rZXJuZWwvcHRyYWNlLmMNCj4gPiBpbmRleCBjZDZlNWZhNDhiOWMuLmIzNWI5YjBjNTk0YyAx MDA2NDQNCj4gPiAtLS0gYS9hcmNoL2FybTY0L2tlcm5lbC9wdHJhY2UuYw0KPiA+ICsrKyBiL2Fy Y2gvYXJtNjQva2VybmVsL3B0cmFjZS5jDQo+ID4gQEAgLTI5LDYgKzI5LDcgQEANCj4gPiAgI2lu Y2x1ZGUgPGxpbnV4L3JlZ3NldC5oPg0KPiA+ICAjaW5jbHVkZSA8bGludXgvdHJhY2Vob29rLmg+ DQo+ID4gICNpbmNsdWRlIDxsaW51eC9lbGYuaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L2lzb2xh dGlvbi5oPg0KPiA+ICANCj4gPiAgI2luY2x1ZGUgPGFzbS9jb21wYXQuaD4NCj4gPiAgI2luY2x1 ZGUgPGFzbS9jcHVmZWF0dXJlLmg+DQo+ID4gQEAgLTE4MzYsNiArMTgzNywxNSBAQCBpbnQgc3lz Y2FsbF90cmFjZV9lbnRlcihzdHJ1Y3QgcHRfcmVncw0KPiA+ICpyZWdzKQ0KPiA+ICAJCQlyZXR1 cm4gLTE7DQo+ID4gIAl9DQo+ID4gIA0KPiA+ICsJLyoNCj4gPiArCSAqIEluIHRhc2sgaXNvbGF0 aW9uIG1vZGUsIHdlIG1heSBwcmV2ZW50IHRoZSBzeXNjYWxsIGZyb20NCj4gPiArCSAqIHJ1bm5p bmcsIGFuZCBpZiBzbyB3ZSBhbHNvIGRlbGl2ZXIgYSBzaWduYWwgdG8gdGhlIHByb2Nlc3MuDQo+ ID4gKwkgKi8NCj4gPiArCWlmICh0ZXN0X3RocmVhZF9mbGFnKFRJRl9UQVNLX0lTT0xBVElPTikp IHsNCj4gPiArCQlpZiAodGFza19pc29sYXRpb25fc3lzY2FsbChyZWdzLT5zeXNjYWxsbm8pID09 IC0xKQ0KPiA+ICsJCQlyZXR1cm4gLTE7DQo+ID4gKwl9DQo+IA0KPiBBcyBhYm92ZSwgdGhpcyBk b2Vzbid0IG1hdGNoIHRoZSBjb21taXQgbWVzc2FnZS4NCj4gDQo+IEFGQUlDVCwgdGFza19pc29s YXRpb25fc3lzY2FsbCgpIGFsd2F5cyByZXR1cm5zIGVpdGhlciAwIG9yIC0xLCB3aGljaA0KPiBp c24ndCBncmVhdCBhcyBhbiBBUEkuIEkgc2VlIHNlY3VyZV9jb21wdXRpbmcoKSBzZWVtcyB0byBk byB0aGUgc2FtZSwNCj4gYW5kIGl0J2QgYmUgbmljZSB0byBjbGVhbiB0aGF0IHVwIHRvIGVpdGhl ciBiZSBhIHJlYWwgZXJybyBjb2RlIG9yIGENCj4gYm9vbGVhbi4NCg0KQm9vbGVhbiBtYXkgbWFr ZSBtb3JlIHNlbnNlIGNvbnNpZGVyaW5nIHRoYXQgd2UgYXJlIG5vdCBkZWFsaW5nIHdpdGgNCmVy cm9ycyByZXR1cm5lZCBieSBzb21lIG9wZXJhdGlvbiB0aGUgZmFjdCB0aGF0IGNhbGxzIHdlcmUg bWFkZSBmcm9tDQp0aGUgd3Jvbmcgc3RhdGUuDQoNCj4gDQoNCj4gPiA+ID4gKw0KPiA+ICAJLyog RG8gdGhlIHNlY3VyZSBjb21wdXRpbmcgYWZ0ZXIgcHRyYWNlOyBmYWlsdXJlcyBzaG91bGQgYmUN Cj4gPiBmYXN0LiAqLw0KPiA+ICAJaWYgKHNlY3VyZV9jb21wdXRpbmcoKSA9PSAtMSkNCj4gPiAg CQlyZXR1cm4gLTE7DQo+ID4gZGlmZiAtLWdpdCBhL2FyY2gvYXJtNjQva2VybmVsL3NpZ25hbC5j DQo+ID4gYi9hcmNoL2FybTY0L2tlcm5lbC9zaWduYWwuYw0KPiA+IGluZGV4IDMzOTg4MmRiNWE5 MS4uZDQ4OGM5MWE0ODc3IDEwMDY0NA0KPiA+IC0tLSBhL2FyY2gvYXJtNjQva2VybmVsL3NpZ25h bC5jDQo+ID4gKysrIGIvYXJjaC9hcm02NC9rZXJuZWwvc2lnbmFsLmMNCj4gPiBAQCAtMjAsNiAr MjAsNyBAQA0KPiA+ICAjaW5jbHVkZSA8bGludXgvdHJhY2Vob29rLmg+DQo+ID4gICNpbmNsdWRl IDxsaW51eC9yYXRlbGltaXQuaD4NCj4gPiAgI2luY2x1ZGUgPGxpbnV4L3N5c2NhbGxzLmg+DQo+ ID4gKyNpbmNsdWRlIDxsaW51eC9pc29sYXRpb24uaD4NCj4gPiAgDQo+ID4gICNpbmNsdWRlIDxh c20vZGFpZmZsYWdzLmg+DQo+ID4gICNpbmNsdWRlIDxhc20vZGVidWctbW9uaXRvcnMuaD4NCj4g PiBAQCAtODk4LDYgKzg5OSwxMSBAQCBzdGF0aWMgdm9pZCBkb19zaWduYWwoc3RydWN0IHB0X3Jl Z3MgKnJlZ3MpDQo+ID4gIAlyZXN0b3JlX3NhdmVkX3NpZ21hc2soKTsNCj4gPiAgfQ0KPiA+ICAN Cj4gPiArI2RlZmluZSBOT1RJRllfUkVTVU1FX0xPT1BfRkxBR1MgXA0KPiA+ICsJKF9USUZfTkVF RF9SRVNDSEVEIHwgX1RJRl9TSUdQRU5ESU5HIHwgXA0KPiA+ICsJX1RJRl9OT1RJRllfUkVTVU1F IHwgX1RJRl9GT1JFSUdOX0ZQU1RBVEUgfCBcDQo+ID4gKwlfVElGX1VQUk9CRSB8IF9USUZfRlND SEVDSykNCj4gPiArDQo+ID4gIGFzbWxpbmthZ2Ugdm9pZCBkb19ub3RpZnlfcmVzdW1lKHN0cnVj dCBwdF9yZWdzICpyZWdzLA0KPiA+ICAJCQkJIHVuc2lnbmVkIGxvbmcgdGhyZWFkX2ZsYWdzKQ0K PiA+ICB7DQo+ID4gQEAgLTkwOCw2ICs5MTQsOCBAQCBhc21saW5rYWdlIHZvaWQgZG9fbm90aWZ5 X3Jlc3VtZShzdHJ1Y3QgcHRfcmVncw0KPiA+ICpyZWdzLA0KPiA+ICAJICovDQo+ID4gIAl0cmFj ZV9oYXJkaXJxc19vZmYoKTsNCj4gPiAgDQo+ID4gKwl0YXNrX2lzb2xhdGlvbl9jaGVja19ydW5f Y2xlYW51cCgpOw0KPiA+ICsNCj4gPiAgCWRvIHsNCj4gPiAgCQkvKiBDaGVjayB2YWxpZCB1c2Vy IEZTIGlmIG5lZWRlZCAqLw0KPiA+ICAJCWFkZHJfbGltaXRfdXNlcl9jaGVjaygpOw0KPiA+IEBA IC05MzgsNyArOTQ2LDEwIEBAIGFzbWxpbmthZ2Ugdm9pZCBkb19ub3RpZnlfcmVzdW1lKHN0cnVj dA0KPiA+IHB0X3JlZ3MgKnJlZ3MsDQo+ID4gIA0KPiA+ICAJCWxvY2FsX2RhaWZfbWFzaygpOw0K PiA+ICAJCXRocmVhZF9mbGFncyA9IFJFQURfT05DRShjdXJyZW50X3RocmVhZF9pbmZvKCktPmZs YWdzKTsNCj4gPiAtCX0gd2hpbGUgKHRocmVhZF9mbGFncyAmIF9USUZfV09SS19NQVNLKTsNCj4g PiArCX0gd2hpbGUgKHRocmVhZF9mbGFncyAmIE5PVElGWV9SRVNVTUVfTE9PUF9GTEFHUyk7DQo+ ID4gKw0KPiA+ICsJaWYgKHRocmVhZF9mbGFncyAmIF9USUZfVEFTS19JU09MQVRJT04pDQo+ID4g KwkJdGFza19pc29sYXRpb25fc3RhcnQoKTsNCj4gPiAgfQ0KPiA+ICANCj4gPiAgdW5zaWduZWQg bG9uZyBfX3JvX2FmdGVyX2luaXQgc2lnbmFsX21pbnNpZ3N0a3N6Ow0KPiA+IGRpZmYgLS1naXQg YS9hcmNoL2FybTY0L2tlcm5lbC9zbXAuYyBiL2FyY2gvYXJtNjQva2VybmVsL3NtcC5jDQo+ID4g aW5kZXggZDRlZDlhMTlkOGZlLi4wMGYwZjc3YWRlYTAgMTAwNjQ0DQo+ID4gLS0tIGEvYXJjaC9h cm02NC9rZXJuZWwvc21wLmMNCj4gPiArKysgYi9hcmNoL2FybTY0L2tlcm5lbC9zbXAuYw0KPiA+ IEBAIC0zMiw2ICszMiw3IEBADQo+ID4gICNpbmNsdWRlIDxsaW51eC9pcnFfd29yay5oPg0KPiA+ ICAjaW5jbHVkZSA8bGludXgva2V4ZWMuaD4NCj4gPiAgI2luY2x1ZGUgPGxpbnV4L2t2bV9ob3N0 Lmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9pc29sYXRpb24uaD4NCj4gPiAgDQo+ID4gICNpbmNs dWRlIDxhc20vYWx0ZXJuYXRpdmUuaD4NCj4gPiAgI2luY2x1ZGUgPGFzbS9hdG9taWMuaD4NCj4g PiBAQCAtODE4LDYgKzgxOSw3IEBAIHZvaWQgYXJjaF9zZW5kX2NhbGxfZnVuY3Rpb25fc2luZ2xl X2lwaShpbnQNCj4gPiBjcHUpDQo+ID4gICNpZmRlZiBDT05GSUdfQVJNNjRfQUNQSV9QQVJLSU5H X1BST1RPQ09MDQo+ID4gIHZvaWQgYXJjaF9zZW5kX3dha2V1cF9pcGlfbWFzayhjb25zdCBzdHJ1 Y3QgY3B1bWFzayAqbWFzaykNCj4gPiAgew0KPiA+ICsJdGFza19pc29sYXRpb25fcmVtb3RlX2Nw dW1hc2sobWFzaywgIndha2V1cCBJUEkiKTsNCj4gPiAgCXNtcF9jcm9zc19jYWxsKG1hc2ssIElQ SV9XQUtFVVApOw0KPiA+ICB9DQo+ID4gICNlbmRpZg0KPiA+IEBAIC04ODYsNiArODg4LDkgQEAg dm9pZCBoYW5kbGVfSVBJKGludCBpcGluciwgc3RydWN0IHB0X3JlZ3MNCj4gPiAqcmVncykNCj4g PiAgCQlfX2luY19pcnFfc3RhdChjcHUsIGlwaV9pcnFzW2lwaW5yXSk7DQo+ID4gIAl9DQo+ID4g IA0KPiA+ICsJdGFza19pc29sYXRpb25faW50ZXJydXB0KCJJUEkgdHlwZSAlZCAoJXMpIiwgaXBp bnIsDQo+ID4gKwkJCQkgaXBpbnIgPCBOUl9JUEkgPyBpcGlfdHlwZXNbaXBpbnJdIDoNCj4gPiAi dW5rbm93biIpOw0KPiA+ICsNCj4gDQo+IEFyZSB0aGVzZSB0cmFjaW5nIGhvb2tzPw0KPiANCj4g U3VyZWx5IHRoZXkgYXJlbid0IG5lY2Vzc2FyeSBmb3IgZnVuY3Rpb25hbCBjb3JyZWN0bmVzcz8N Cg0KVGhpcyBpcyBuZWNlc3NhcnkgdG8gcHJvcGVybHkgYnJlYWsgaXNvbGF0aW9uIGFuZCBzZW5k IGEgc2lnbmFsIHdoZW4NCnNvbWV0aGluZyBkaXN0dXJiZWQgdGhlIGlzb2xhdGVkIHRhc2ssIGFu ZCB0byB0ZWxsIHRoZSB1c2VyIChsaWtlbHkgYQ0KZGV2ZWxvcGVyKSwgd2h5IHRoaXMgaGFwcGVu ZWQuIFRoZXJlIGFyZSBzb21lIGxlZ2l0aW1hdGUgcmVhc29ucyBmb3INCmJyZWFraW5nIGlzb2xh dGlvbiAoZm9yIGV4YW1wbGUsIGEgc2lnbmFsIHRoYXQgdGVybWluYXRlcyB0aGUgcHJvY2VzcykN CmFuZCB2ZXJ5IGxhcmdlIG51bWJlciBvZiBwb3NzaWJsZSB0aGluZ3MgdGhhdCBzaG91bGQgbm90 IGhhcHBlbiB0byBhbg0KaXNvbGF0ZWQgdGFzayAtLSBwYWdlIGZhdWx0IGNhdXNlZCBieSBhY2Nl c3MgdG8gdW5tYXBwZWQgYWRkcmVzc2VzLA0Kc3lzY2FsbCBpc3N1ZWQgYnkgdGhlIHRhc2sgaW4g aXNvbGF0ZWQgc3RhdGUsIGludGVycnVwdCBkaXJlY3RlZCB0byB0aGUNCmNvcmUgcnVubmluZyBp c29sYXRlZCB0YXNrLCB0aW1lciByZW1haW5pbmcgdGhlcmUsIG9yIGtlcm5lbCB0cnlpbmcgdG8N CnJ1biBzb21ldGhpbmcgb24gdGhhdCBjb3JlLiBJdCB3YXMgdmVyeSBoZWxwZnVsIHRvIGtub3cg d2hhdCBleGFjdGx5DQpoYXBwZW5lZCwgYW5kIGlmIG5vdCB0aGlzIHJlcG9ydGluZywgSSB3b3Vs ZCBoYXZlIGhhcmQgdGltZSBkZWJ1Z2dpbmcNCnRoZSBkcml2ZXJzIGFuZCBzdWJzeXN0ZW1zIHRo YXQgY2FsbGVkIHRoZWlyIGZ1bmN0aW9ucyBhbmQgc2NoZWR1bGVkDQp0aGVpciB0aHJlYWRzIGFs bCBvdmVyIHRoZSBwbGFjZS4gU28gYm90aCByZWxpYWJsZSBicmVha2luZyBvZg0KaXNvbGF0aW9u IGFuZCByZXBvcnRpbmcgdGhlIGNhdXNlIGlzIGltcG9ydGFudC4NCg0KPiANCj4gPiAgCXN3aXRj aCAoaXBpbnIpIHsNCj4gPiAgCWNhc2UgSVBJX1JFU0NIRURVTEU6DQo+ID4gIAkJc2NoZWR1bGVy X2lwaSgpOw0KPiA+IEBAIC05NDgsMTIgKzk1MywxNCBAQCB2b2lkIGhhbmRsZV9JUEkoaW50IGlw aW5yLCBzdHJ1Y3QgcHRfcmVncw0KPiA+ICpyZWdzKQ0KPiA+ICANCj4gPiAgdm9pZCBzbXBfc2Vu ZF9yZXNjaGVkdWxlKGludCBjcHUpDQo+ID4gIHsNCj4gPiArCXRhc2tfaXNvbGF0aW9uX3JlbW90 ZShjcHUsICJyZXNjaGVkdWxlIElQSSIpOw0KPiA+ICAJc21wX2Nyb3NzX2NhbGwoY3B1bWFza19v ZihjcHUpLCBJUElfUkVTQ0hFRFVMRSk7DQo+ID4gIH0NCj4gPiAgDQo+ID4gICNpZmRlZiBDT05G SUdfR0VORVJJQ19DTE9DS0VWRU5UU19CUk9BRENBU1QNCj4gPiAgdm9pZCB0aWNrX2Jyb2FkY2Fz dChjb25zdCBzdHJ1Y3QgY3B1bWFzayAqbWFzaykNCj4gPiAgew0KPiA+ICsJdGFza19pc29sYXRp b25fcmVtb3RlX2NwdW1hc2sobWFzaywgInRpbWVyIElQSSIpOw0KPiA+ICAJc21wX2Nyb3NzX2Nh bGwobWFzaywgSVBJX1RJTUVSKTsNCj4gPiAgfQ0KPiA+ICAjZW5kaWYNCj4gPiBkaWZmIC0tZ2l0 IGEvYXJjaC9hcm02NC9tbS9mYXVsdC5jIGIvYXJjaC9hcm02NC9tbS9mYXVsdC5jDQo+ID4gaW5k ZXggODU1NjZkMzI5NThmLi5mYzRiNDJjODFjNGYgMTAwNjQ0DQo+ID4gLS0tIGEvYXJjaC9hcm02 NC9tbS9mYXVsdC5jDQo+ID4gKysrIGIvYXJjaC9hcm02NC9tbS9mYXVsdC5jDQo+ID4gQEAgLTIz LDYgKzIzLDcgQEANCj4gPiAgI2luY2x1ZGUgPGxpbnV4L3BlcmZfZXZlbnQuaD4NCj4gPiAgI2lu Y2x1ZGUgPGxpbnV4L3ByZWVtcHQuaD4NCj4gPiAgI2luY2x1ZGUgPGxpbnV4L2h1Z2V0bGIuaD4N Cj4gPiArI2luY2x1ZGUgPGxpbnV4L2lzb2xhdGlvbi5oPg0KPiA+ICANCj4gPiAgI2luY2x1ZGUg PGFzbS9hY3BpLmg+DQo+ID4gICNpbmNsdWRlIDxhc20vYnVnLmg+DQo+ID4gQEAgLTU0Myw2ICs1 NDQsMTAgQEAgc3RhdGljIGludCBfX2twcm9iZXMgZG9fcGFnZV9mYXVsdCh1bnNpZ25lZA0KPiA+ IGxvbmcgYWRkciwgdW5zaWduZWQgaW50IGVzciwNCj4gPiAgCSAqLw0KPiA+ICAJaWYgKGxpa2Vs eSghKGZhdWx0ICYgKFZNX0ZBVUxUX0VSUk9SIHwgVk1fRkFVTFRfQkFETUFQIHwNCj4gPiAgCQkJ ICAgICAgVk1fRkFVTFRfQkFEQUNDRVNTKSkpKSB7DQo+ID4gKwkJLyogTm8gc2lnbmFsIHdhcyBn ZW5lcmF0ZWQsIGJ1dCBub3RpZnkgdGFzay1pc29sYXRpb24NCj4gPiB0YXNrcy4gKi8NCj4gPiAr CQlpZiAodXNlcl9tb2RlKHJlZ3MpKQ0KPiA+ICsJCQl0YXNrX2lzb2xhdGlvbl9pbnRlcnJ1cHQo InBhZ2UgZmF1bHQgYXQgJSNseCIsDQo+ID4gYWRkcik7DQo+ID4gKw0KPiANCj4gV2UgY2hlY2sg dXNlcl9tb2RlKHJlZ3MpIG11Y2ggZWFybGllciBpbiB0aGlzIGZ1bmN0aW9uIHRvIHNldA0KPiBG QVVMVF9GTEFHX1VTRVIuIElzIHRoZXJlIHNvbWUgcmVhc29uIHRoaXMgY2Fubm90IGxpdmUgdGhl cmU/DQo+IA0KPiBBbHNvLCB0aGlzIHNlZW1zIHRvIGJlIGEgdHJhY2luZyBob29rIC0tIGlzIHRo aXMgbmVjZXNzYXJ5Pw0KDQpUaGlzIGlzIGFub3RoZXIgcG9pbnQgd2hlcmUgdGFzayBpc29sYXRp b24gc3RhdGUgaXMgYnJva2VuLCB0YXNrDQpyZWNlaXZlcyBhIHNpZ25hbCBhbmQgdGhlIHJlYXNv biBpcyBsb2dnZWQuIElmIG5vdCBpc29sYXRpb24sIHRhc2sNCndvdWxkIG5vdCBrbm93IHRoYXQg YW55dGhpbmcgaGFwcGVuZWQsIGJ1dCBpdCBpcyBpbXBvcnRhbnQgZm9yDQppc29sYXRpb24uDQoN CkluIGdlbmVyYWwgaWYgaXNvbGF0ZWQgdGFzayBpcyBzdXBwb3NlZCB0byBiZSBydW5uaW5nIG9u IGEgQ1BVIGNvcmUsIGl0DQpoYXMgdG8gc3RheSBpbiB1c2Vyc3BhY2UuIFNvIGlmIGZvciBzb21l IHJlYXNvbiBhIGtlcm5lbCBjb2RlIGlzDQpydW5uaW5nIG9uIHRoYXQgQ1BVIGNvcmUsIHRoaXMg aXMgZWl0aGVyIGEgdGFzayBsZWF2aW5nIGlzb2xhdGlvbiBvbg0KaXRzIG93biBvciBpc29sYXRp b24gaXMgYnJva2VuIGFuZCB0aGUgdGFzayBzaG91bGQgYmUgbm90aWZpZWQgYWJvdXQNCml0LiBU aGUgb25seSBwcm9ibGVtIGlzIGhvdyB0byBwcm9wZXJseSBhbmQgcmVsaWFibHkgZXhwbGFpbiB3 aHkgdGhpcw0KaGFwcGVuZWQuDQoNClRoYW5rcyENCg0KLS0gDQpBbGV4DQo=