From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754685AbdCBSM1 (ORCPT ); Thu, 2 Mar 2017 13:12:27 -0500 Received: from mx1.redhat.com ([209.132.183.28]:35756 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753217AbdCBSMW (ORCPT ); Thu, 2 Mar 2017 13:12:22 -0500 From: Vitaly Kuznetsov To: xen-devel@lists.xenproject.org Cc: x86@kernel.org, linux-kernel@vger.kernel.org, Boris Ostrovsky , Juergen Gross , Andrew Jones Subject: [PATCH v2 11/21] x86/xen: split off smp_pv.c Date: Thu, 2 Mar 2017 18:53:47 +0100 Message-Id: <20170302175357.8222-12-vkuznets@redhat.com> In-Reply-To: <20170302175357.8222-1-vkuznets@redhat.com> References: <20170302175357.8222-1-vkuznets@redhat.com> X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Thu, 02 Mar 2017 17:54:20 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Basically, smp.c is renamed to smp_pv.c and some code moved out to common smp.c. struct xen_common_irq delcaration ended up in smp.h. Signed-off-by: Vitaly Kuznetsov --- arch/x86/xen/Makefile | 2 +- arch/x86/xen/smp.c | 487 +----------------------------------------------- arch/x86/xen/smp.h | 5 + arch/x86/xen/smp_pv.c | 499 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 508 insertions(+), 485 deletions(-) create mode 100644 arch/x86/xen/smp_pv.c diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile index bc7df8c..ebf3522 100644 --- a/arch/x86/xen/Makefile +++ b/arch/x86/xen/Makefile @@ -20,7 +20,7 @@ obj-$(CONFIG_XEN_PVH) += enlighten_pvh.o obj-$(CONFIG_EVENT_TRACING) += trace.o -obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_SMP) += smp.o smp_pv.o obj-$(CONFIG_XEN_PVHVM_SMP) += smp_hvm.o obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o obj-$(CONFIG_XEN_DEBUG_FS) += debugfs.o diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index c692336..82ac611 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -1,62 +1,21 @@ -/* - * Xen SMP support - * - * This file implements the Xen versions of smp_ops. SMP under Xen is - * very straightforward. Bringing a CPU up is simply a matter of - * loading its initial context and setting it running. - * - * IPIs are handled through the Xen event mechanism. - * - * Because virtual CPUs can be scheduled onto any real CPU, there's no - * useful topology information for the kernel to make use of. As a - * result, all CPUs are treated as if they're single-core and - * single-threaded. - */ -#include -#include -#include #include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include +#include +#include +#include -#include -#include #include #include #include "xen-ops.h" -#include "mmu.h" #include "smp.h" -#include "pmu.h" - -cpumask_var_t xen_cpu_initialized_map; -struct xen_common_irq { - int irq; - char *name; -}; static DEFINE_PER_CPU(struct xen_common_irq, xen_resched_irq) = { .irq = -1 }; static DEFINE_PER_CPU(struct xen_common_irq, xen_callfunc_irq) = { .irq = -1 }; static DEFINE_PER_CPU(struct xen_common_irq, xen_callfuncsingle_irq) = { .irq = -1 }; -static DEFINE_PER_CPU(struct xen_common_irq, xen_irq_work) = { .irq = -1 }; static DEFINE_PER_CPU(struct xen_common_irq, xen_debug_irq) = { .irq = -1 }; -static DEFINE_PER_CPU(struct xen_common_irq, xen_pmu_irq) = { .irq = -1 }; static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id); static irqreturn_t xen_call_function_single_interrupt(int irq, void *dev_id); -static irqreturn_t xen_irq_work_interrupt(int irq, void *dev_id); /* * Reschedule call back. @@ -69,42 +28,6 @@ static irqreturn_t xen_reschedule_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static void cpu_bringup(void) -{ - int cpu; - - cpu_init(); - touch_softlockup_watchdog(); - preempt_disable(); - - /* PVH runs in ring 0 and allows us to do native syscalls. Yay! */ - if (!xen_feature(XENFEAT_supervisor_mode_kernel)) { - xen_enable_sysenter(); - xen_enable_syscall(); - } - cpu = smp_processor_id(); - smp_store_cpu_info(cpu); - cpu_data(cpu).x86_max_cores = 1; - set_cpu_sibling_map(cpu); - - xen_setup_cpu_clockevents(); - - notify_cpu_starting(cpu); - - set_cpu_online(cpu, true); - - cpu_set_state_online(cpu); /* Implies full memory barrier. */ - - /* We can take interrupts now: we're officially "up". */ - local_irq_enable(); -} - -asmlinkage __visible void cpu_bringup_and_idle(void) -{ - cpu_bringup(); - cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); -} - void xen_smp_intr_free(unsigned int cpu) { if (per_cpu(xen_resched_irq, cpu).irq >= 0) { @@ -134,23 +57,6 @@ void xen_smp_intr_free(unsigned int cpu) } } -void xen_smp_intr_free_pv(unsigned int cpu) -{ - if (per_cpu(xen_irq_work, cpu).irq >= 0) { - unbind_from_irqhandler(per_cpu(xen_irq_work, cpu).irq, NULL); - per_cpu(xen_irq_work, cpu).irq = -1; - kfree(per_cpu(xen_irq_work, cpu).name); - per_cpu(xen_irq_work, cpu).name = NULL; - } - - if (per_cpu(xen_pmu_irq, cpu).irq >= 0) { - unbind_from_irqhandler(per_cpu(xen_pmu_irq, cpu).irq, NULL); - per_cpu(xen_pmu_irq, cpu).irq = -1; - kfree(per_cpu(xen_pmu_irq, cpu).name); - per_cpu(xen_pmu_irq, cpu).name = NULL; - } -} - int xen_smp_intr_init(unsigned int cpu) { int rc; @@ -208,360 +114,6 @@ int xen_smp_intr_init(unsigned int cpu) return rc; } -int xen_smp_intr_init_pv(unsigned int cpu) -{ - int rc; - char *callfunc_name, *pmu_name; - - callfunc_name = kasprintf(GFP_KERNEL, "irqwork%d", cpu); - rc = bind_ipi_to_irqhandler(XEN_IRQ_WORK_VECTOR, - cpu, - xen_irq_work_interrupt, - IRQF_PERCPU|IRQF_NOBALANCING, - callfunc_name, - NULL); - if (rc < 0) - goto fail; - per_cpu(xen_irq_work, cpu).irq = rc; - per_cpu(xen_irq_work, cpu).name = callfunc_name; - - if (is_xen_pmu(cpu)) { - pmu_name = kasprintf(GFP_KERNEL, "pmu%d", cpu); - rc = bind_virq_to_irqhandler(VIRQ_XENPMU, cpu, - xen_pmu_irq_handler, - IRQF_PERCPU|IRQF_NOBALANCING, - pmu_name, NULL); - if (rc < 0) - goto fail; - per_cpu(xen_pmu_irq, cpu).irq = rc; - per_cpu(xen_pmu_irq, cpu).name = pmu_name; - } - - return 0; - - fail: - xen_smp_intr_free_pv(cpu); - return rc; -} - -static void __init xen_fill_possible_map(void) -{ - int i, rc; - - if (xen_initial_domain()) - return; - - for (i = 0; i < nr_cpu_ids; i++) { - rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL); - if (rc >= 0) { - num_processors++; - set_cpu_possible(i, true); - } - } -} - -static void __init xen_filter_cpu_maps(void) -{ - int i, rc; - unsigned int subtract = 0; - - if (!xen_initial_domain()) - return; - - num_processors = 0; - disabled_cpus = 0; - for (i = 0; i < nr_cpu_ids; i++) { - rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL); - if (rc >= 0) { - num_processors++; - set_cpu_possible(i, true); - } else { - set_cpu_possible(i, false); - set_cpu_present(i, false); - subtract++; - } - } -#ifdef CONFIG_HOTPLUG_CPU - /* This is akin to using 'nr_cpus' on the Linux command line. - * Which is OK as when we use 'dom0_max_vcpus=X' we can only - * have up to X, while nr_cpu_ids is greater than X. This - * normally is not a problem, except when CPU hotplugging - * is involved and then there might be more than X CPUs - * in the guest - which will not work as there is no - * hypercall to expand the max number of VCPUs an already - * running guest has. So cap it up to X. */ - if (subtract) - nr_cpu_ids = nr_cpu_ids - subtract; -#endif - -} - -static void __init xen_pv_smp_prepare_boot_cpu(void) -{ - BUG_ON(smp_processor_id() != 0); - native_smp_prepare_boot_cpu(); - - if (!xen_feature(XENFEAT_writable_page_tables)) - /* We've switched to the "real" per-cpu gdt, so make - * sure the old memory can be recycled. */ - make_lowmem_page_readwrite(xen_initial_gdt); - -#ifdef CONFIG_X86_32 - /* - * Xen starts us with XEN_FLAT_RING1_DS, but linux code - * expects __USER_DS - */ - loadsegment(ds, __USER_DS); - loadsegment(es, __USER_DS); -#endif - - xen_filter_cpu_maps(); - xen_setup_vcpu_info_placement(); - - /* - * The alternative logic (which patches the unlock/lock) runs before - * the smp bootup up code is activated. Hence we need to set this up - * the core kernel is being patched. Otherwise we will have only - * modules patched but not core code. - */ - xen_init_spinlocks(); -} - -static void __init xen_smp_prepare_cpus(unsigned int max_cpus) -{ - unsigned cpu; - unsigned int i; - - if (skip_ioapic_setup) { - char *m = (max_cpus == 0) ? - "The nosmp parameter is incompatible with Xen; " \ - "use Xen dom0_max_vcpus=1 parameter" : - "The noapic parameter is incompatible with Xen"; - - xen_raw_printk(m); - panic(m); - } - xen_init_lock_cpu(0); - - smp_store_boot_cpu_info(); - cpu_data(0).x86_max_cores = 1; - - for_each_possible_cpu(i) { - zalloc_cpumask_var(&per_cpu(cpu_sibling_map, i), GFP_KERNEL); - zalloc_cpumask_var(&per_cpu(cpu_core_map, i), GFP_KERNEL); - zalloc_cpumask_var(&per_cpu(cpu_llc_shared_map, i), GFP_KERNEL); - } - set_cpu_sibling_map(0); - - xen_pmu_init(0); - - if (xen_smp_intr_init(0)) - BUG(); - - if (!alloc_cpumask_var(&xen_cpu_initialized_map, GFP_KERNEL)) - panic("could not allocate xen_cpu_initialized_map\n"); - - cpumask_copy(xen_cpu_initialized_map, cpumask_of(0)); - - /* Restrict the possible_map according to max_cpus. */ - while ((num_possible_cpus() > 1) && (num_possible_cpus() > max_cpus)) { - for (cpu = nr_cpu_ids - 1; !cpu_possible(cpu); cpu--) - continue; - set_cpu_possible(cpu, false); - } - - for_each_possible_cpu(cpu) - set_cpu_present(cpu, true); -} - -static int -cpu_initialize_context(unsigned int cpu, struct task_struct *idle) -{ - struct vcpu_guest_context *ctxt; - struct desc_struct *gdt; - unsigned long gdt_mfn; - - /* used to tell cpu_init() that it can proceed with initialization */ - cpumask_set_cpu(cpu, cpu_callout_mask); - if (cpumask_test_and_set_cpu(cpu, xen_cpu_initialized_map)) - return 0; - - ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); - if (ctxt == NULL) - return -ENOMEM; - - gdt = get_cpu_gdt_table(cpu); - -#ifdef CONFIG_X86_32 - ctxt->user_regs.fs = __KERNEL_PERCPU; - ctxt->user_regs.gs = __KERNEL_STACK_CANARY; -#endif - memset(&ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt)); - - ctxt->user_regs.eip = (unsigned long)cpu_bringup_and_idle; - ctxt->flags = VGCF_IN_KERNEL; - ctxt->user_regs.eflags = 0x1000; /* IOPL_RING1 */ - ctxt->user_regs.ds = __USER_DS; - ctxt->user_regs.es = __USER_DS; - ctxt->user_regs.ss = __KERNEL_DS; - - xen_copy_trap_info(ctxt->trap_ctxt); - - ctxt->ldt_ents = 0; - - BUG_ON((unsigned long)gdt & ~PAGE_MASK); - - gdt_mfn = arbitrary_virt_to_mfn(gdt); - make_lowmem_page_readonly(gdt); - make_lowmem_page_readonly(mfn_to_virt(gdt_mfn)); - - ctxt->gdt_frames[0] = gdt_mfn; - ctxt->gdt_ents = GDT_ENTRIES; - - ctxt->kernel_ss = __KERNEL_DS; - ctxt->kernel_sp = idle->thread.sp0; - -#ifdef CONFIG_X86_32 - ctxt->event_callback_cs = __KERNEL_CS; - ctxt->failsafe_callback_cs = __KERNEL_CS; -#else - ctxt->gs_base_kernel = per_cpu_offset(cpu); -#endif - ctxt->event_callback_eip = - (unsigned long)xen_hypervisor_callback; - ctxt->failsafe_callback_eip = - (unsigned long)xen_failsafe_callback; - ctxt->user_regs.cs = __KERNEL_CS; - per_cpu(xen_cr3, cpu) = __pa(swapper_pg_dir); - - ctxt->user_regs.esp = idle->thread.sp0 - sizeof(struct pt_regs); - ctxt->ctrlreg[3] = xen_pfn_to_cr3(virt_to_gfn(swapper_pg_dir)); - if (HYPERVISOR_vcpu_op(VCPUOP_initialise, xen_vcpu_nr(cpu), ctxt)) - BUG(); - - kfree(ctxt); - return 0; -} - -static int xen_cpu_up(unsigned int cpu, struct task_struct *idle) -{ - int rc; - - common_cpu_up(cpu, idle); - - xen_setup_runstate_info(cpu); - - /* - * PV VCPUs are always successfully taken down (see 'while' loop - * in xen_cpu_die()), so -EBUSY is an error. - */ - rc = cpu_check_up_prepare(cpu); - if (rc) - return rc; - - /* make sure interrupts start blocked */ - per_cpu(xen_vcpu, cpu)->evtchn_upcall_mask = 1; - - rc = cpu_initialize_context(cpu, idle); - if (rc) - return rc; - - xen_pmu_init(cpu); - - rc = HYPERVISOR_vcpu_op(VCPUOP_up, xen_vcpu_nr(cpu), NULL); - BUG_ON(rc); - - while (cpu_report_state(cpu) != CPU_ONLINE) - HYPERVISOR_sched_op(SCHEDOP_yield, NULL); - - return 0; -} - -static void xen_smp_cpus_done(unsigned int max_cpus) -{ -} - -#ifdef CONFIG_HOTPLUG_CPU -static int xen_cpu_disable(void) -{ - unsigned int cpu = smp_processor_id(); - if (cpu == 0) - return -EBUSY; - - cpu_disable_common(); - - load_cr3(swapper_pg_dir); - return 0; -} - -static void xen_pv_cpu_die(unsigned int cpu) -{ - while (HYPERVISOR_vcpu_op(VCPUOP_is_up, - xen_vcpu_nr(cpu), NULL)) { - __set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ/10); - } - - if (common_cpu_die(cpu) == 0) { - xen_smp_intr_free(cpu); - xen_uninit_lock_cpu(cpu); - xen_teardown_timer(cpu); - xen_pmu_finish(cpu); - } -} - -static void xen_play_dead(void) /* used only with HOTPLUG_CPU */ -{ - play_dead_common(); - HYPERVISOR_vcpu_op(VCPUOP_down, xen_vcpu_nr(smp_processor_id()), NULL); - cpu_bringup(); - /* - * commit 4b0c0f294 (tick: Cleanup NOHZ per cpu data on cpu down) - * clears certain data that the cpu_idle loop (which called us - * and that we return from) expects. The only way to get that - * data back is to call: - */ - tick_nohz_idle_enter(); - - cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); -} - -#else /* !CONFIG_HOTPLUG_CPU */ -static int xen_cpu_disable(void) -{ - return -ENOSYS; -} - -static void xen_pv_cpu_die(unsigned int cpu) -{ - BUG(); -} - -static void xen_play_dead(void) -{ - BUG(); -} - -#endif -static void stop_self(void *v) -{ - int cpu = smp_processor_id(); - - /* make sure we're not pinning something down */ - load_cr3(swapper_pg_dir); - /* should set up a minimal gdt */ - - set_cpu_online(cpu, false); - - HYPERVISOR_vcpu_op(VCPUOP_down, xen_vcpu_nr(cpu), NULL); - BUG(); -} - -static void xen_stop_other_cpus(int wait) -{ - smp_call_function(stop_self, NULL, wait); -} - void xen_smp_send_reschedule(int cpu) { xen_send_IPI_one(cpu, XEN_RESCHEDULE_VECTOR); @@ -696,36 +248,3 @@ static irqreturn_t xen_call_function_single_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } - -static irqreturn_t xen_irq_work_interrupt(int irq, void *dev_id) -{ - irq_enter(); - irq_work_run(); - inc_irq_stat(apic_irq_work_irqs); - irq_exit(); - - return IRQ_HANDLED; -} - -static const struct smp_ops xen_smp_ops __initconst = { - .smp_prepare_boot_cpu = xen_pv_smp_prepare_boot_cpu, - .smp_prepare_cpus = xen_smp_prepare_cpus, - .smp_cpus_done = xen_smp_cpus_done, - - .cpu_up = xen_cpu_up, - .cpu_die = xen_pv_cpu_die, - .cpu_disable = xen_cpu_disable, - .play_dead = xen_play_dead, - - .stop_other_cpus = xen_stop_other_cpus, - .smp_send_reschedule = xen_smp_send_reschedule, - - .send_call_func_ipi = xen_smp_send_call_function_ipi, - .send_call_func_single_ipi = xen_smp_send_call_function_single_ipi, -}; - -void __init xen_smp_init(void) -{ - smp_ops = xen_smp_ops; - xen_fill_possible_map(); -} diff --git a/arch/x86/xen/smp.h b/arch/x86/xen/smp.h index bf36e79..3245343 100644 --- a/arch/x86/xen/smp.h +++ b/arch/x86/xen/smp.h @@ -17,6 +17,11 @@ extern void xen_smp_intr_free_pv(unsigned int cpu); extern void xen_smp_send_reschedule(int cpu); extern void xen_smp_send_call_function_ipi(const struct cpumask *mask); extern void xen_smp_send_call_function_single_ipi(int cpu); + +struct xen_common_irq { + int irq; + char *name; +}; #else /* CONFIG_SMP */ static inline int xen_smp_intr_init(unsigned int cpu) diff --git a/arch/x86/xen/smp_pv.c b/arch/x86/xen/smp_pv.c new file mode 100644 index 0000000..e20718a --- /dev/null +++ b/arch/x86/xen/smp_pv.c @@ -0,0 +1,499 @@ +/* + * Xen SMP support + * + * This file implements the Xen versions of smp_ops. SMP under Xen is + * very straightforward. Bringing a CPU up is simply a matter of + * loading its initial context and setting it running. + * + * IPIs are handled through the Xen event mechanism. + * + * Because virtual CPUs can be scheduled onto any real CPU, there's no + * useful topology information for the kernel to make use of. As a + * result, all CPUs are treated as if they're single-core and + * single-threaded. + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include "xen-ops.h" +#include "mmu.h" +#include "smp.h" +#include "pmu.h" + +cpumask_var_t xen_cpu_initialized_map; + +static DEFINE_PER_CPU(struct xen_common_irq, xen_irq_work) = { .irq = -1 }; +static DEFINE_PER_CPU(struct xen_common_irq, xen_pmu_irq) = { .irq = -1 }; + +static irqreturn_t xen_irq_work_interrupt(int irq, void *dev_id); + +static void cpu_bringup(void) +{ + int cpu; + + cpu_init(); + touch_softlockup_watchdog(); + preempt_disable(); + + /* PVH runs in ring 0 and allows us to do native syscalls. Yay! */ + if (!xen_feature(XENFEAT_supervisor_mode_kernel)) { + xen_enable_sysenter(); + xen_enable_syscall(); + } + cpu = smp_processor_id(); + smp_store_cpu_info(cpu); + cpu_data(cpu).x86_max_cores = 1; + set_cpu_sibling_map(cpu); + + xen_setup_cpu_clockevents(); + + notify_cpu_starting(cpu); + + set_cpu_online(cpu, true); + + cpu_set_state_online(cpu); /* Implies full memory barrier. */ + + /* We can take interrupts now: we're officially "up". */ + local_irq_enable(); +} + +asmlinkage __visible void cpu_bringup_and_idle(void) +{ + cpu_bringup(); + cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); +} + +void xen_smp_intr_free_pv(unsigned int cpu) +{ + if (per_cpu(xen_irq_work, cpu).irq >= 0) { + unbind_from_irqhandler(per_cpu(xen_irq_work, cpu).irq, NULL); + per_cpu(xen_irq_work, cpu).irq = -1; + kfree(per_cpu(xen_irq_work, cpu).name); + per_cpu(xen_irq_work, cpu).name = NULL; + } + + if (per_cpu(xen_pmu_irq, cpu).irq >= 0) { + unbind_from_irqhandler(per_cpu(xen_pmu_irq, cpu).irq, NULL); + per_cpu(xen_pmu_irq, cpu).irq = -1; + kfree(per_cpu(xen_pmu_irq, cpu).name); + per_cpu(xen_pmu_irq, cpu).name = NULL; + } +} + +int xen_smp_intr_init_pv(unsigned int cpu) +{ + int rc; + char *callfunc_name, *pmu_name; + + callfunc_name = kasprintf(GFP_KERNEL, "irqwork%d", cpu); + rc = bind_ipi_to_irqhandler(XEN_IRQ_WORK_VECTOR, + cpu, + xen_irq_work_interrupt, + IRQF_PERCPU|IRQF_NOBALANCING, + callfunc_name, + NULL); + if (rc < 0) + goto fail; + per_cpu(xen_irq_work, cpu).irq = rc; + per_cpu(xen_irq_work, cpu).name = callfunc_name; + + if (is_xen_pmu(cpu)) { + pmu_name = kasprintf(GFP_KERNEL, "pmu%d", cpu); + rc = bind_virq_to_irqhandler(VIRQ_XENPMU, cpu, + xen_pmu_irq_handler, + IRQF_PERCPU|IRQF_NOBALANCING, + pmu_name, NULL); + if (rc < 0) + goto fail; + per_cpu(xen_pmu_irq, cpu).irq = rc; + per_cpu(xen_pmu_irq, cpu).name = pmu_name; + } + + return 0; + + fail: + xen_smp_intr_free_pv(cpu); + return rc; +} + +static void __init xen_fill_possible_map(void) +{ + int i, rc; + + if (xen_initial_domain()) + return; + + for (i = 0; i < nr_cpu_ids; i++) { + rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL); + if (rc >= 0) { + num_processors++; + set_cpu_possible(i, true); + } + } +} + +static void __init xen_filter_cpu_maps(void) +{ + int i, rc; + unsigned int subtract = 0; + + if (!xen_initial_domain()) + return; + + num_processors = 0; + disabled_cpus = 0; + for (i = 0; i < nr_cpu_ids; i++) { + rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL); + if (rc >= 0) { + num_processors++; + set_cpu_possible(i, true); + } else { + set_cpu_possible(i, false); + set_cpu_present(i, false); + subtract++; + } + } +#ifdef CONFIG_HOTPLUG_CPU + /* This is akin to using 'nr_cpus' on the Linux command line. + * Which is OK as when we use 'dom0_max_vcpus=X' we can only + * have up to X, while nr_cpu_ids is greater than X. This + * normally is not a problem, except when CPU hotplugging + * is involved and then there might be more than X CPUs + * in the guest - which will not work as there is no + * hypercall to expand the max number of VCPUs an already + * running guest has. So cap it up to X. */ + if (subtract) + nr_cpu_ids = nr_cpu_ids - subtract; +#endif + +} + +static void __init xen_pv_smp_prepare_boot_cpu(void) +{ + BUG_ON(smp_processor_id() != 0); + native_smp_prepare_boot_cpu(); + + if (!xen_feature(XENFEAT_writable_page_tables)) + /* We've switched to the "real" per-cpu gdt, so make + * sure the old memory can be recycled. */ + make_lowmem_page_readwrite(xen_initial_gdt); + +#ifdef CONFIG_X86_32 + /* + * Xen starts us with XEN_FLAT_RING1_DS, but linux code + * expects __USER_DS + */ + loadsegment(ds, __USER_DS); + loadsegment(es, __USER_DS); +#endif + + xen_filter_cpu_maps(); + xen_setup_vcpu_info_placement(); + + /* + * The alternative logic (which patches the unlock/lock) runs before + * the smp bootup up code is activated. Hence we need to set this up + * the core kernel is being patched. Otherwise we will have only + * modules patched but not core code. + */ + xen_init_spinlocks(); +} + +static void __init xen_smp_prepare_cpus(unsigned int max_cpus) +{ + unsigned cpu; + unsigned int i; + + if (skip_ioapic_setup) { + char *m = (max_cpus == 0) ? + "The nosmp parameter is incompatible with Xen; " \ + "use Xen dom0_max_vcpus=1 parameter" : + "The noapic parameter is incompatible with Xen"; + + xen_raw_printk(m); + panic(m); + } + xen_init_lock_cpu(0); + + smp_store_boot_cpu_info(); + cpu_data(0).x86_max_cores = 1; + + for_each_possible_cpu(i) { + zalloc_cpumask_var(&per_cpu(cpu_sibling_map, i), GFP_KERNEL); + zalloc_cpumask_var(&per_cpu(cpu_core_map, i), GFP_KERNEL); + zalloc_cpumask_var(&per_cpu(cpu_llc_shared_map, i), GFP_KERNEL); + } + set_cpu_sibling_map(0); + + xen_pmu_init(0); + + if (xen_smp_intr_init(0)) + BUG(); + + if (!alloc_cpumask_var(&xen_cpu_initialized_map, GFP_KERNEL)) + panic("could not allocate xen_cpu_initialized_map\n"); + + cpumask_copy(xen_cpu_initialized_map, cpumask_of(0)); + + /* Restrict the possible_map according to max_cpus. */ + while ((num_possible_cpus() > 1) && (num_possible_cpus() > max_cpus)) { + for (cpu = nr_cpu_ids - 1; !cpu_possible(cpu); cpu--) + continue; + set_cpu_possible(cpu, false); + } + + for_each_possible_cpu(cpu) + set_cpu_present(cpu, true); +} + +static int +cpu_initialize_context(unsigned int cpu, struct task_struct *idle) +{ + struct vcpu_guest_context *ctxt; + struct desc_struct *gdt; + unsigned long gdt_mfn; + + /* used to tell cpu_init() that it can proceed with initialization */ + cpumask_set_cpu(cpu, cpu_callout_mask); + if (cpumask_test_and_set_cpu(cpu, xen_cpu_initialized_map)) + return 0; + + ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); + if (ctxt == NULL) + return -ENOMEM; + + gdt = get_cpu_gdt_table(cpu); + +#ifdef CONFIG_X86_32 + ctxt->user_regs.fs = __KERNEL_PERCPU; + ctxt->user_regs.gs = __KERNEL_STACK_CANARY; +#endif + memset(&ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt)); + + ctxt->user_regs.eip = (unsigned long)cpu_bringup_and_idle; + ctxt->flags = VGCF_IN_KERNEL; + ctxt->user_regs.eflags = 0x1000; /* IOPL_RING1 */ + ctxt->user_regs.ds = __USER_DS; + ctxt->user_regs.es = __USER_DS; + ctxt->user_regs.ss = __KERNEL_DS; + + xen_copy_trap_info(ctxt->trap_ctxt); + + ctxt->ldt_ents = 0; + + BUG_ON((unsigned long)gdt & ~PAGE_MASK); + + gdt_mfn = arbitrary_virt_to_mfn(gdt); + make_lowmem_page_readonly(gdt); + make_lowmem_page_readonly(mfn_to_virt(gdt_mfn)); + + ctxt->gdt_frames[0] = gdt_mfn; + ctxt->gdt_ents = GDT_ENTRIES; + + ctxt->kernel_ss = __KERNEL_DS; + ctxt->kernel_sp = idle->thread.sp0; + +#ifdef CONFIG_X86_32 + ctxt->event_callback_cs = __KERNEL_CS; + ctxt->failsafe_callback_cs = __KERNEL_CS; +#else + ctxt->gs_base_kernel = per_cpu_offset(cpu); +#endif + ctxt->event_callback_eip = + (unsigned long)xen_hypervisor_callback; + ctxt->failsafe_callback_eip = + (unsigned long)xen_failsafe_callback; + ctxt->user_regs.cs = __KERNEL_CS; + per_cpu(xen_cr3, cpu) = __pa(swapper_pg_dir); + + ctxt->user_regs.esp = idle->thread.sp0 - sizeof(struct pt_regs); + ctxt->ctrlreg[3] = xen_pfn_to_cr3(virt_to_gfn(swapper_pg_dir)); + if (HYPERVISOR_vcpu_op(VCPUOP_initialise, xen_vcpu_nr(cpu), ctxt)) + BUG(); + + kfree(ctxt); + return 0; +} + +static int xen_cpu_up(unsigned int cpu, struct task_struct *idle) +{ + int rc; + + common_cpu_up(cpu, idle); + + xen_setup_runstate_info(cpu); + + /* + * PV VCPUs are always successfully taken down (see 'while' loop + * in xen_cpu_die()), so -EBUSY is an error. + */ + rc = cpu_check_up_prepare(cpu); + if (rc) + return rc; + + /* make sure interrupts start blocked */ + per_cpu(xen_vcpu, cpu)->evtchn_upcall_mask = 1; + + rc = cpu_initialize_context(cpu, idle); + if (rc) + return rc; + + xen_pmu_init(cpu); + + rc = HYPERVISOR_vcpu_op(VCPUOP_up, xen_vcpu_nr(cpu), NULL); + BUG_ON(rc); + + while (cpu_report_state(cpu) != CPU_ONLINE) + HYPERVISOR_sched_op(SCHEDOP_yield, NULL); + + return 0; +} + +static void xen_smp_cpus_done(unsigned int max_cpus) +{ +} + +#ifdef CONFIG_HOTPLUG_CPU +static int xen_cpu_disable(void) +{ + unsigned int cpu = smp_processor_id(); + if (cpu == 0) + return -EBUSY; + + cpu_disable_common(); + + load_cr3(swapper_pg_dir); + return 0; +} + +static void xen_pv_cpu_die(unsigned int cpu) +{ + while (HYPERVISOR_vcpu_op(VCPUOP_is_up, + xen_vcpu_nr(cpu), NULL)) { + __set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ/10); + } + + if (common_cpu_die(cpu) == 0) { + xen_smp_intr_free(cpu); + xen_uninit_lock_cpu(cpu); + xen_teardown_timer(cpu); + xen_pmu_finish(cpu); + } +} + +static void xen_play_dead(void) /* used only with HOTPLUG_CPU */ +{ + play_dead_common(); + HYPERVISOR_vcpu_op(VCPUOP_down, xen_vcpu_nr(smp_processor_id()), NULL); + cpu_bringup(); + /* + * commit 4b0c0f294 (tick: Cleanup NOHZ per cpu data on cpu down) + * clears certain data that the cpu_idle loop (which called us + * and that we return from) expects. The only way to get that + * data back is to call: + */ + tick_nohz_idle_enter(); + + cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); +} + +#else /* !CONFIG_HOTPLUG_CPU */ +static int xen_cpu_disable(void) +{ + return -ENOSYS; +} + +static void xen_pv_cpu_die(unsigned int cpu) +{ + BUG(); +} + +static void xen_play_dead(void) +{ + BUG(); +} + +#endif +static void stop_self(void *v) +{ + int cpu = smp_processor_id(); + + /* make sure we're not pinning something down */ + load_cr3(swapper_pg_dir); + /* should set up a minimal gdt */ + + set_cpu_online(cpu, false); + + HYPERVISOR_vcpu_op(VCPUOP_down, xen_vcpu_nr(cpu), NULL); + BUG(); +} + +static void xen_stop_other_cpus(int wait) +{ + smp_call_function(stop_self, NULL, wait); +} + +static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id) +{ + irq_enter(); + generic_smp_call_function_interrupt(); + inc_irq_stat(irq_call_count); + irq_exit(); + + return IRQ_HANDLED; +} + +static irqreturn_t xen_irq_work_interrupt(int irq, void *dev_id) +{ + irq_enter(); + irq_work_run(); + inc_irq_stat(apic_irq_work_irqs); + irq_exit(); + + return IRQ_HANDLED; +} + +static const struct smp_ops xen_smp_ops __initconst = { + .smp_prepare_boot_cpu = xen_pv_smp_prepare_boot_cpu, + .smp_prepare_cpus = xen_smp_prepare_cpus, + .smp_cpus_done = xen_smp_cpus_done, + + .cpu_up = xen_cpu_up, + .cpu_die = xen_pv_cpu_die, + .cpu_disable = xen_cpu_disable, + .play_dead = xen_play_dead, + + .stop_other_cpus = xen_stop_other_cpus, + .smp_send_reschedule = xen_smp_send_reschedule, + + .send_call_func_ipi = xen_smp_send_call_function_ipi, + .send_call_func_single_ipi = xen_smp_send_call_function_single_ipi, +}; + +void __init xen_smp_init(void) +{ + smp_ops = xen_smp_ops; + xen_fill_possible_map(); +} -- 2.9.3 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Vitaly Kuznetsov Subject: [PATCH v2 11/21] x86/xen: split off smp_pv.c Date: Thu, 2 Mar 2017 18:53:47 +0100 Message-ID: <20170302175357.8222-12-vkuznets@redhat.com> References: <20170302175357.8222-1-vkuznets@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cjUvn-0003cp-Ck for xen-devel@lists.xenproject.org; Thu, 02 Mar 2017 17:54:23 +0000 In-Reply-To: <20170302175357.8222-1-vkuznets@redhat.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" To: xen-devel@lists.xenproject.org Cc: Juergen Gross , Boris Ostrovsky , x86@kernel.org, Andrew Jones , linux-kernel@vger.kernel.org List-Id: xen-devel@lists.xenproject.org QmFzaWNhbGx5LCBzbXAuYyBpcyByZW5hbWVkIHRvIHNtcF9wdi5jIGFuZCBzb21lIGNvZGUgbW92 ZWQgb3V0IHRvIGNvbW1vbgpzbXAuYy4gc3RydWN0IHhlbl9jb21tb25faXJxIGRlbGNhcmF0aW9u IGVuZGVkIHVwIGluIHNtcC5oLgoKU2lnbmVkLW9mZi1ieTogVml0YWx5IEt1em5ldHNvdiA8dmt1 em5ldHNAcmVkaGF0LmNvbT4KLS0tCiBhcmNoL3g4Ni94ZW4vTWFrZWZpbGUgfCAgIDIgKy0KIGFy Y2gveDg2L3hlbi9zbXAuYyAgICB8IDQ4NyArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0KIGFyY2gveDg2L3hlbi9zbXAuaCAgICB8ICAgNSArCiBhcmNoL3g4 Ni94ZW4vc21wX3B2LmMgfCA0OTkgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr KysrKysrKysrKysrKysKIDQgZmlsZXMgY2hhbmdlZCwgNTA4IGluc2VydGlvbnMoKyksIDQ4NSBk ZWxldGlvbnMoLSkKIGNyZWF0ZSBtb2RlIDEwMDY0NCBhcmNoL3g4Ni94ZW4vc21wX3B2LmMKCmRp ZmYgLS1naXQgYS9hcmNoL3g4Ni94ZW4vTWFrZWZpbGUgYi9hcmNoL3g4Ni94ZW4vTWFrZWZpbGUK aW5kZXggYmM3ZGY4Yy4uZWJmMzUyMiAxMDA2NDQKLS0tIGEvYXJjaC94ODYveGVuL01ha2VmaWxl CisrKyBiL2FyY2gveDg2L3hlbi9NYWtlZmlsZQpAQCAtMjAsNyArMjAsNyBAQCBvYmotJChDT05G SUdfWEVOX1BWSCkJCQkrPSBlbmxpZ2h0ZW5fcHZoLm8KIAogb2JqLSQoQ09ORklHX0VWRU5UX1RS QUNJTkcpICs9IHRyYWNlLm8KIAotb2JqLSQoQ09ORklHX1NNUCkJCSs9IHNtcC5vCitvYmotJChD T05GSUdfU01QKQkJKz0gc21wLm8gc21wX3B2Lm8KIG9iai0kKENPTkZJR19YRU5fUFZIVk1fU01Q KSAgCSs9IHNtcF9odm0ubwogb2JqLSQoQ09ORklHX1BBUkFWSVJUX1NQSU5MT0NLUykrPSBzcGlu bG9jay5vCiBvYmotJChDT05GSUdfWEVOX0RFQlVHX0ZTKQkrPSBkZWJ1Z2ZzLm8KZGlmZiAtLWdp dCBhL2FyY2gveDg2L3hlbi9zbXAuYyBiL2FyY2gveDg2L3hlbi9zbXAuYwppbmRleCBjNjkyMzM2 Li44MmFjNjExIDEwMDY0NAotLS0gYS9hcmNoL3g4Ni94ZW4vc21wLmMKKysrIGIvYXJjaC94ODYv eGVuL3NtcC5jCkBAIC0xLDYyICsxLDIxIEBACi0vKgotICogWGVuIFNNUCBzdXBwb3J0Ci0gKgot ICogVGhpcyBmaWxlIGltcGxlbWVudHMgdGhlIFhlbiB2ZXJzaW9ucyBvZiBzbXBfb3BzLiAgU01Q IHVuZGVyIFhlbiBpcwotICogdmVyeSBzdHJhaWdodGZvcndhcmQuICBCcmluZ2luZyBhIENQVSB1 cCBpcyBzaW1wbHkgYSBtYXR0ZXIgb2YKLSAqIGxvYWRpbmcgaXRzIGluaXRpYWwgY29udGV4dCBh bmQgc2V0dGluZyBpdCBydW5uaW5nLgotICoKLSAqIElQSXMgYXJlIGhhbmRsZWQgdGhyb3VnaCB0 aGUgWGVuIGV2ZW50IG1lY2hhbmlzbS4KLSAqCi0gKiBCZWNhdXNlIHZpcnR1YWwgQ1BVcyBjYW4g YmUgc2NoZWR1bGVkIG9udG8gYW55IHJlYWwgQ1BVLCB0aGVyZSdzIG5vCi0gKiB1c2VmdWwgdG9w b2xvZ3kgaW5mb3JtYXRpb24gZm9yIHRoZSBrZXJuZWwgdG8gbWFrZSB1c2Ugb2YuICBBcyBhCi0g KiByZXN1bHQsIGFsbCBDUFVzIGFyZSB0cmVhdGVkIGFzIGlmIHRoZXkncmUgc2luZ2xlLWNvcmUg YW5kCi0gKiBzaW5nbGUtdGhyZWFkZWQuCi0gKi8KLSNpbmNsdWRlIDxsaW51eC9zY2hlZC5oPgot I2luY2x1ZGUgPGxpbnV4L2Vyci5oPgotI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KICNpbmNsdWRl IDxsaW51eC9zbXAuaD4KLSNpbmNsdWRlIDxsaW51eC9pcnFfd29yay5oPgotI2luY2x1ZGUgPGxp bnV4L3RpY2suaD4KLQotI2luY2x1ZGUgPGFzbS9wYXJhdmlydC5oPgotI2luY2x1ZGUgPGFzbS9k ZXNjLmg+Ci0jaW5jbHVkZSA8YXNtL3BndGFibGUuaD4KLSNpbmNsdWRlIDxhc20vY3B1Lmg+Ci0K LSNpbmNsdWRlIDx4ZW4vaW50ZXJmYWNlL3hlbi5oPgotI2luY2x1ZGUgPHhlbi9pbnRlcmZhY2Uv dmNwdS5oPgotI2luY2x1ZGUgPHhlbi9pbnRlcmZhY2UveGVucG11Lmg+Ci0KLSNpbmNsdWRlIDxh c20veGVuL2ludGVyZmFjZS5oPgotI2luY2x1ZGUgPGFzbS94ZW4vaHlwZXJjYWxsLmg+CisjaW5j bHVkZSA8bGludXgvc2xhYi5oPgorI2luY2x1ZGUgPGxpbnV4L2NwdW1hc2suaD4KKyNpbmNsdWRl IDxsaW51eC9wZXJjcHUuaD4KIAotI2luY2x1ZGUgPHhlbi94ZW4uaD4KLSNpbmNsdWRlIDx4ZW4v cGFnZS5oPgogI2luY2x1ZGUgPHhlbi9ldmVudHMuaD4KIAogI2luY2x1ZGUgPHhlbi9odmMtY29u c29sZS5oPgogI2luY2x1ZGUgInhlbi1vcHMuaCIKLSNpbmNsdWRlICJtbXUuaCIKICNpbmNsdWRl ICJzbXAuaCIKLSNpbmNsdWRlICJwbXUuaCIKLQotY3B1bWFza192YXJfdCB4ZW5fY3B1X2luaXRp YWxpemVkX21hcDsKIAotc3RydWN0IHhlbl9jb21tb25faXJxIHsKLQlpbnQgaXJxOwotCWNoYXIg Km5hbWU7Ci19Owogc3RhdGljIERFRklORV9QRVJfQ1BVKHN0cnVjdCB4ZW5fY29tbW9uX2lycSwg eGVuX3Jlc2NoZWRfaXJxKSA9IHsgLmlycSA9IC0xIH07CiBzdGF0aWMgREVGSU5FX1BFUl9DUFUo c3RydWN0IHhlbl9jb21tb25faXJxLCB4ZW5fY2FsbGZ1bmNfaXJxKSA9IHsgLmlycSA9IC0xIH07 CiBzdGF0aWMgREVGSU5FX1BFUl9DUFUoc3RydWN0IHhlbl9jb21tb25faXJxLCB4ZW5fY2FsbGZ1 bmNzaW5nbGVfaXJxKSA9IHsgLmlycSA9IC0xIH07Ci1zdGF0aWMgREVGSU5FX1BFUl9DUFUoc3Ry dWN0IHhlbl9jb21tb25faXJxLCB4ZW5faXJxX3dvcmspID0geyAuaXJxID0gLTEgfTsKIHN0YXRp YyBERUZJTkVfUEVSX0NQVShzdHJ1Y3QgeGVuX2NvbW1vbl9pcnEsIHhlbl9kZWJ1Z19pcnEpID0g eyAuaXJxID0gLTEgfTsKLXN0YXRpYyBERUZJTkVfUEVSX0NQVShzdHJ1Y3QgeGVuX2NvbW1vbl9p cnEsIHhlbl9wbXVfaXJxKSA9IHsgLmlycSA9IC0xIH07CiAKIHN0YXRpYyBpcnFyZXR1cm5fdCB4 ZW5fY2FsbF9mdW5jdGlvbl9pbnRlcnJ1cHQoaW50IGlycSwgdm9pZCAqZGV2X2lkKTsKIHN0YXRp YyBpcnFyZXR1cm5fdCB4ZW5fY2FsbF9mdW5jdGlvbl9zaW5nbGVfaW50ZXJydXB0KGludCBpcnEs IHZvaWQgKmRldl9pZCk7Ci1zdGF0aWMgaXJxcmV0dXJuX3QgeGVuX2lycV93b3JrX2ludGVycnVw dChpbnQgaXJxLCB2b2lkICpkZXZfaWQpOwogCiAvKgogICogUmVzY2hlZHVsZSBjYWxsIGJhY2su CkBAIC02OSw0MiArMjgsNiBAQCBzdGF0aWMgaXJxcmV0dXJuX3QgeGVuX3Jlc2NoZWR1bGVfaW50 ZXJydXB0KGludCBpcnEsIHZvaWQgKmRldl9pZCkKIAlyZXR1cm4gSVJRX0hBTkRMRUQ7CiB9CiAK LXN0YXRpYyB2b2lkIGNwdV9icmluZ3VwKHZvaWQpCi17Ci0JaW50IGNwdTsKLQotCWNwdV9pbml0 KCk7Ci0JdG91Y2hfc29mdGxvY2t1cF93YXRjaGRvZygpOwotCXByZWVtcHRfZGlzYWJsZSgpOwot Ci0JLyogUFZIIHJ1bnMgaW4gcmluZyAwIGFuZCBhbGxvd3MgdXMgdG8gZG8gbmF0aXZlIHN5c2Nh bGxzLiBZYXkhICovCi0JaWYgKCF4ZW5fZmVhdHVyZShYRU5GRUFUX3N1cGVydmlzb3JfbW9kZV9r ZXJuZWwpKSB7Ci0JCXhlbl9lbmFibGVfc3lzZW50ZXIoKTsKLQkJeGVuX2VuYWJsZV9zeXNjYWxs KCk7Ci0JfQotCWNwdSA9IHNtcF9wcm9jZXNzb3JfaWQoKTsKLQlzbXBfc3RvcmVfY3B1X2luZm8o Y3B1KTsKLQljcHVfZGF0YShjcHUpLng4Nl9tYXhfY29yZXMgPSAxOwotCXNldF9jcHVfc2libGlu Z19tYXAoY3B1KTsKLQotCXhlbl9zZXR1cF9jcHVfY2xvY2tldmVudHMoKTsKLQotCW5vdGlmeV9j cHVfc3RhcnRpbmcoY3B1KTsKLQotCXNldF9jcHVfb25saW5lKGNwdSwgdHJ1ZSk7Ci0KLQljcHVf c2V0X3N0YXRlX29ubGluZShjcHUpOyAgLyogSW1wbGllcyBmdWxsIG1lbW9yeSBiYXJyaWVyLiAq LwotCi0JLyogV2UgY2FuIHRha2UgaW50ZXJydXB0cyBub3c6IHdlJ3JlIG9mZmljaWFsbHkgInVw Ii4gKi8KLQlsb2NhbF9pcnFfZW5hYmxlKCk7Ci19Ci0KLWFzbWxpbmthZ2UgX192aXNpYmxlIHZv aWQgY3B1X2JyaW5ndXBfYW5kX2lkbGUodm9pZCkKLXsKLQljcHVfYnJpbmd1cCgpOwotCWNwdV9z dGFydHVwX2VudHJ5KENQVUhQX0FQX09OTElORV9JRExFKTsKLX0KLQogdm9pZCB4ZW5fc21wX2lu dHJfZnJlZSh1bnNpZ25lZCBpbnQgY3B1KQogewogCWlmIChwZXJfY3B1KHhlbl9yZXNjaGVkX2ly cSwgY3B1KS5pcnEgPj0gMCkgewpAQCAtMTM0LDIzICs1Nyw2IEBAIHZvaWQgeGVuX3NtcF9pbnRy X2ZyZWUodW5zaWduZWQgaW50IGNwdSkKIAl9CiB9CiAKLXZvaWQgeGVuX3NtcF9pbnRyX2ZyZWVf cHYodW5zaWduZWQgaW50IGNwdSkKLXsKLQlpZiAocGVyX2NwdSh4ZW5faXJxX3dvcmssIGNwdSku aXJxID49IDApIHsKLQkJdW5iaW5kX2Zyb21faXJxaGFuZGxlcihwZXJfY3B1KHhlbl9pcnFfd29y aywgY3B1KS5pcnEsIE5VTEwpOwotCQlwZXJfY3B1KHhlbl9pcnFfd29yaywgY3B1KS5pcnEgPSAt MTsKLQkJa2ZyZWUocGVyX2NwdSh4ZW5faXJxX3dvcmssIGNwdSkubmFtZSk7Ci0JCXBlcl9jcHUo eGVuX2lycV93b3JrLCBjcHUpLm5hbWUgPSBOVUxMOwotCX0KLQotCWlmIChwZXJfY3B1KHhlbl9w bXVfaXJxLCBjcHUpLmlycSA+PSAwKSB7Ci0JCXVuYmluZF9mcm9tX2lycWhhbmRsZXIocGVyX2Nw dSh4ZW5fcG11X2lycSwgY3B1KS5pcnEsIE5VTEwpOwotCQlwZXJfY3B1KHhlbl9wbXVfaXJxLCBj cHUpLmlycSA9IC0xOwotCQlrZnJlZShwZXJfY3B1KHhlbl9wbXVfaXJxLCBjcHUpLm5hbWUpOwot CQlwZXJfY3B1KHhlbl9wbXVfaXJxLCBjcHUpLm5hbWUgPSBOVUxMOwotCX0KLX0KLQogaW50IHhl bl9zbXBfaW50cl9pbml0KHVuc2lnbmVkIGludCBjcHUpCiB7CiAJaW50IHJjOwpAQCAtMjA4LDM2 MCArMTE0LDYgQEAgaW50IHhlbl9zbXBfaW50cl9pbml0KHVuc2lnbmVkIGludCBjcHUpCiAJcmV0 dXJuIHJjOwogfQogCi1pbnQgeGVuX3NtcF9pbnRyX2luaXRfcHYodW5zaWduZWQgaW50IGNwdSkK LXsKLQlpbnQgcmM7Ci0JY2hhciAqY2FsbGZ1bmNfbmFtZSwgKnBtdV9uYW1lOwotCi0JY2FsbGZ1 bmNfbmFtZSA9IGthc3ByaW50ZihHRlBfS0VSTkVMLCAiaXJxd29yayVkIiwgY3B1KTsKLQlyYyA9 IGJpbmRfaXBpX3RvX2lycWhhbmRsZXIoWEVOX0lSUV9XT1JLX1ZFQ1RPUiwKLQkJCQkgICAgY3B1 LAotCQkJCSAgICB4ZW5faXJxX3dvcmtfaW50ZXJydXB0LAotCQkJCSAgICBJUlFGX1BFUkNQVXxJ UlFGX05PQkFMQU5DSU5HLAotCQkJCSAgICBjYWxsZnVuY19uYW1lLAotCQkJCSAgICBOVUxMKTsK LQlpZiAocmMgPCAwKQotCQlnb3RvIGZhaWw7Ci0JcGVyX2NwdSh4ZW5faXJxX3dvcmssIGNwdSku aXJxID0gcmM7Ci0JcGVyX2NwdSh4ZW5faXJxX3dvcmssIGNwdSkubmFtZSA9IGNhbGxmdW5jX25h bWU7Ci0KLQlpZiAoaXNfeGVuX3BtdShjcHUpKSB7Ci0JCXBtdV9uYW1lID0ga2FzcHJpbnRmKEdG UF9LRVJORUwsICJwbXUlZCIsIGNwdSk7Ci0JCXJjID0gYmluZF92aXJxX3RvX2lycWhhbmRsZXIo VklSUV9YRU5QTVUsIGNwdSwKLQkJCQkJICAgICB4ZW5fcG11X2lycV9oYW5kbGVyLAotCQkJCQkg ICAgIElSUUZfUEVSQ1BVfElSUUZfTk9CQUxBTkNJTkcsCi0JCQkJCSAgICAgcG11X25hbWUsIE5V TEwpOwotCQlpZiAocmMgPCAwKQotCQkJZ290byBmYWlsOwotCQlwZXJfY3B1KHhlbl9wbXVfaXJx LCBjcHUpLmlycSA9IHJjOwotCQlwZXJfY3B1KHhlbl9wbXVfaXJxLCBjcHUpLm5hbWUgPSBwbXVf bmFtZTsKLQl9Ci0KLQlyZXR1cm4gMDsKLQotIGZhaWw6Ci0JeGVuX3NtcF9pbnRyX2ZyZWVfcHYo Y3B1KTsKLQlyZXR1cm4gcmM7Ci19Ci0KLXN0YXRpYyB2b2lkIF9faW5pdCB4ZW5fZmlsbF9wb3Nz aWJsZV9tYXAodm9pZCkKLXsKLQlpbnQgaSwgcmM7Ci0KLQlpZiAoeGVuX2luaXRpYWxfZG9tYWlu KCkpCi0JCXJldHVybjsKLQotCWZvciAoaSA9IDA7IGkgPCBucl9jcHVfaWRzOyBpKyspIHsKLQkJ cmMgPSBIWVBFUlZJU09SX3ZjcHVfb3AoVkNQVU9QX2lzX3VwLCBpLCBOVUxMKTsKLQkJaWYgKHJj ID49IDApIHsKLQkJCW51bV9wcm9jZXNzb3JzKys7Ci0JCQlzZXRfY3B1X3Bvc3NpYmxlKGksIHRy dWUpOwotCQl9Ci0JfQotfQotCi1zdGF0aWMgdm9pZCBfX2luaXQgeGVuX2ZpbHRlcl9jcHVfbWFw cyh2b2lkKQotewotCWludCBpLCByYzsKLQl1bnNpZ25lZCBpbnQgc3VidHJhY3QgPSAwOwotCi0J aWYgKCF4ZW5faW5pdGlhbF9kb21haW4oKSkKLQkJcmV0dXJuOwotCi0JbnVtX3Byb2Nlc3NvcnMg PSAwOwotCWRpc2FibGVkX2NwdXMgPSAwOwotCWZvciAoaSA9IDA7IGkgPCBucl9jcHVfaWRzOyBp KyspIHsKLQkJcmMgPSBIWVBFUlZJU09SX3ZjcHVfb3AoVkNQVU9QX2lzX3VwLCBpLCBOVUxMKTsK LQkJaWYgKHJjID49IDApIHsKLQkJCW51bV9wcm9jZXNzb3JzKys7Ci0JCQlzZXRfY3B1X3Bvc3Np YmxlKGksIHRydWUpOwotCQl9IGVsc2UgewotCQkJc2V0X2NwdV9wb3NzaWJsZShpLCBmYWxzZSk7 Ci0JCQlzZXRfY3B1X3ByZXNlbnQoaSwgZmFsc2UpOwotCQkJc3VidHJhY3QrKzsKLQkJfQotCX0K LSNpZmRlZiBDT05GSUdfSE9UUExVR19DUFUKLQkvKiBUaGlzIGlzIGFraW4gdG8gdXNpbmcgJ25y X2NwdXMnIG9uIHRoZSBMaW51eCBjb21tYW5kIGxpbmUuCi0JICogV2hpY2ggaXMgT0sgYXMgd2hl biB3ZSB1c2UgJ2RvbTBfbWF4X3ZjcHVzPVgnIHdlIGNhbiBvbmx5Ci0JICogaGF2ZSB1cCB0byBY LCB3aGlsZSBucl9jcHVfaWRzIGlzIGdyZWF0ZXIgdGhhbiBYLiBUaGlzCi0JICogbm9ybWFsbHkg aXMgbm90IGEgcHJvYmxlbSwgZXhjZXB0IHdoZW4gQ1BVIGhvdHBsdWdnaW5nCi0JICogaXMgaW52 b2x2ZWQgYW5kIHRoZW4gdGhlcmUgbWlnaHQgYmUgbW9yZSB0aGFuIFggQ1BVcwotCSAqIGluIHRo ZSBndWVzdCAtIHdoaWNoIHdpbGwgbm90IHdvcmsgYXMgdGhlcmUgaXMgbm8KLQkgKiBoeXBlcmNh bGwgdG8gZXhwYW5kIHRoZSBtYXggbnVtYmVyIG9mIFZDUFVzIGFuIGFscmVhZHkKLQkgKiBydW5u aW5nIGd1ZXN0IGhhcy4gU28gY2FwIGl0IHVwIHRvIFguICovCi0JaWYgKHN1YnRyYWN0KQotCQlu cl9jcHVfaWRzID0gbnJfY3B1X2lkcyAtIHN1YnRyYWN0OwotI2VuZGlmCi0KLX0KLQotc3RhdGlj IHZvaWQgX19pbml0IHhlbl9wdl9zbXBfcHJlcGFyZV9ib290X2NwdSh2b2lkKQotewotCUJVR19P TihzbXBfcHJvY2Vzc29yX2lkKCkgIT0gMCk7Ci0JbmF0aXZlX3NtcF9wcmVwYXJlX2Jvb3RfY3B1 KCk7Ci0KLQlpZiAoIXhlbl9mZWF0dXJlKFhFTkZFQVRfd3JpdGFibGVfcGFnZV90YWJsZXMpKQot CQkvKiBXZSd2ZSBzd2l0Y2hlZCB0byB0aGUgInJlYWwiIHBlci1jcHUgZ2R0LCBzbyBtYWtlCi0J CSAqIHN1cmUgdGhlIG9sZCBtZW1vcnkgY2FuIGJlIHJlY3ljbGVkLiAqLwotCQltYWtlX2xvd21l bV9wYWdlX3JlYWR3cml0ZSh4ZW5faW5pdGlhbF9nZHQpOwotCi0jaWZkZWYgQ09ORklHX1g4Nl8z MgotCS8qCi0JICogWGVuIHN0YXJ0cyB1cyB3aXRoIFhFTl9GTEFUX1JJTkcxX0RTLCBidXQgbGlu dXggY29kZQotCSAqIGV4cGVjdHMgX19VU0VSX0RTCi0JICovCi0JbG9hZHNlZ21lbnQoZHMsIF9f VVNFUl9EUyk7Ci0JbG9hZHNlZ21lbnQoZXMsIF9fVVNFUl9EUyk7Ci0jZW5kaWYKLQotCXhlbl9m aWx0ZXJfY3B1X21hcHMoKTsKLQl4ZW5fc2V0dXBfdmNwdV9pbmZvX3BsYWNlbWVudCgpOwotCi0J LyoKLQkgKiBUaGUgYWx0ZXJuYXRpdmUgbG9naWMgKHdoaWNoIHBhdGNoZXMgdGhlIHVubG9jay9s b2NrKSBydW5zIGJlZm9yZQotCSAqIHRoZSBzbXAgYm9vdHVwIHVwIGNvZGUgaXMgYWN0aXZhdGVk LiBIZW5jZSB3ZSBuZWVkIHRvIHNldCB0aGlzIHVwCi0JICogdGhlIGNvcmUga2VybmVsIGlzIGJl aW5nIHBhdGNoZWQuIE90aGVyd2lzZSB3ZSB3aWxsIGhhdmUgb25seQotCSAqIG1vZHVsZXMgcGF0 Y2hlZCBidXQgbm90IGNvcmUgY29kZS4KLQkgKi8KLQl4ZW5faW5pdF9zcGlubG9ja3MoKTsKLX0K LQotc3RhdGljIHZvaWQgX19pbml0IHhlbl9zbXBfcHJlcGFyZV9jcHVzKHVuc2lnbmVkIGludCBt YXhfY3B1cykKLXsKLQl1bnNpZ25lZCBjcHU7Ci0JdW5zaWduZWQgaW50IGk7Ci0KLQlpZiAoc2tp cF9pb2FwaWNfc2V0dXApIHsKLQkJY2hhciAqbSA9IChtYXhfY3B1cyA9PSAwKSA/Ci0JCQkiVGhl IG5vc21wIHBhcmFtZXRlciBpcyBpbmNvbXBhdGlibGUgd2l0aCBYZW47ICIgXAotCQkJInVzZSBY ZW4gZG9tMF9tYXhfdmNwdXM9MSBwYXJhbWV0ZXIiIDoKLQkJCSJUaGUgbm9hcGljIHBhcmFtZXRl ciBpcyBpbmNvbXBhdGlibGUgd2l0aCBYZW4iOwotCi0JCXhlbl9yYXdfcHJpbnRrKG0pOwotCQlw YW5pYyhtKTsKLQl9Ci0JeGVuX2luaXRfbG9ja19jcHUoMCk7Ci0KLQlzbXBfc3RvcmVfYm9vdF9j cHVfaW5mbygpOwotCWNwdV9kYXRhKDApLng4Nl9tYXhfY29yZXMgPSAxOwotCi0JZm9yX2VhY2hf cG9zc2libGVfY3B1KGkpIHsKLQkJemFsbG9jX2NwdW1hc2tfdmFyKCZwZXJfY3B1KGNwdV9zaWJs aW5nX21hcCwgaSksIEdGUF9LRVJORUwpOwotCQl6YWxsb2NfY3B1bWFza192YXIoJnBlcl9jcHUo Y3B1X2NvcmVfbWFwLCBpKSwgR0ZQX0tFUk5FTCk7Ci0JCXphbGxvY19jcHVtYXNrX3ZhcigmcGVy X2NwdShjcHVfbGxjX3NoYXJlZF9tYXAsIGkpLCBHRlBfS0VSTkVMKTsKLQl9Ci0Jc2V0X2NwdV9z aWJsaW5nX21hcCgwKTsKLQotCXhlbl9wbXVfaW5pdCgwKTsKLQotCWlmICh4ZW5fc21wX2ludHJf aW5pdCgwKSkKLQkJQlVHKCk7Ci0KLQlpZiAoIWFsbG9jX2NwdW1hc2tfdmFyKCZ4ZW5fY3B1X2lu aXRpYWxpemVkX21hcCwgR0ZQX0tFUk5FTCkpCi0JCXBhbmljKCJjb3VsZCBub3QgYWxsb2NhdGUg eGVuX2NwdV9pbml0aWFsaXplZF9tYXBcbiIpOwotCi0JY3B1bWFza19jb3B5KHhlbl9jcHVfaW5p dGlhbGl6ZWRfbWFwLCBjcHVtYXNrX29mKDApKTsKLQotCS8qIFJlc3RyaWN0IHRoZSBwb3NzaWJs ZV9tYXAgYWNjb3JkaW5nIHRvIG1heF9jcHVzLiAqLwotCXdoaWxlICgobnVtX3Bvc3NpYmxlX2Nw dXMoKSA+IDEpICYmIChudW1fcG9zc2libGVfY3B1cygpID4gbWF4X2NwdXMpKSB7Ci0JCWZvciAo Y3B1ID0gbnJfY3B1X2lkcyAtIDE7ICFjcHVfcG9zc2libGUoY3B1KTsgY3B1LS0pCi0JCQljb250 aW51ZTsKLQkJc2V0X2NwdV9wb3NzaWJsZShjcHUsIGZhbHNlKTsKLQl9Ci0KLQlmb3JfZWFjaF9w b3NzaWJsZV9jcHUoY3B1KQotCQlzZXRfY3B1X3ByZXNlbnQoY3B1LCB0cnVlKTsKLX0KLQotc3Rh dGljIGludAotY3B1X2luaXRpYWxpemVfY29udGV4dCh1bnNpZ25lZCBpbnQgY3B1LCBzdHJ1Y3Qg dGFza19zdHJ1Y3QgKmlkbGUpCi17Ci0Jc3RydWN0IHZjcHVfZ3Vlc3RfY29udGV4dCAqY3R4dDsK LQlzdHJ1Y3QgZGVzY19zdHJ1Y3QgKmdkdDsKLQl1bnNpZ25lZCBsb25nIGdkdF9tZm47Ci0KLQkv KiB1c2VkIHRvIHRlbGwgY3B1X2luaXQoKSB0aGF0IGl0IGNhbiBwcm9jZWVkIHdpdGggaW5pdGlh bGl6YXRpb24gKi8KLQljcHVtYXNrX3NldF9jcHUoY3B1LCBjcHVfY2FsbG91dF9tYXNrKTsKLQlp ZiAoY3B1bWFza190ZXN0X2FuZF9zZXRfY3B1KGNwdSwgeGVuX2NwdV9pbml0aWFsaXplZF9tYXAp KQotCQlyZXR1cm4gMDsKLQotCWN0eHQgPSBremFsbG9jKHNpemVvZigqY3R4dCksIEdGUF9LRVJO RUwpOwotCWlmIChjdHh0ID09IE5VTEwpCi0JCXJldHVybiAtRU5PTUVNOwotCi0JZ2R0ID0gZ2V0 X2NwdV9nZHRfdGFibGUoY3B1KTsKLQotI2lmZGVmIENPTkZJR19YODZfMzIKLQljdHh0LT51c2Vy X3JlZ3MuZnMgPSBfX0tFUk5FTF9QRVJDUFU7Ci0JY3R4dC0+dXNlcl9yZWdzLmdzID0gX19LRVJO RUxfU1RBQ0tfQ0FOQVJZOwotI2VuZGlmCi0JbWVtc2V0KCZjdHh0LT5mcHVfY3R4dCwgMCwgc2l6 ZW9mKGN0eHQtPmZwdV9jdHh0KSk7Ci0KLQljdHh0LT51c2VyX3JlZ3MuZWlwID0gKHVuc2lnbmVk IGxvbmcpY3B1X2JyaW5ndXBfYW5kX2lkbGU7Ci0JY3R4dC0+ZmxhZ3MgPSBWR0NGX0lOX0tFUk5F TDsKLQljdHh0LT51c2VyX3JlZ3MuZWZsYWdzID0gMHgxMDAwOyAvKiBJT1BMX1JJTkcxICovCi0J Y3R4dC0+dXNlcl9yZWdzLmRzID0gX19VU0VSX0RTOwotCWN0eHQtPnVzZXJfcmVncy5lcyA9IF9f VVNFUl9EUzsKLQljdHh0LT51c2VyX3JlZ3Muc3MgPSBfX0tFUk5FTF9EUzsKLQotCXhlbl9jb3B5 X3RyYXBfaW5mbyhjdHh0LT50cmFwX2N0eHQpOwotCi0JY3R4dC0+bGR0X2VudHMgPSAwOwotCi0J QlVHX09OKCh1bnNpZ25lZCBsb25nKWdkdCAmIH5QQUdFX01BU0spOwotCi0JZ2R0X21mbiA9IGFy Yml0cmFyeV92aXJ0X3RvX21mbihnZHQpOwotCW1ha2VfbG93bWVtX3BhZ2VfcmVhZG9ubHkoZ2R0 KTsKLQltYWtlX2xvd21lbV9wYWdlX3JlYWRvbmx5KG1mbl90b192aXJ0KGdkdF9tZm4pKTsKLQot CWN0eHQtPmdkdF9mcmFtZXNbMF0gPSBnZHRfbWZuOwotCWN0eHQtPmdkdF9lbnRzICAgICAgPSBH RFRfRU5UUklFUzsKLQotCWN0eHQtPmtlcm5lbF9zcyA9IF9fS0VSTkVMX0RTOwotCWN0eHQtPmtl cm5lbF9zcCA9IGlkbGUtPnRocmVhZC5zcDA7Ci0KLSNpZmRlZiBDT05GSUdfWDg2XzMyCi0JY3R4 dC0+ZXZlbnRfY2FsbGJhY2tfY3MgICAgID0gX19LRVJORUxfQ1M7Ci0JY3R4dC0+ZmFpbHNhZmVf Y2FsbGJhY2tfY3MgID0gX19LRVJORUxfQ1M7Ci0jZWxzZQotCWN0eHQtPmdzX2Jhc2Vfa2VybmVs ID0gcGVyX2NwdV9vZmZzZXQoY3B1KTsKLSNlbmRpZgotCWN0eHQtPmV2ZW50X2NhbGxiYWNrX2Vp cCAgICA9Ci0JCSh1bnNpZ25lZCBsb25nKXhlbl9oeXBlcnZpc29yX2NhbGxiYWNrOwotCWN0eHQt PmZhaWxzYWZlX2NhbGxiYWNrX2VpcCA9Ci0JCSh1bnNpZ25lZCBsb25nKXhlbl9mYWlsc2FmZV9j YWxsYmFjazsKLQljdHh0LT51c2VyX3JlZ3MuY3MgPSBfX0tFUk5FTF9DUzsKLQlwZXJfY3B1KHhl bl9jcjMsIGNwdSkgPSBfX3BhKHN3YXBwZXJfcGdfZGlyKTsKLQotCWN0eHQtPnVzZXJfcmVncy5l c3AgPSBpZGxlLT50aHJlYWQuc3AwIC0gc2l6ZW9mKHN0cnVjdCBwdF9yZWdzKTsKLQljdHh0LT5j dHJscmVnWzNdID0geGVuX3Bmbl90b19jcjModmlydF90b19nZm4oc3dhcHBlcl9wZ19kaXIpKTsK LQlpZiAoSFlQRVJWSVNPUl92Y3B1X29wKFZDUFVPUF9pbml0aWFsaXNlLCB4ZW5fdmNwdV9ucihj cHUpLCBjdHh0KSkKLQkJQlVHKCk7Ci0KLQlrZnJlZShjdHh0KTsKLQlyZXR1cm4gMDsKLX0KLQot c3RhdGljIGludCB4ZW5fY3B1X3VwKHVuc2lnbmVkIGludCBjcHUsIHN0cnVjdCB0YXNrX3N0cnVj dCAqaWRsZSkKLXsKLQlpbnQgcmM7Ci0KLQljb21tb25fY3B1X3VwKGNwdSwgaWRsZSk7Ci0KLQl4 ZW5fc2V0dXBfcnVuc3RhdGVfaW5mbyhjcHUpOwotCi0JLyoKLQkgKiBQViBWQ1BVcyBhcmUgYWx3 YXlzIHN1Y2Nlc3NmdWxseSB0YWtlbiBkb3duIChzZWUgJ3doaWxlJyBsb29wCi0JICogaW4geGVu X2NwdV9kaWUoKSksIHNvIC1FQlVTWSBpcyBhbiBlcnJvci4KLQkgKi8KLQlyYyA9IGNwdV9jaGVj a191cF9wcmVwYXJlKGNwdSk7Ci0JaWYgKHJjKQotCQlyZXR1cm4gcmM7Ci0KLQkvKiBtYWtlIHN1 cmUgaW50ZXJydXB0cyBzdGFydCBibG9ja2VkICovCi0JcGVyX2NwdSh4ZW5fdmNwdSwgY3B1KS0+ ZXZ0Y2huX3VwY2FsbF9tYXNrID0gMTsKLQotCXJjID0gY3B1X2luaXRpYWxpemVfY29udGV4dChj cHUsIGlkbGUpOwotCWlmIChyYykKLQkJcmV0dXJuIHJjOwotCi0JeGVuX3BtdV9pbml0KGNwdSk7 Ci0KLQlyYyA9IEhZUEVSVklTT1JfdmNwdV9vcChWQ1BVT1BfdXAsIHhlbl92Y3B1X25yKGNwdSks IE5VTEwpOwotCUJVR19PTihyYyk7Ci0KLQl3aGlsZSAoY3B1X3JlcG9ydF9zdGF0ZShjcHUpICE9 IENQVV9PTkxJTkUpCi0JCUhZUEVSVklTT1Jfc2NoZWRfb3AoU0NIRURPUF95aWVsZCwgTlVMTCk7 Ci0KLQlyZXR1cm4gMDsKLX0KLQotc3RhdGljIHZvaWQgeGVuX3NtcF9jcHVzX2RvbmUodW5zaWdu ZWQgaW50IG1heF9jcHVzKQotewotfQotCi0jaWZkZWYgQ09ORklHX0hPVFBMVUdfQ1BVCi1zdGF0 aWMgaW50IHhlbl9jcHVfZGlzYWJsZSh2b2lkKQotewotCXVuc2lnbmVkIGludCBjcHUgPSBzbXBf cHJvY2Vzc29yX2lkKCk7Ci0JaWYgKGNwdSA9PSAwKQotCQlyZXR1cm4gLUVCVVNZOwotCi0JY3B1 X2Rpc2FibGVfY29tbW9uKCk7Ci0KLQlsb2FkX2NyMyhzd2FwcGVyX3BnX2Rpcik7Ci0JcmV0dXJu IDA7Ci19Ci0KLXN0YXRpYyB2b2lkIHhlbl9wdl9jcHVfZGllKHVuc2lnbmVkIGludCBjcHUpCi17 Ci0Jd2hpbGUgKEhZUEVSVklTT1JfdmNwdV9vcChWQ1BVT1BfaXNfdXAsCi0JCQkJICB4ZW5fdmNw dV9ucihjcHUpLCBOVUxMKSkgewotCQlfX3NldF9jdXJyZW50X3N0YXRlKFRBU0tfVU5JTlRFUlJV UFRJQkxFKTsKLQkJc2NoZWR1bGVfdGltZW91dChIWi8xMCk7Ci0JfQotCi0JaWYgKGNvbW1vbl9j cHVfZGllKGNwdSkgPT0gMCkgewotCQl4ZW5fc21wX2ludHJfZnJlZShjcHUpOwotCQl4ZW5fdW5p bml0X2xvY2tfY3B1KGNwdSk7Ci0JCXhlbl90ZWFyZG93bl90aW1lcihjcHUpOwotCQl4ZW5fcG11 X2ZpbmlzaChjcHUpOwotCX0KLX0KLQotc3RhdGljIHZvaWQgeGVuX3BsYXlfZGVhZCh2b2lkKSAv KiB1c2VkIG9ubHkgd2l0aCBIT1RQTFVHX0NQVSAqLwotewotCXBsYXlfZGVhZF9jb21tb24oKTsK LQlIWVBFUlZJU09SX3ZjcHVfb3AoVkNQVU9QX2Rvd24sIHhlbl92Y3B1X25yKHNtcF9wcm9jZXNz b3JfaWQoKSksIE5VTEwpOwotCWNwdV9icmluZ3VwKCk7Ci0JLyoKLQkgKiBjb21taXQgNGIwYzBm Mjk0ICh0aWNrOiBDbGVhbnVwIE5PSFogcGVyIGNwdSBkYXRhIG9uIGNwdSBkb3duKQotCSAqIGNs ZWFycyBjZXJ0YWluIGRhdGEgdGhhdCB0aGUgY3B1X2lkbGUgbG9vcCAod2hpY2ggY2FsbGVkIHVz Ci0JICogYW5kIHRoYXQgd2UgcmV0dXJuIGZyb20pIGV4cGVjdHMuIFRoZSBvbmx5IHdheSB0byBn ZXQgdGhhdAotCSAqIGRhdGEgYmFjayBpcyB0byBjYWxsOgotCSAqLwotCXRpY2tfbm9oel9pZGxl X2VudGVyKCk7Ci0KLQljcHVfc3RhcnR1cF9lbnRyeShDUFVIUF9BUF9PTkxJTkVfSURMRSk7Ci19 Ci0KLSNlbHNlIC8qICFDT05GSUdfSE9UUExVR19DUFUgKi8KLXN0YXRpYyBpbnQgeGVuX2NwdV9k aXNhYmxlKHZvaWQpCi17Ci0JcmV0dXJuIC1FTk9TWVM7Ci19Ci0KLXN0YXRpYyB2b2lkIHhlbl9w dl9jcHVfZGllKHVuc2lnbmVkIGludCBjcHUpCi17Ci0JQlVHKCk7Ci19Ci0KLXN0YXRpYyB2b2lk IHhlbl9wbGF5X2RlYWQodm9pZCkKLXsKLQlCVUcoKTsKLX0KLQotI2VuZGlmCi1zdGF0aWMgdm9p ZCBzdG9wX3NlbGYodm9pZCAqdikKLXsKLQlpbnQgY3B1ID0gc21wX3Byb2Nlc3Nvcl9pZCgpOwot Ci0JLyogbWFrZSBzdXJlIHdlJ3JlIG5vdCBwaW5uaW5nIHNvbWV0aGluZyBkb3duICovCi0JbG9h ZF9jcjMoc3dhcHBlcl9wZ19kaXIpOwotCS8qIHNob3VsZCBzZXQgdXAgYSBtaW5pbWFsIGdkdCAq LwotCi0Jc2V0X2NwdV9vbmxpbmUoY3B1LCBmYWxzZSk7Ci0KLQlIWVBFUlZJU09SX3ZjcHVfb3Ao VkNQVU9QX2Rvd24sIHhlbl92Y3B1X25yKGNwdSksIE5VTEwpOwotCUJVRygpOwotfQotCi1zdGF0 aWMgdm9pZCB4ZW5fc3RvcF9vdGhlcl9jcHVzKGludCB3YWl0KQotewotCXNtcF9jYWxsX2Z1bmN0 aW9uKHN0b3Bfc2VsZiwgTlVMTCwgd2FpdCk7Ci19Ci0KIHZvaWQgeGVuX3NtcF9zZW5kX3Jlc2No ZWR1bGUoaW50IGNwdSkKIHsKIAl4ZW5fc2VuZF9JUElfb25lKGNwdSwgWEVOX1JFU0NIRURVTEVf VkVDVE9SKTsKQEAgLTY5NiwzNiArMjQ4LDMgQEAgc3RhdGljIGlycXJldHVybl90IHhlbl9jYWxs X2Z1bmN0aW9uX3NpbmdsZV9pbnRlcnJ1cHQoaW50IGlycSwgdm9pZCAqZGV2X2lkKQogCiAJcmV0 dXJuIElSUV9IQU5ETEVEOwogfQotCi1zdGF0aWMgaXJxcmV0dXJuX3QgeGVuX2lycV93b3JrX2lu dGVycnVwdChpbnQgaXJxLCB2b2lkICpkZXZfaWQpCi17Ci0JaXJxX2VudGVyKCk7Ci0JaXJxX3dv cmtfcnVuKCk7Ci0JaW5jX2lycV9zdGF0KGFwaWNfaXJxX3dvcmtfaXJxcyk7Ci0JaXJxX2V4aXQo KTsKLQotCXJldHVybiBJUlFfSEFORExFRDsKLX0KLQotc3RhdGljIGNvbnN0IHN0cnVjdCBzbXBf b3BzIHhlbl9zbXBfb3BzIF9faW5pdGNvbnN0ID0gewotCS5zbXBfcHJlcGFyZV9ib290X2NwdSA9 IHhlbl9wdl9zbXBfcHJlcGFyZV9ib290X2NwdSwKLQkuc21wX3ByZXBhcmVfY3B1cyA9IHhlbl9z bXBfcHJlcGFyZV9jcHVzLAotCS5zbXBfY3B1c19kb25lID0geGVuX3NtcF9jcHVzX2RvbmUsCi0K LQkuY3B1X3VwID0geGVuX2NwdV91cCwKLQkuY3B1X2RpZSA9IHhlbl9wdl9jcHVfZGllLAotCS5j cHVfZGlzYWJsZSA9IHhlbl9jcHVfZGlzYWJsZSwKLQkucGxheV9kZWFkID0geGVuX3BsYXlfZGVh ZCwKLQotCS5zdG9wX290aGVyX2NwdXMgPSB4ZW5fc3RvcF9vdGhlcl9jcHVzLAotCS5zbXBfc2Vu ZF9yZXNjaGVkdWxlID0geGVuX3NtcF9zZW5kX3Jlc2NoZWR1bGUsCi0KLQkuc2VuZF9jYWxsX2Z1 bmNfaXBpID0geGVuX3NtcF9zZW5kX2NhbGxfZnVuY3Rpb25faXBpLAotCS5zZW5kX2NhbGxfZnVu Y19zaW5nbGVfaXBpID0geGVuX3NtcF9zZW5kX2NhbGxfZnVuY3Rpb25fc2luZ2xlX2lwaSwKLX07 Ci0KLXZvaWQgX19pbml0IHhlbl9zbXBfaW5pdCh2b2lkKQotewotCXNtcF9vcHMgPSB4ZW5fc21w X29wczsKLQl4ZW5fZmlsbF9wb3NzaWJsZV9tYXAoKTsKLX0KZGlmZiAtLWdpdCBhL2FyY2gveDg2 L3hlbi9zbXAuaCBiL2FyY2gveDg2L3hlbi9zbXAuaAppbmRleCBiZjM2ZTc5Li4zMjQ1MzQzIDEw MDY0NAotLS0gYS9hcmNoL3g4Ni94ZW4vc21wLmgKKysrIGIvYXJjaC94ODYveGVuL3NtcC5oCkBA IC0xNyw2ICsxNywxMSBAQCBleHRlcm4gdm9pZCB4ZW5fc21wX2ludHJfZnJlZV9wdih1bnNpZ25l ZCBpbnQgY3B1KTsKIGV4dGVybiB2b2lkIHhlbl9zbXBfc2VuZF9yZXNjaGVkdWxlKGludCBjcHUp OwogZXh0ZXJuIHZvaWQgeGVuX3NtcF9zZW5kX2NhbGxfZnVuY3Rpb25faXBpKGNvbnN0IHN0cnVj dCBjcHVtYXNrICptYXNrKTsKIGV4dGVybiB2b2lkIHhlbl9zbXBfc2VuZF9jYWxsX2Z1bmN0aW9u X3NpbmdsZV9pcGkoaW50IGNwdSk7CisKK3N0cnVjdCB4ZW5fY29tbW9uX2lycSB7CisJaW50IGly cTsKKwljaGFyICpuYW1lOworfTsKICNlbHNlIC8qIENPTkZJR19TTVAgKi8KIAogc3RhdGljIGlu bGluZSBpbnQgeGVuX3NtcF9pbnRyX2luaXQodW5zaWduZWQgaW50IGNwdSkKZGlmZiAtLWdpdCBh L2FyY2gveDg2L3hlbi9zbXBfcHYuYyBiL2FyY2gveDg2L3hlbi9zbXBfcHYuYwpuZXcgZmlsZSBt b2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMjA3MThhCi0tLSAvZGV2L251bGwKKysrIGIvYXJj aC94ODYveGVuL3NtcF9wdi5jCkBAIC0wLDAgKzEsNDk5IEBACisvKgorICogWGVuIFNNUCBzdXBw b3J0CisgKgorICogVGhpcyBmaWxlIGltcGxlbWVudHMgdGhlIFhlbiB2ZXJzaW9ucyBvZiBzbXBf b3BzLiAgU01QIHVuZGVyIFhlbiBpcworICogdmVyeSBzdHJhaWdodGZvcndhcmQuICBCcmluZ2lu ZyBhIENQVSB1cCBpcyBzaW1wbHkgYSBtYXR0ZXIgb2YKKyAqIGxvYWRpbmcgaXRzIGluaXRpYWwg Y29udGV4dCBhbmQgc2V0dGluZyBpdCBydW5uaW5nLgorICoKKyAqIElQSXMgYXJlIGhhbmRsZWQg dGhyb3VnaCB0aGUgWGVuIGV2ZW50IG1lY2hhbmlzbS4KKyAqCisgKiBCZWNhdXNlIHZpcnR1YWwg Q1BVcyBjYW4gYmUgc2NoZWR1bGVkIG9udG8gYW55IHJlYWwgQ1BVLCB0aGVyZSdzIG5vCisgKiB1 c2VmdWwgdG9wb2xvZ3kgaW5mb3JtYXRpb24gZm9yIHRoZSBrZXJuZWwgdG8gbWFrZSB1c2Ugb2Yu ICBBcyBhCisgKiByZXN1bHQsIGFsbCBDUFVzIGFyZSB0cmVhdGVkIGFzIGlmIHRoZXkncmUgc2lu Z2xlLWNvcmUgYW5kCisgKiBzaW5nbGUtdGhyZWFkZWQuCisgKi8KKyNpbmNsdWRlIDxsaW51eC9z Y2hlZC5oPgorI2luY2x1ZGUgPGxpbnV4L2Vyci5oPgorI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4K KyNpbmNsdWRlIDxsaW51eC9zbXAuaD4KKyNpbmNsdWRlIDxsaW51eC9pcnFfd29yay5oPgorI2lu Y2x1ZGUgPGxpbnV4L3RpY2suaD4KKworI2luY2x1ZGUgPGFzbS9wYXJhdmlydC5oPgorI2luY2x1 ZGUgPGFzbS9kZXNjLmg+CisjaW5jbHVkZSA8YXNtL3BndGFibGUuaD4KKyNpbmNsdWRlIDxhc20v Y3B1Lmg+CisKKyNpbmNsdWRlIDx4ZW4vaW50ZXJmYWNlL3hlbi5oPgorI2luY2x1ZGUgPHhlbi9p bnRlcmZhY2UvdmNwdS5oPgorI2luY2x1ZGUgPHhlbi9pbnRlcmZhY2UveGVucG11Lmg+CisKKyNp bmNsdWRlIDxhc20veGVuL2ludGVyZmFjZS5oPgorI2luY2x1ZGUgPGFzbS94ZW4vaHlwZXJjYWxs Lmg+CisKKyNpbmNsdWRlIDx4ZW4veGVuLmg+CisjaW5jbHVkZSA8eGVuL3BhZ2UuaD4KKyNpbmNs dWRlIDx4ZW4vZXZlbnRzLmg+CisKKyNpbmNsdWRlIDx4ZW4vaHZjLWNvbnNvbGUuaD4KKyNpbmNs dWRlICJ4ZW4tb3BzLmgiCisjaW5jbHVkZSAibW11LmgiCisjaW5jbHVkZSAic21wLmgiCisjaW5j bHVkZSAicG11LmgiCisKK2NwdW1hc2tfdmFyX3QgeGVuX2NwdV9pbml0aWFsaXplZF9tYXA7CisK K3N0YXRpYyBERUZJTkVfUEVSX0NQVShzdHJ1Y3QgeGVuX2NvbW1vbl9pcnEsIHhlbl9pcnFfd29y aykgPSB7IC5pcnEgPSAtMSB9Oworc3RhdGljIERFRklORV9QRVJfQ1BVKHN0cnVjdCB4ZW5fY29t bW9uX2lycSwgeGVuX3BtdV9pcnEpID0geyAuaXJxID0gLTEgfTsKKworc3RhdGljIGlycXJldHVy bl90IHhlbl9pcnFfd29ya19pbnRlcnJ1cHQoaW50IGlycSwgdm9pZCAqZGV2X2lkKTsKKworc3Rh dGljIHZvaWQgY3B1X2JyaW5ndXAodm9pZCkKK3sKKwlpbnQgY3B1OworCisJY3B1X2luaXQoKTsK Kwl0b3VjaF9zb2Z0bG9ja3VwX3dhdGNoZG9nKCk7CisJcHJlZW1wdF9kaXNhYmxlKCk7CisKKwkv KiBQVkggcnVucyBpbiByaW5nIDAgYW5kIGFsbG93cyB1cyB0byBkbyBuYXRpdmUgc3lzY2FsbHMu IFlheSEgKi8KKwlpZiAoIXhlbl9mZWF0dXJlKFhFTkZFQVRfc3VwZXJ2aXNvcl9tb2RlX2tlcm5l bCkpIHsKKwkJeGVuX2VuYWJsZV9zeXNlbnRlcigpOworCQl4ZW5fZW5hYmxlX3N5c2NhbGwoKTsK Kwl9CisJY3B1ID0gc21wX3Byb2Nlc3Nvcl9pZCgpOworCXNtcF9zdG9yZV9jcHVfaW5mbyhjcHUp OworCWNwdV9kYXRhKGNwdSkueDg2X21heF9jb3JlcyA9IDE7CisJc2V0X2NwdV9zaWJsaW5nX21h cChjcHUpOworCisJeGVuX3NldHVwX2NwdV9jbG9ja2V2ZW50cygpOworCisJbm90aWZ5X2NwdV9z dGFydGluZyhjcHUpOworCisJc2V0X2NwdV9vbmxpbmUoY3B1LCB0cnVlKTsKKworCWNwdV9zZXRf c3RhdGVfb25saW5lKGNwdSk7ICAvKiBJbXBsaWVzIGZ1bGwgbWVtb3J5IGJhcnJpZXIuICovCisK KwkvKiBXZSBjYW4gdGFrZSBpbnRlcnJ1cHRzIG5vdzogd2UncmUgb2ZmaWNpYWxseSAidXAiLiAq LworCWxvY2FsX2lycV9lbmFibGUoKTsKK30KKworYXNtbGlua2FnZSBfX3Zpc2libGUgdm9pZCBj cHVfYnJpbmd1cF9hbmRfaWRsZSh2b2lkKQoreworCWNwdV9icmluZ3VwKCk7CisJY3B1X3N0YXJ0 dXBfZW50cnkoQ1BVSFBfQVBfT05MSU5FX0lETEUpOworfQorCit2b2lkIHhlbl9zbXBfaW50cl9m cmVlX3B2KHVuc2lnbmVkIGludCBjcHUpCit7CisJaWYgKHBlcl9jcHUoeGVuX2lycV93b3JrLCBj cHUpLmlycSA+PSAwKSB7CisJCXVuYmluZF9mcm9tX2lycWhhbmRsZXIocGVyX2NwdSh4ZW5faXJx X3dvcmssIGNwdSkuaXJxLCBOVUxMKTsKKwkJcGVyX2NwdSh4ZW5faXJxX3dvcmssIGNwdSkuaXJx ID0gLTE7CisJCWtmcmVlKHBlcl9jcHUoeGVuX2lycV93b3JrLCBjcHUpLm5hbWUpOworCQlwZXJf Y3B1KHhlbl9pcnFfd29yaywgY3B1KS5uYW1lID0gTlVMTDsKKwl9CisKKwlpZiAocGVyX2NwdSh4 ZW5fcG11X2lycSwgY3B1KS5pcnEgPj0gMCkgeworCQl1bmJpbmRfZnJvbV9pcnFoYW5kbGVyKHBl cl9jcHUoeGVuX3BtdV9pcnEsIGNwdSkuaXJxLCBOVUxMKTsKKwkJcGVyX2NwdSh4ZW5fcG11X2ly cSwgY3B1KS5pcnEgPSAtMTsKKwkJa2ZyZWUocGVyX2NwdSh4ZW5fcG11X2lycSwgY3B1KS5uYW1l KTsKKwkJcGVyX2NwdSh4ZW5fcG11X2lycSwgY3B1KS5uYW1lID0gTlVMTDsKKwl9Cit9CisKK2lu dCB4ZW5fc21wX2ludHJfaW5pdF9wdih1bnNpZ25lZCBpbnQgY3B1KQoreworCWludCByYzsKKwlj aGFyICpjYWxsZnVuY19uYW1lLCAqcG11X25hbWU7CisKKwljYWxsZnVuY19uYW1lID0ga2FzcHJp bnRmKEdGUF9LRVJORUwsICJpcnF3b3JrJWQiLCBjcHUpOworCXJjID0gYmluZF9pcGlfdG9faXJx aGFuZGxlcihYRU5fSVJRX1dPUktfVkVDVE9SLAorCQkJCSAgICBjcHUsCisJCQkJICAgIHhlbl9p cnFfd29ya19pbnRlcnJ1cHQsCisJCQkJICAgIElSUUZfUEVSQ1BVfElSUUZfTk9CQUxBTkNJTkcs CisJCQkJICAgIGNhbGxmdW5jX25hbWUsCisJCQkJICAgIE5VTEwpOworCWlmIChyYyA8IDApCisJ CWdvdG8gZmFpbDsKKwlwZXJfY3B1KHhlbl9pcnFfd29yaywgY3B1KS5pcnEgPSByYzsKKwlwZXJf Y3B1KHhlbl9pcnFfd29yaywgY3B1KS5uYW1lID0gY2FsbGZ1bmNfbmFtZTsKKworCWlmIChpc194 ZW5fcG11KGNwdSkpIHsKKwkJcG11X25hbWUgPSBrYXNwcmludGYoR0ZQX0tFUk5FTCwgInBtdSVk IiwgY3B1KTsKKwkJcmMgPSBiaW5kX3ZpcnFfdG9faXJxaGFuZGxlcihWSVJRX1hFTlBNVSwgY3B1 LAorCQkJCQkgICAgIHhlbl9wbXVfaXJxX2hhbmRsZXIsCisJCQkJCSAgICAgSVJRRl9QRVJDUFV8 SVJRRl9OT0JBTEFOQ0lORywKKwkJCQkJICAgICBwbXVfbmFtZSwgTlVMTCk7CisJCWlmIChyYyA8 IDApCisJCQlnb3RvIGZhaWw7CisJCXBlcl9jcHUoeGVuX3BtdV9pcnEsIGNwdSkuaXJxID0gcmM7 CisJCXBlcl9jcHUoeGVuX3BtdV9pcnEsIGNwdSkubmFtZSA9IHBtdV9uYW1lOworCX0KKworCXJl dHVybiAwOworCisgZmFpbDoKKwl4ZW5fc21wX2ludHJfZnJlZV9wdihjcHUpOworCXJldHVybiBy YzsKK30KKworc3RhdGljIHZvaWQgX19pbml0IHhlbl9maWxsX3Bvc3NpYmxlX21hcCh2b2lkKQor eworCWludCBpLCByYzsKKworCWlmICh4ZW5faW5pdGlhbF9kb21haW4oKSkKKwkJcmV0dXJuOwor CisJZm9yIChpID0gMDsgaSA8IG5yX2NwdV9pZHM7IGkrKykgeworCQlyYyA9IEhZUEVSVklTT1Jf dmNwdV9vcChWQ1BVT1BfaXNfdXAsIGksIE5VTEwpOworCQlpZiAocmMgPj0gMCkgeworCQkJbnVt X3Byb2Nlc3NvcnMrKzsKKwkJCXNldF9jcHVfcG9zc2libGUoaSwgdHJ1ZSk7CisJCX0KKwl9Cit9 CisKK3N0YXRpYyB2b2lkIF9faW5pdCB4ZW5fZmlsdGVyX2NwdV9tYXBzKHZvaWQpCit7CisJaW50 IGksIHJjOworCXVuc2lnbmVkIGludCBzdWJ0cmFjdCA9IDA7CisKKwlpZiAoIXhlbl9pbml0aWFs X2RvbWFpbigpKQorCQlyZXR1cm47CisKKwludW1fcHJvY2Vzc29ycyA9IDA7CisJZGlzYWJsZWRf Y3B1cyA9IDA7CisJZm9yIChpID0gMDsgaSA8IG5yX2NwdV9pZHM7IGkrKykgeworCQlyYyA9IEhZ UEVSVklTT1JfdmNwdV9vcChWQ1BVT1BfaXNfdXAsIGksIE5VTEwpOworCQlpZiAocmMgPj0gMCkg eworCQkJbnVtX3Byb2Nlc3NvcnMrKzsKKwkJCXNldF9jcHVfcG9zc2libGUoaSwgdHJ1ZSk7CisJ CX0gZWxzZSB7CisJCQlzZXRfY3B1X3Bvc3NpYmxlKGksIGZhbHNlKTsKKwkJCXNldF9jcHVfcHJl c2VudChpLCBmYWxzZSk7CisJCQlzdWJ0cmFjdCsrOworCQl9CisJfQorI2lmZGVmIENPTkZJR19I T1RQTFVHX0NQVQorCS8qIFRoaXMgaXMgYWtpbiB0byB1c2luZyAnbnJfY3B1cycgb24gdGhlIExp bnV4IGNvbW1hbmQgbGluZS4KKwkgKiBXaGljaCBpcyBPSyBhcyB3aGVuIHdlIHVzZSAnZG9tMF9t YXhfdmNwdXM9WCcgd2UgY2FuIG9ubHkKKwkgKiBoYXZlIHVwIHRvIFgsIHdoaWxlIG5yX2NwdV9p ZHMgaXMgZ3JlYXRlciB0aGFuIFguIFRoaXMKKwkgKiBub3JtYWxseSBpcyBub3QgYSBwcm9ibGVt LCBleGNlcHQgd2hlbiBDUFUgaG90cGx1Z2dpbmcKKwkgKiBpcyBpbnZvbHZlZCBhbmQgdGhlbiB0 aGVyZSBtaWdodCBiZSBtb3JlIHRoYW4gWCBDUFVzCisJICogaW4gdGhlIGd1ZXN0IC0gd2hpY2gg d2lsbCBub3Qgd29yayBhcyB0aGVyZSBpcyBubworCSAqIGh5cGVyY2FsbCB0byBleHBhbmQgdGhl IG1heCBudW1iZXIgb2YgVkNQVXMgYW4gYWxyZWFkeQorCSAqIHJ1bm5pbmcgZ3Vlc3QgaGFzLiBT byBjYXAgaXQgdXAgdG8gWC4gKi8KKwlpZiAoc3VidHJhY3QpCisJCW5yX2NwdV9pZHMgPSBucl9j cHVfaWRzIC0gc3VidHJhY3Q7CisjZW5kaWYKKworfQorCitzdGF0aWMgdm9pZCBfX2luaXQgeGVu X3B2X3NtcF9wcmVwYXJlX2Jvb3RfY3B1KHZvaWQpCit7CisJQlVHX09OKHNtcF9wcm9jZXNzb3Jf aWQoKSAhPSAwKTsKKwluYXRpdmVfc21wX3ByZXBhcmVfYm9vdF9jcHUoKTsKKworCWlmICgheGVu X2ZlYXR1cmUoWEVORkVBVF93cml0YWJsZV9wYWdlX3RhYmxlcykpCisJCS8qIFdlJ3ZlIHN3aXRj aGVkIHRvIHRoZSAicmVhbCIgcGVyLWNwdSBnZHQsIHNvIG1ha2UKKwkJICogc3VyZSB0aGUgb2xk IG1lbW9yeSBjYW4gYmUgcmVjeWNsZWQuICovCisJCW1ha2VfbG93bWVtX3BhZ2VfcmVhZHdyaXRl KHhlbl9pbml0aWFsX2dkdCk7CisKKyNpZmRlZiBDT05GSUdfWDg2XzMyCisJLyoKKwkgKiBYZW4g c3RhcnRzIHVzIHdpdGggWEVOX0ZMQVRfUklORzFfRFMsIGJ1dCBsaW51eCBjb2RlCisJICogZXhw ZWN0cyBfX1VTRVJfRFMKKwkgKi8KKwlsb2Fkc2VnbWVudChkcywgX19VU0VSX0RTKTsKKwlsb2Fk c2VnbWVudChlcywgX19VU0VSX0RTKTsKKyNlbmRpZgorCisJeGVuX2ZpbHRlcl9jcHVfbWFwcygp OworCXhlbl9zZXR1cF92Y3B1X2luZm9fcGxhY2VtZW50KCk7CisKKwkvKgorCSAqIFRoZSBhbHRl cm5hdGl2ZSBsb2dpYyAod2hpY2ggcGF0Y2hlcyB0aGUgdW5sb2NrL2xvY2spIHJ1bnMgYmVmb3Jl CisJICogdGhlIHNtcCBib290dXAgdXAgY29kZSBpcyBhY3RpdmF0ZWQuIEhlbmNlIHdlIG5lZWQg dG8gc2V0IHRoaXMgdXAKKwkgKiB0aGUgY29yZSBrZXJuZWwgaXMgYmVpbmcgcGF0Y2hlZC4gT3Ro ZXJ3aXNlIHdlIHdpbGwgaGF2ZSBvbmx5CisJICogbW9kdWxlcyBwYXRjaGVkIGJ1dCBub3QgY29y ZSBjb2RlLgorCSAqLworCXhlbl9pbml0X3NwaW5sb2NrcygpOworfQorCitzdGF0aWMgdm9pZCBf X2luaXQgeGVuX3NtcF9wcmVwYXJlX2NwdXModW5zaWduZWQgaW50IG1heF9jcHVzKQoreworCXVu c2lnbmVkIGNwdTsKKwl1bnNpZ25lZCBpbnQgaTsKKworCWlmIChza2lwX2lvYXBpY19zZXR1cCkg eworCQljaGFyICptID0gKG1heF9jcHVzID09IDApID8KKwkJCSJUaGUgbm9zbXAgcGFyYW1ldGVy IGlzIGluY29tcGF0aWJsZSB3aXRoIFhlbjsgIiBcCisJCQkidXNlIFhlbiBkb20wX21heF92Y3B1 cz0xIHBhcmFtZXRlciIgOgorCQkJIlRoZSBub2FwaWMgcGFyYW1ldGVyIGlzIGluY29tcGF0aWJs ZSB3aXRoIFhlbiI7CisKKwkJeGVuX3Jhd19wcmludGsobSk7CisJCXBhbmljKG0pOworCX0KKwl4 ZW5faW5pdF9sb2NrX2NwdSgwKTsKKworCXNtcF9zdG9yZV9ib290X2NwdV9pbmZvKCk7CisJY3B1 X2RhdGEoMCkueDg2X21heF9jb3JlcyA9IDE7CisKKwlmb3JfZWFjaF9wb3NzaWJsZV9jcHUoaSkg eworCQl6YWxsb2NfY3B1bWFza192YXIoJnBlcl9jcHUoY3B1X3NpYmxpbmdfbWFwLCBpKSwgR0ZQ X0tFUk5FTCk7CisJCXphbGxvY19jcHVtYXNrX3ZhcigmcGVyX2NwdShjcHVfY29yZV9tYXAsIGkp LCBHRlBfS0VSTkVMKTsKKwkJemFsbG9jX2NwdW1hc2tfdmFyKCZwZXJfY3B1KGNwdV9sbGNfc2hh cmVkX21hcCwgaSksIEdGUF9LRVJORUwpOworCX0KKwlzZXRfY3B1X3NpYmxpbmdfbWFwKDApOwor CisJeGVuX3BtdV9pbml0KDApOworCisJaWYgKHhlbl9zbXBfaW50cl9pbml0KDApKQorCQlCVUco KTsKKworCWlmICghYWxsb2NfY3B1bWFza192YXIoJnhlbl9jcHVfaW5pdGlhbGl6ZWRfbWFwLCBH RlBfS0VSTkVMKSkKKwkJcGFuaWMoImNvdWxkIG5vdCBhbGxvY2F0ZSB4ZW5fY3B1X2luaXRpYWxp emVkX21hcFxuIik7CisKKwljcHVtYXNrX2NvcHkoeGVuX2NwdV9pbml0aWFsaXplZF9tYXAsIGNw dW1hc2tfb2YoMCkpOworCisJLyogUmVzdHJpY3QgdGhlIHBvc3NpYmxlX21hcCBhY2NvcmRpbmcg dG8gbWF4X2NwdXMuICovCisJd2hpbGUgKChudW1fcG9zc2libGVfY3B1cygpID4gMSkgJiYgKG51 bV9wb3NzaWJsZV9jcHVzKCkgPiBtYXhfY3B1cykpIHsKKwkJZm9yIChjcHUgPSBucl9jcHVfaWRz IC0gMTsgIWNwdV9wb3NzaWJsZShjcHUpOyBjcHUtLSkKKwkJCWNvbnRpbnVlOworCQlzZXRfY3B1 X3Bvc3NpYmxlKGNwdSwgZmFsc2UpOworCX0KKworCWZvcl9lYWNoX3Bvc3NpYmxlX2NwdShjcHUp CisJCXNldF9jcHVfcHJlc2VudChjcHUsIHRydWUpOworfQorCitzdGF0aWMgaW50CitjcHVfaW5p dGlhbGl6ZV9jb250ZXh0KHVuc2lnbmVkIGludCBjcHUsIHN0cnVjdCB0YXNrX3N0cnVjdCAqaWRs ZSkKK3sKKwlzdHJ1Y3QgdmNwdV9ndWVzdF9jb250ZXh0ICpjdHh0OworCXN0cnVjdCBkZXNjX3N0 cnVjdCAqZ2R0OworCXVuc2lnbmVkIGxvbmcgZ2R0X21mbjsKKworCS8qIHVzZWQgdG8gdGVsbCBj cHVfaW5pdCgpIHRoYXQgaXQgY2FuIHByb2NlZWQgd2l0aCBpbml0aWFsaXphdGlvbiAqLworCWNw dW1hc2tfc2V0X2NwdShjcHUsIGNwdV9jYWxsb3V0X21hc2spOworCWlmIChjcHVtYXNrX3Rlc3Rf YW5kX3NldF9jcHUoY3B1LCB4ZW5fY3B1X2luaXRpYWxpemVkX21hcCkpCisJCXJldHVybiAwOwor CisJY3R4dCA9IGt6YWxsb2Moc2l6ZW9mKCpjdHh0KSwgR0ZQX0tFUk5FTCk7CisJaWYgKGN0eHQg PT0gTlVMTCkKKwkJcmV0dXJuIC1FTk9NRU07CisKKwlnZHQgPSBnZXRfY3B1X2dkdF90YWJsZShj cHUpOworCisjaWZkZWYgQ09ORklHX1g4Nl8zMgorCWN0eHQtPnVzZXJfcmVncy5mcyA9IF9fS0VS TkVMX1BFUkNQVTsKKwljdHh0LT51c2VyX3JlZ3MuZ3MgPSBfX0tFUk5FTF9TVEFDS19DQU5BUlk7 CisjZW5kaWYKKwltZW1zZXQoJmN0eHQtPmZwdV9jdHh0LCAwLCBzaXplb2YoY3R4dC0+ZnB1X2N0 eHQpKTsKKworCWN0eHQtPnVzZXJfcmVncy5laXAgPSAodW5zaWduZWQgbG9uZyljcHVfYnJpbmd1 cF9hbmRfaWRsZTsKKwljdHh0LT5mbGFncyA9IFZHQ0ZfSU5fS0VSTkVMOworCWN0eHQtPnVzZXJf cmVncy5lZmxhZ3MgPSAweDEwMDA7IC8qIElPUExfUklORzEgKi8KKwljdHh0LT51c2VyX3JlZ3Mu ZHMgPSBfX1VTRVJfRFM7CisJY3R4dC0+dXNlcl9yZWdzLmVzID0gX19VU0VSX0RTOworCWN0eHQt PnVzZXJfcmVncy5zcyA9IF9fS0VSTkVMX0RTOworCisJeGVuX2NvcHlfdHJhcF9pbmZvKGN0eHQt PnRyYXBfY3R4dCk7CisKKwljdHh0LT5sZHRfZW50cyA9IDA7CisKKwlCVUdfT04oKHVuc2lnbmVk IGxvbmcpZ2R0ICYgflBBR0VfTUFTSyk7CisKKwlnZHRfbWZuID0gYXJiaXRyYXJ5X3ZpcnRfdG9f bWZuKGdkdCk7CisJbWFrZV9sb3dtZW1fcGFnZV9yZWFkb25seShnZHQpOworCW1ha2VfbG93bWVt X3BhZ2VfcmVhZG9ubHkobWZuX3RvX3ZpcnQoZ2R0X21mbikpOworCisJY3R4dC0+Z2R0X2ZyYW1l c1swXSA9IGdkdF9tZm47CisJY3R4dC0+Z2R0X2VudHMgICAgICA9IEdEVF9FTlRSSUVTOworCisJ Y3R4dC0+a2VybmVsX3NzID0gX19LRVJORUxfRFM7CisJY3R4dC0+a2VybmVsX3NwID0gaWRsZS0+ dGhyZWFkLnNwMDsKKworI2lmZGVmIENPTkZJR19YODZfMzIKKwljdHh0LT5ldmVudF9jYWxsYmFj a19jcyAgICAgPSBfX0tFUk5FTF9DUzsKKwljdHh0LT5mYWlsc2FmZV9jYWxsYmFja19jcyAgPSBf X0tFUk5FTF9DUzsKKyNlbHNlCisJY3R4dC0+Z3NfYmFzZV9rZXJuZWwgPSBwZXJfY3B1X29mZnNl dChjcHUpOworI2VuZGlmCisJY3R4dC0+ZXZlbnRfY2FsbGJhY2tfZWlwICAgID0KKwkJKHVuc2ln bmVkIGxvbmcpeGVuX2h5cGVydmlzb3JfY2FsbGJhY2s7CisJY3R4dC0+ZmFpbHNhZmVfY2FsbGJh Y2tfZWlwID0KKwkJKHVuc2lnbmVkIGxvbmcpeGVuX2ZhaWxzYWZlX2NhbGxiYWNrOworCWN0eHQt PnVzZXJfcmVncy5jcyA9IF9fS0VSTkVMX0NTOworCXBlcl9jcHUoeGVuX2NyMywgY3B1KSA9IF9f cGEoc3dhcHBlcl9wZ19kaXIpOworCisJY3R4dC0+dXNlcl9yZWdzLmVzcCA9IGlkbGUtPnRocmVh ZC5zcDAgLSBzaXplb2Yoc3RydWN0IHB0X3JlZ3MpOworCWN0eHQtPmN0cmxyZWdbM10gPSB4ZW5f cGZuX3RvX2NyMyh2aXJ0X3RvX2dmbihzd2FwcGVyX3BnX2RpcikpOworCWlmIChIWVBFUlZJU09S X3ZjcHVfb3AoVkNQVU9QX2luaXRpYWxpc2UsIHhlbl92Y3B1X25yKGNwdSksIGN0eHQpKQorCQlC VUcoKTsKKworCWtmcmVlKGN0eHQpOworCXJldHVybiAwOworfQorCitzdGF0aWMgaW50IHhlbl9j cHVfdXAodW5zaWduZWQgaW50IGNwdSwgc3RydWN0IHRhc2tfc3RydWN0ICppZGxlKQoreworCWlu dCByYzsKKworCWNvbW1vbl9jcHVfdXAoY3B1LCBpZGxlKTsKKworCXhlbl9zZXR1cF9ydW5zdGF0 ZV9pbmZvKGNwdSk7CisKKwkvKgorCSAqIFBWIFZDUFVzIGFyZSBhbHdheXMgc3VjY2Vzc2Z1bGx5 IHRha2VuIGRvd24gKHNlZSAnd2hpbGUnIGxvb3AKKwkgKiBpbiB4ZW5fY3B1X2RpZSgpKSwgc28g LUVCVVNZIGlzIGFuIGVycm9yLgorCSAqLworCXJjID0gY3B1X2NoZWNrX3VwX3ByZXBhcmUoY3B1 KTsKKwlpZiAocmMpCisJCXJldHVybiByYzsKKworCS8qIG1ha2Ugc3VyZSBpbnRlcnJ1cHRzIHN0 YXJ0IGJsb2NrZWQgKi8KKwlwZXJfY3B1KHhlbl92Y3B1LCBjcHUpLT5ldnRjaG5fdXBjYWxsX21h c2sgPSAxOworCisJcmMgPSBjcHVfaW5pdGlhbGl6ZV9jb250ZXh0KGNwdSwgaWRsZSk7CisJaWYg KHJjKQorCQlyZXR1cm4gcmM7CisKKwl4ZW5fcG11X2luaXQoY3B1KTsKKworCXJjID0gSFlQRVJW SVNPUl92Y3B1X29wKFZDUFVPUF91cCwgeGVuX3ZjcHVfbnIoY3B1KSwgTlVMTCk7CisJQlVHX09O KHJjKTsKKworCXdoaWxlIChjcHVfcmVwb3J0X3N0YXRlKGNwdSkgIT0gQ1BVX09OTElORSkKKwkJ SFlQRVJWSVNPUl9zY2hlZF9vcChTQ0hFRE9QX3lpZWxkLCBOVUxMKTsKKworCXJldHVybiAwOwor fQorCitzdGF0aWMgdm9pZCB4ZW5fc21wX2NwdXNfZG9uZSh1bnNpZ25lZCBpbnQgbWF4X2NwdXMp Cit7Cit9CisKKyNpZmRlZiBDT05GSUdfSE9UUExVR19DUFUKK3N0YXRpYyBpbnQgeGVuX2NwdV9k aXNhYmxlKHZvaWQpCit7CisJdW5zaWduZWQgaW50IGNwdSA9IHNtcF9wcm9jZXNzb3JfaWQoKTsK KwlpZiAoY3B1ID09IDApCisJCXJldHVybiAtRUJVU1k7CisKKwljcHVfZGlzYWJsZV9jb21tb24o KTsKKworCWxvYWRfY3IzKHN3YXBwZXJfcGdfZGlyKTsKKwlyZXR1cm4gMDsKK30KKworc3RhdGlj IHZvaWQgeGVuX3B2X2NwdV9kaWUodW5zaWduZWQgaW50IGNwdSkKK3sKKwl3aGlsZSAoSFlQRVJW SVNPUl92Y3B1X29wKFZDUFVPUF9pc191cCwKKwkJCQkgIHhlbl92Y3B1X25yKGNwdSksIE5VTEwp KSB7CisJCV9fc2V0X2N1cnJlbnRfc3RhdGUoVEFTS19VTklOVEVSUlVQVElCTEUpOworCQlzY2hl ZHVsZV90aW1lb3V0KEhaLzEwKTsKKwl9CisKKwlpZiAoY29tbW9uX2NwdV9kaWUoY3B1KSA9PSAw KSB7CisJCXhlbl9zbXBfaW50cl9mcmVlKGNwdSk7CisJCXhlbl91bmluaXRfbG9ja19jcHUoY3B1 KTsKKwkJeGVuX3RlYXJkb3duX3RpbWVyKGNwdSk7CisJCXhlbl9wbXVfZmluaXNoKGNwdSk7CisJ fQorfQorCitzdGF0aWMgdm9pZCB4ZW5fcGxheV9kZWFkKHZvaWQpIC8qIHVzZWQgb25seSB3aXRo IEhPVFBMVUdfQ1BVICovCit7CisJcGxheV9kZWFkX2NvbW1vbigpOworCUhZUEVSVklTT1JfdmNw dV9vcChWQ1BVT1BfZG93biwgeGVuX3ZjcHVfbnIoc21wX3Byb2Nlc3Nvcl9pZCgpKSwgTlVMTCk7 CisJY3B1X2JyaW5ndXAoKTsKKwkvKgorCSAqIGNvbW1pdCA0YjBjMGYyOTQgKHRpY2s6IENsZWFu dXAgTk9IWiBwZXIgY3B1IGRhdGEgb24gY3B1IGRvd24pCisJICogY2xlYXJzIGNlcnRhaW4gZGF0 YSB0aGF0IHRoZSBjcHVfaWRsZSBsb29wICh3aGljaCBjYWxsZWQgdXMKKwkgKiBhbmQgdGhhdCB3 ZSByZXR1cm4gZnJvbSkgZXhwZWN0cy4gVGhlIG9ubHkgd2F5IHRvIGdldCB0aGF0CisJICogZGF0 YSBiYWNrIGlzIHRvIGNhbGw6CisJICovCisJdGlja19ub2h6X2lkbGVfZW50ZXIoKTsKKworCWNw dV9zdGFydHVwX2VudHJ5KENQVUhQX0FQX09OTElORV9JRExFKTsKK30KKworI2Vsc2UgLyogIUNP TkZJR19IT1RQTFVHX0NQVSAqLworc3RhdGljIGludCB4ZW5fY3B1X2Rpc2FibGUodm9pZCkKK3sK KwlyZXR1cm4gLUVOT1NZUzsKK30KKworc3RhdGljIHZvaWQgeGVuX3B2X2NwdV9kaWUodW5zaWdu ZWQgaW50IGNwdSkKK3sKKwlCVUcoKTsKK30KKworc3RhdGljIHZvaWQgeGVuX3BsYXlfZGVhZCh2 b2lkKQoreworCUJVRygpOworfQorCisjZW5kaWYKK3N0YXRpYyB2b2lkIHN0b3Bfc2VsZih2b2lk ICp2KQoreworCWludCBjcHUgPSBzbXBfcHJvY2Vzc29yX2lkKCk7CisKKwkvKiBtYWtlIHN1cmUg d2UncmUgbm90IHBpbm5pbmcgc29tZXRoaW5nIGRvd24gKi8KKwlsb2FkX2NyMyhzd2FwcGVyX3Bn X2Rpcik7CisJLyogc2hvdWxkIHNldCB1cCBhIG1pbmltYWwgZ2R0ICovCisKKwlzZXRfY3B1X29u bGluZShjcHUsIGZhbHNlKTsKKworCUhZUEVSVklTT1JfdmNwdV9vcChWQ1BVT1BfZG93biwgeGVu X3ZjcHVfbnIoY3B1KSwgTlVMTCk7CisJQlVHKCk7Cit9CisKK3N0YXRpYyB2b2lkIHhlbl9zdG9w X290aGVyX2NwdXMoaW50IHdhaXQpCit7CisJc21wX2NhbGxfZnVuY3Rpb24oc3RvcF9zZWxmLCBO VUxMLCB3YWl0KTsKK30KKworc3RhdGljIGlycXJldHVybl90IHhlbl9jYWxsX2Z1bmN0aW9uX2lu dGVycnVwdChpbnQgaXJxLCB2b2lkICpkZXZfaWQpCit7CisJaXJxX2VudGVyKCk7CisJZ2VuZXJp Y19zbXBfY2FsbF9mdW5jdGlvbl9pbnRlcnJ1cHQoKTsKKwlpbmNfaXJxX3N0YXQoaXJxX2NhbGxf Y291bnQpOworCWlycV9leGl0KCk7CisKKwlyZXR1cm4gSVJRX0hBTkRMRUQ7Cit9CisKK3N0YXRp YyBpcnFyZXR1cm5fdCB4ZW5faXJxX3dvcmtfaW50ZXJydXB0KGludCBpcnEsIHZvaWQgKmRldl9p ZCkKK3sKKwlpcnFfZW50ZXIoKTsKKwlpcnFfd29ya19ydW4oKTsKKwlpbmNfaXJxX3N0YXQoYXBp Y19pcnFfd29ya19pcnFzKTsKKwlpcnFfZXhpdCgpOworCisJcmV0dXJuIElSUV9IQU5ETEVEOwor fQorCitzdGF0aWMgY29uc3Qgc3RydWN0IHNtcF9vcHMgeGVuX3NtcF9vcHMgX19pbml0Y29uc3Qg PSB7CisJLnNtcF9wcmVwYXJlX2Jvb3RfY3B1ID0geGVuX3B2X3NtcF9wcmVwYXJlX2Jvb3RfY3B1 LAorCS5zbXBfcHJlcGFyZV9jcHVzID0geGVuX3NtcF9wcmVwYXJlX2NwdXMsCisJLnNtcF9jcHVz X2RvbmUgPSB4ZW5fc21wX2NwdXNfZG9uZSwKKworCS5jcHVfdXAgPSB4ZW5fY3B1X3VwLAorCS5j cHVfZGllID0geGVuX3B2X2NwdV9kaWUsCisJLmNwdV9kaXNhYmxlID0geGVuX2NwdV9kaXNhYmxl LAorCS5wbGF5X2RlYWQgPSB4ZW5fcGxheV9kZWFkLAorCisJLnN0b3Bfb3RoZXJfY3B1cyA9IHhl bl9zdG9wX290aGVyX2NwdXMsCisJLnNtcF9zZW5kX3Jlc2NoZWR1bGUgPSB4ZW5fc21wX3NlbmRf cmVzY2hlZHVsZSwKKworCS5zZW5kX2NhbGxfZnVuY19pcGkgPSB4ZW5fc21wX3NlbmRfY2FsbF9m dW5jdGlvbl9pcGksCisJLnNlbmRfY2FsbF9mdW5jX3NpbmdsZV9pcGkgPSB4ZW5fc21wX3NlbmRf Y2FsbF9mdW5jdGlvbl9zaW5nbGVfaXBpLAorfTsKKwordm9pZCBfX2luaXQgeGVuX3NtcF9pbml0 KHZvaWQpCit7CisJc21wX29wcyA9IHhlbl9zbXBfb3BzOworCXhlbl9maWxsX3Bvc3NpYmxlX21h cCgpOworfQotLSAKMi45LjMKCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fXwpYZW4tZGV2ZWwgbWFpbGluZyBsaXN0Clhlbi1kZXZlbEBsaXN0cy54ZW4ub3Jn Cmh0dHBzOi8vbGlzdHMueGVuLm9yZy94ZW4tZGV2ZWwK