From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753669AbdCNRjX (ORCPT ); Tue, 14 Mar 2017 13:39:23 -0400 Received: from mx1.redhat.com ([209.132.183.28]:42364 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753353AbdCNRgY (ORCPT ); Tue, 14 Mar 2017 13:36:24 -0400 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 v3 11/21] x86/xen: split off smp_pv.c Date: Tue, 14 Mar 2017 18:35:46 +0100 Message-Id: <20170314173556.2249-12-vkuznets@redhat.com> In-Reply-To: <20170314173556.2249-1-vkuznets@redhat.com> References: <20170314173556.2249-1-vkuznets@redhat.com> X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Tue, 14 Mar 2017 17:36:19 +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. Reviewed-by: Juergen Gross Signed-off-by: Vitaly Kuznetsov --- arch/x86/xen/Makefile | 2 +- arch/x86/xen/smp.c | 488 +----------------------------------------------- arch/x86/xen/smp.h | 5 + arch/x86/xen/smp_pv.c | 500 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 509 insertions(+), 486 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 5939592..82ac611 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -1,63 +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 #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. @@ -70,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) { @@ -135,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; @@ -209,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); @@ -697,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 2e8cd56..8ebb6ac 100644 --- a/arch/x86/xen/smp.h +++ b/arch/x86/xen/smp.h @@ -17,6 +17,11 @@ void xen_smp_intr_free_pv(unsigned int cpu); void xen_smp_send_reschedule(int cpu); void xen_smp_send_call_function_ipi(const struct cpumask *mask); 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..3a61e0e --- /dev/null +++ b/arch/x86/xen/smp_pv.c @@ -0,0 +1,500 @@ +/* + * 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 "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 v3 11/21] x86/xen: split off smp_pv.c Date: Tue, 14 Mar 2017 18:35:46 +0100 Message-ID: <20170314173556.2249-12-vkuznets@redhat.com> References: <20170314173556.2249-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 1cnqMw-0001Fl-6f for xen-devel@lists.xenproject.org; Tue, 14 Mar 2017 17:36:22 +0000 In-Reply-To: <20170314173556.2249-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 IGVuZGVkIHVwIGluIHNtcC5oLgoKUmV2aWV3ZWQtYnk6IEp1ZXJnZW4gR3Jvc3MgPGpncm9zc0Bz dXNlLmNvbT4KU2lnbmVkLW9mZi1ieTogVml0YWx5IEt1em5ldHNvdiA8dmt1em5ldHNAcmVkaGF0 LmNvbT4KLS0tCiBhcmNoL3g4Ni94ZW4vTWFrZWZpbGUgfCAgIDIgKy0KIGFyY2gveDg2L3hlbi9z bXAuYyAgICB8IDQ4OCArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0KIGFyY2gveDg2L3hlbi9zbXAuaCAgICB8ICAgNSArCiBhcmNoL3g4Ni94ZW4vc21wX3B2 LmMgfCA1MDAgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr KysKIDQgZmlsZXMgY2hhbmdlZCwgNTA5IGluc2VydGlvbnMoKyksIDQ4NiBkZWxldGlvbnMoLSkK IGNyZWF0ZSBtb2RlIDEwMDY0NCBhcmNoL3g4Ni94ZW4vc21wX3B2LmMKCmRpZmYgLS1naXQgYS9h cmNoL3g4Ni94ZW4vTWFrZWZpbGUgYi9hcmNoL3g4Ni94ZW4vTWFrZWZpbGUKaW5kZXggYmM3ZGY4 Yy4uZWJmMzUyMiAxMDA2NDQKLS0tIGEvYXJjaC94ODYveGVuL01ha2VmaWxlCisrKyBiL2FyY2gv eDg2L3hlbi9NYWtlZmlsZQpAQCAtMjAsNyArMjAsNyBAQCBvYmotJChDT05GSUdfWEVOX1BWSCkJ CQkrPSBlbmxpZ2h0ZW5fcHZoLm8KIAogb2JqLSQoQ09ORklHX0VWRU5UX1RSQUNJTkcpICs9IHRy YWNlLm8KIAotb2JqLSQoQ09ORklHX1NNUCkJCSs9IHNtcC5vCitvYmotJChDT05GSUdfU01QKQkJ Kz0gc21wLm8gc21wX3B2Lm8KIG9iai0kKENPTkZJR19YRU5fUFZIVk1fU01QKSAgCSs9IHNtcF9o dm0ubwogb2JqLSQoQ09ORklHX1BBUkFWSVJUX1NQSU5MT0NLUykrPSBzcGlubG9jay5vCiBvYmot JChDT05GSUdfWEVOX0RFQlVHX0ZTKQkrPSBkZWJ1Z2ZzLm8KZGlmZiAtLWdpdCBhL2FyY2gveDg2 L3hlbi9zbXAuYyBiL2FyY2gveDg2L3hlbi9zbXAuYwppbmRleCA1OTM5NTkyLi44MmFjNjExIDEw MDY0NAotLS0gYS9hcmNoL3g4Ni94ZW4vc21wLmMKKysrIGIvYXJjaC94ODYveGVuL3NtcC5jCkBA IC0xLDYzICsxLDIxIEBACi0vKgotICogWGVuIFNNUCBzdXBwb3J0Ci0gKgotICogVGhpcyBmaWxl IGltcGxlbWVudHMgdGhlIFhlbiB2ZXJzaW9ucyBvZiBzbXBfb3BzLiAgU01QIHVuZGVyIFhlbiBp cwotICogdmVyeSBzdHJhaWdodGZvcndhcmQuICBCcmluZ2luZyBhIENQVSB1cCBpcyBzaW1wbHkg YSBtYXR0ZXIgb2YKLSAqIGxvYWRpbmcgaXRzIGluaXRpYWwgY29udGV4dCBhbmQgc2V0dGluZyBp dCBydW5uaW5nLgotICoKLSAqIElQSXMgYXJlIGhhbmRsZWQgdGhyb3VnaCB0aGUgWGVuIGV2ZW50 IG1lY2hhbmlzbS4KLSAqCi0gKiBCZWNhdXNlIHZpcnR1YWwgQ1BVcyBjYW4gYmUgc2NoZWR1bGVk IG9udG8gYW55IHJlYWwgQ1BVLCB0aGVyZSdzIG5vCi0gKiB1c2VmdWwgdG9wb2xvZ3kgaW5mb3Jt YXRpb24gZm9yIHRoZSBrZXJuZWwgdG8gbWFrZSB1c2Ugb2YuICBBcyBhCi0gKiByZXN1bHQsIGFs bCBDUFVzIGFyZSB0cmVhdGVkIGFzIGlmIHRoZXkncmUgc2luZ2xlLWNvcmUgYW5kCi0gKiBzaW5n bGUtdGhyZWFkZWQuCi0gKi8KLSNpbmNsdWRlIDxsaW51eC9zY2hlZC5oPgotI2luY2x1ZGUgPGxp bnV4L2Vyci5oPgotI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KICNpbmNsdWRlIDxsaW51eC9zbXAu aD4KLSNpbmNsdWRlIDxsaW51eC9pcnFfd29yay5oPgotI2luY2x1ZGUgPGxpbnV4L3RpY2suaD4K LSNpbmNsdWRlIDxsaW51eC9ubWkuaD4KLQotI2luY2x1ZGUgPGFzbS9wYXJhdmlydC5oPgotI2lu Y2x1ZGUgPGFzbS9kZXNjLmg+Ci0jaW5jbHVkZSA8YXNtL3BndGFibGUuaD4KLSNpbmNsdWRlIDxh c20vY3B1Lmg+Ci0KLSNpbmNsdWRlIDx4ZW4vaW50ZXJmYWNlL3hlbi5oPgotI2luY2x1ZGUgPHhl bi9pbnRlcmZhY2UvdmNwdS5oPgotI2luY2x1ZGUgPHhlbi9pbnRlcmZhY2UveGVucG11Lmg+Ci0K LSNpbmNsdWRlIDxhc20veGVuL2ludGVyZmFjZS5oPgotI2luY2x1ZGUgPGFzbS94ZW4vaHlwZXJj YWxsLmg+CisjaW5jbHVkZSA8bGludXgvc2xhYi5oPgorI2luY2x1ZGUgPGxpbnV4L2NwdW1hc2su aD4KKyNpbmNsdWRlIDxsaW51eC9wZXJjcHUuaD4KIAotI2luY2x1ZGUgPHhlbi94ZW4uaD4KLSNp bmNsdWRlIDx4ZW4vcGFnZS5oPgogI2luY2x1ZGUgPHhlbi9ldmVudHMuaD4KIAogI2luY2x1ZGUg PHhlbi9odmMtY29uc29sZS5oPgogI2luY2x1ZGUgInhlbi1vcHMuaCIKLSNpbmNsdWRlICJtbXUu aCIKICNpbmNsdWRlICJzbXAuaCIKLSNpbmNsdWRlICJwbXUuaCIKLQotY3B1bWFza192YXJfdCB4 ZW5fY3B1X2luaXRpYWxpemVkX21hcDsKIAotc3RydWN0IHhlbl9jb21tb25faXJxIHsKLQlpbnQg aXJxOwotCWNoYXIgKm5hbWU7Ci19Owogc3RhdGljIERFRklORV9QRVJfQ1BVKHN0cnVjdCB4ZW5f Y29tbW9uX2lycSwgeGVuX3Jlc2NoZWRfaXJxKSA9IHsgLmlycSA9IC0xIH07CiBzdGF0aWMgREVG SU5FX1BFUl9DUFUoc3RydWN0IHhlbl9jb21tb25faXJxLCB4ZW5fY2FsbGZ1bmNfaXJxKSA9IHsg LmlycSA9IC0xIH07CiBzdGF0aWMgREVGSU5FX1BFUl9DUFUoc3RydWN0IHhlbl9jb21tb25faXJx LCB4ZW5fY2FsbGZ1bmNzaW5nbGVfaXJxKSA9IHsgLmlycSA9IC0xIH07Ci1zdGF0aWMgREVGSU5F X1BFUl9DUFUoc3RydWN0IHhlbl9jb21tb25faXJxLCB4ZW5faXJxX3dvcmspID0geyAuaXJxID0g LTEgfTsKIHN0YXRpYyBERUZJTkVfUEVSX0NQVShzdHJ1Y3QgeGVuX2NvbW1vbl9pcnEsIHhlbl9k ZWJ1Z19pcnEpID0geyAuaXJxID0gLTEgfTsKLXN0YXRpYyBERUZJTkVfUEVSX0NQVShzdHJ1Y3Qg eGVuX2NvbW1vbl9pcnEsIHhlbl9wbXVfaXJxKSA9IHsgLmlycSA9IC0xIH07CiAKIHN0YXRpYyBp cnFyZXR1cm5fdCB4ZW5fY2FsbF9mdW5jdGlvbl9pbnRlcnJ1cHQoaW50IGlycSwgdm9pZCAqZGV2 X2lkKTsKIHN0YXRpYyBpcnFyZXR1cm5fdCB4ZW5fY2FsbF9mdW5jdGlvbl9zaW5nbGVfaW50ZXJy dXB0KGludCBpcnEsIHZvaWQgKmRldl9pZCk7Ci1zdGF0aWMgaXJxcmV0dXJuX3QgeGVuX2lycV93 b3JrX2ludGVycnVwdChpbnQgaXJxLCB2b2lkICpkZXZfaWQpOwogCiAvKgogICogUmVzY2hlZHVs ZSBjYWxsIGJhY2suCkBAIC03MCw0MiArMjgsNiBAQCBzdGF0aWMgaXJxcmV0dXJuX3QgeGVuX3Jl c2NoZWR1bGVfaW50ZXJydXB0KGludCBpcnEsIHZvaWQgKmRldl9pZCkKIAlyZXR1cm4gSVJRX0hB TkRMRUQ7CiB9CiAKLXN0YXRpYyB2b2lkIGNwdV9icmluZ3VwKHZvaWQpCi17Ci0JaW50IGNwdTsK LQotCWNwdV9pbml0KCk7Ci0JdG91Y2hfc29mdGxvY2t1cF93YXRjaGRvZygpOwotCXByZWVtcHRf ZGlzYWJsZSgpOwotCi0JLyogUFZIIHJ1bnMgaW4gcmluZyAwIGFuZCBhbGxvd3MgdXMgdG8gZG8g bmF0aXZlIHN5c2NhbGxzLiBZYXkhICovCi0JaWYgKCF4ZW5fZmVhdHVyZShYRU5GRUFUX3N1cGVy dmlzb3JfbW9kZV9rZXJuZWwpKSB7Ci0JCXhlbl9lbmFibGVfc3lzZW50ZXIoKTsKLQkJeGVuX2Vu YWJsZV9zeXNjYWxsKCk7Ci0JfQotCWNwdSA9IHNtcF9wcm9jZXNzb3JfaWQoKTsKLQlzbXBfc3Rv cmVfY3B1X2luZm8oY3B1KTsKLQljcHVfZGF0YShjcHUpLng4Nl9tYXhfY29yZXMgPSAxOwotCXNl dF9jcHVfc2libGluZ19tYXAoY3B1KTsKLQotCXhlbl9zZXR1cF9jcHVfY2xvY2tldmVudHMoKTsK LQotCW5vdGlmeV9jcHVfc3RhcnRpbmcoY3B1KTsKLQotCXNldF9jcHVfb25saW5lKGNwdSwgdHJ1 ZSk7Ci0KLQljcHVfc2V0X3N0YXRlX29ubGluZShjcHUpOyAgLyogSW1wbGllcyBmdWxsIG1lbW9y eSBiYXJyaWVyLiAqLwotCi0JLyogV2UgY2FuIHRha2UgaW50ZXJydXB0cyBub3c6IHdlJ3JlIG9m ZmljaWFsbHkgInVwIi4gKi8KLQlsb2NhbF9pcnFfZW5hYmxlKCk7Ci19Ci0KLWFzbWxpbmthZ2Ug X192aXNpYmxlIHZvaWQgY3B1X2JyaW5ndXBfYW5kX2lkbGUodm9pZCkKLXsKLQljcHVfYnJpbmd1 cCgpOwotCWNwdV9zdGFydHVwX2VudHJ5KENQVUhQX0FQX09OTElORV9JRExFKTsKLX0KLQogdm9p ZCB4ZW5fc21wX2ludHJfZnJlZSh1bnNpZ25lZCBpbnQgY3B1KQogewogCWlmIChwZXJfY3B1KHhl bl9yZXNjaGVkX2lycSwgY3B1KS5pcnEgPj0gMCkgewpAQCAtMTM1LDIzICs1Nyw2IEBAIHZvaWQg eGVuX3NtcF9pbnRyX2ZyZWUodW5zaWduZWQgaW50IGNwdSkKIAl9CiB9CiAKLXZvaWQgeGVuX3Nt cF9pbnRyX2ZyZWVfcHYodW5zaWduZWQgaW50IGNwdSkKLXsKLQlpZiAocGVyX2NwdSh4ZW5faXJx X3dvcmssIGNwdSkuaXJxID49IDApIHsKLQkJdW5iaW5kX2Zyb21faXJxaGFuZGxlcihwZXJfY3B1 KHhlbl9pcnFfd29yaywgY3B1KS5pcnEsIE5VTEwpOwotCQlwZXJfY3B1KHhlbl9pcnFfd29yaywg Y3B1KS5pcnEgPSAtMTsKLQkJa2ZyZWUocGVyX2NwdSh4ZW5faXJxX3dvcmssIGNwdSkubmFtZSk7 Ci0JCXBlcl9jcHUoeGVuX2lycV93b3JrLCBjcHUpLm5hbWUgPSBOVUxMOwotCX0KLQotCWlmIChw ZXJfY3B1KHhlbl9wbXVfaXJxLCBjcHUpLmlycSA+PSAwKSB7Ci0JCXVuYmluZF9mcm9tX2lycWhh bmRsZXIocGVyX2NwdSh4ZW5fcG11X2lycSwgY3B1KS5pcnEsIE5VTEwpOwotCQlwZXJfY3B1KHhl bl9wbXVfaXJxLCBjcHUpLmlycSA9IC0xOwotCQlrZnJlZShwZXJfY3B1KHhlbl9wbXVfaXJxLCBj cHUpLm5hbWUpOwotCQlwZXJfY3B1KHhlbl9wbXVfaXJxLCBjcHUpLm5hbWUgPSBOVUxMOwotCX0K LX0KLQogaW50IHhlbl9zbXBfaW50cl9pbml0KHVuc2lnbmVkIGludCBjcHUpCiB7CiAJaW50IHJj OwpAQCAtMjA5LDM2MCArMTE0LDYgQEAgaW50IHhlbl9zbXBfaW50cl9pbml0KHVuc2lnbmVkIGlu dCBjcHUpCiAJcmV0dXJuIHJjOwogfQogCi1pbnQgeGVuX3NtcF9pbnRyX2luaXRfcHYodW5zaWdu ZWQgaW50IGNwdSkKLXsKLQlpbnQgcmM7Ci0JY2hhciAqY2FsbGZ1bmNfbmFtZSwgKnBtdV9uYW1l OwotCi0JY2FsbGZ1bmNfbmFtZSA9IGthc3ByaW50ZihHRlBfS0VSTkVMLCAiaXJxd29yayVkIiwg Y3B1KTsKLQlyYyA9IGJpbmRfaXBpX3RvX2lycWhhbmRsZXIoWEVOX0lSUV9XT1JLX1ZFQ1RPUiwK LQkJCQkgICAgY3B1LAotCQkJCSAgICB4ZW5faXJxX3dvcmtfaW50ZXJydXB0LAotCQkJCSAgICBJ UlFGX1BFUkNQVXxJUlFGX05PQkFMQU5DSU5HLAotCQkJCSAgICBjYWxsZnVuY19uYW1lLAotCQkJ CSAgICBOVUxMKTsKLQlpZiAocmMgPCAwKQotCQlnb3RvIGZhaWw7Ci0JcGVyX2NwdSh4ZW5faXJx X3dvcmssIGNwdSkuaXJxID0gcmM7Ci0JcGVyX2NwdSh4ZW5faXJxX3dvcmssIGNwdSkubmFtZSA9 IGNhbGxmdW5jX25hbWU7Ci0KLQlpZiAoaXNfeGVuX3BtdShjcHUpKSB7Ci0JCXBtdV9uYW1lID0g a2FzcHJpbnRmKEdGUF9LRVJORUwsICJwbXUlZCIsIGNwdSk7Ci0JCXJjID0gYmluZF92aXJxX3Rv X2lycWhhbmRsZXIoVklSUV9YRU5QTVUsIGNwdSwKLQkJCQkJICAgICB4ZW5fcG11X2lycV9oYW5k bGVyLAotCQkJCQkgICAgIElSUUZfUEVSQ1BVfElSUUZfTk9CQUxBTkNJTkcsCi0JCQkJCSAgICAg cG11X25hbWUsIE5VTEwpOwotCQlpZiAocmMgPCAwKQotCQkJZ290byBmYWlsOwotCQlwZXJfY3B1 KHhlbl9wbXVfaXJxLCBjcHUpLmlycSA9IHJjOwotCQlwZXJfY3B1KHhlbl9wbXVfaXJxLCBjcHUp Lm5hbWUgPSBwbXVfbmFtZTsKLQl9Ci0KLQlyZXR1cm4gMDsKLQotIGZhaWw6Ci0JeGVuX3NtcF9p bnRyX2ZyZWVfcHYoY3B1KTsKLQlyZXR1cm4gcmM7Ci19Ci0KLXN0YXRpYyB2b2lkIF9faW5pdCB4 ZW5fZmlsbF9wb3NzaWJsZV9tYXAodm9pZCkKLXsKLQlpbnQgaSwgcmM7Ci0KLQlpZiAoeGVuX2lu aXRpYWxfZG9tYWluKCkpCi0JCXJldHVybjsKLQotCWZvciAoaSA9IDA7IGkgPCBucl9jcHVfaWRz OyBpKyspIHsKLQkJcmMgPSBIWVBFUlZJU09SX3ZjcHVfb3AoVkNQVU9QX2lzX3VwLCBpLCBOVUxM KTsKLQkJaWYgKHJjID49IDApIHsKLQkJCW51bV9wcm9jZXNzb3JzKys7Ci0JCQlzZXRfY3B1X3Bv c3NpYmxlKGksIHRydWUpOwotCQl9Ci0JfQotfQotCi1zdGF0aWMgdm9pZCBfX2luaXQgeGVuX2Zp bHRlcl9jcHVfbWFwcyh2b2lkKQotewotCWludCBpLCByYzsKLQl1bnNpZ25lZCBpbnQgc3VidHJh Y3QgPSAwOwotCi0JaWYgKCF4ZW5faW5pdGlhbF9kb21haW4oKSkKLQkJcmV0dXJuOwotCi0JbnVt X3Byb2Nlc3NvcnMgPSAwOwotCWRpc2FibGVkX2NwdXMgPSAwOwotCWZvciAoaSA9IDA7IGkgPCBu cl9jcHVfaWRzOyBpKyspIHsKLQkJcmMgPSBIWVBFUlZJU09SX3ZjcHVfb3AoVkNQVU9QX2lzX3Vw LCBpLCBOVUxMKTsKLQkJaWYgKHJjID49IDApIHsKLQkJCW51bV9wcm9jZXNzb3JzKys7Ci0JCQlz ZXRfY3B1X3Bvc3NpYmxlKGksIHRydWUpOwotCQl9IGVsc2UgewotCQkJc2V0X2NwdV9wb3NzaWJs ZShpLCBmYWxzZSk7Ci0JCQlzZXRfY3B1X3ByZXNlbnQoaSwgZmFsc2UpOwotCQkJc3VidHJhY3Qr KzsKLQkJfQotCX0KLSNpZmRlZiBDT05GSUdfSE9UUExVR19DUFUKLQkvKiBUaGlzIGlzIGFraW4g dG8gdXNpbmcgJ25yX2NwdXMnIG9uIHRoZSBMaW51eCBjb21tYW5kIGxpbmUuCi0JICogV2hpY2gg aXMgT0sgYXMgd2hlbiB3ZSB1c2UgJ2RvbTBfbWF4X3ZjcHVzPVgnIHdlIGNhbiBvbmx5Ci0JICog aGF2ZSB1cCB0byBYLCB3aGlsZSBucl9jcHVfaWRzIGlzIGdyZWF0ZXIgdGhhbiBYLiBUaGlzCi0J ICogbm9ybWFsbHkgaXMgbm90IGEgcHJvYmxlbSwgZXhjZXB0IHdoZW4gQ1BVIGhvdHBsdWdnaW5n Ci0JICogaXMgaW52b2x2ZWQgYW5kIHRoZW4gdGhlcmUgbWlnaHQgYmUgbW9yZSB0aGFuIFggQ1BV cwotCSAqIGluIHRoZSBndWVzdCAtIHdoaWNoIHdpbGwgbm90IHdvcmsgYXMgdGhlcmUgaXMgbm8K LQkgKiBoeXBlcmNhbGwgdG8gZXhwYW5kIHRoZSBtYXggbnVtYmVyIG9mIFZDUFVzIGFuIGFscmVh ZHkKLQkgKiBydW5uaW5nIGd1ZXN0IGhhcy4gU28gY2FwIGl0IHVwIHRvIFguICovCi0JaWYgKHN1 YnRyYWN0KQotCQlucl9jcHVfaWRzID0gbnJfY3B1X2lkcyAtIHN1YnRyYWN0OwotI2VuZGlmCi0K LX0KLQotc3RhdGljIHZvaWQgX19pbml0IHhlbl9wdl9zbXBfcHJlcGFyZV9ib290X2NwdSh2b2lk KQotewotCUJVR19PTihzbXBfcHJvY2Vzc29yX2lkKCkgIT0gMCk7Ci0JbmF0aXZlX3NtcF9wcmVw YXJlX2Jvb3RfY3B1KCk7Ci0KLQlpZiAoIXhlbl9mZWF0dXJlKFhFTkZFQVRfd3JpdGFibGVfcGFn ZV90YWJsZXMpKQotCQkvKiBXZSd2ZSBzd2l0Y2hlZCB0byB0aGUgInJlYWwiIHBlci1jcHUgZ2R0 LCBzbyBtYWtlCi0JCSAqIHN1cmUgdGhlIG9sZCBtZW1vcnkgY2FuIGJlIHJlY3ljbGVkLiAqLwot CQltYWtlX2xvd21lbV9wYWdlX3JlYWR3cml0ZSh4ZW5faW5pdGlhbF9nZHQpOwotCi0jaWZkZWYg Q09ORklHX1g4Nl8zMgotCS8qCi0JICogWGVuIHN0YXJ0cyB1cyB3aXRoIFhFTl9GTEFUX1JJTkcx X0RTLCBidXQgbGludXggY29kZQotCSAqIGV4cGVjdHMgX19VU0VSX0RTCi0JICovCi0JbG9hZHNl Z21lbnQoZHMsIF9fVVNFUl9EUyk7Ci0JbG9hZHNlZ21lbnQoZXMsIF9fVVNFUl9EUyk7Ci0jZW5k aWYKLQotCXhlbl9maWx0ZXJfY3B1X21hcHMoKTsKLQl4ZW5fc2V0dXBfdmNwdV9pbmZvX3BsYWNl bWVudCgpOwotCi0JLyoKLQkgKiBUaGUgYWx0ZXJuYXRpdmUgbG9naWMgKHdoaWNoIHBhdGNoZXMg dGhlIHVubG9jay9sb2NrKSBydW5zIGJlZm9yZQotCSAqIHRoZSBzbXAgYm9vdHVwIHVwIGNvZGUg aXMgYWN0aXZhdGVkLiBIZW5jZSB3ZSBuZWVkIHRvIHNldCB0aGlzIHVwCi0JICogdGhlIGNvcmUg a2VybmVsIGlzIGJlaW5nIHBhdGNoZWQuIE90aGVyd2lzZSB3ZSB3aWxsIGhhdmUgb25seQotCSAq IG1vZHVsZXMgcGF0Y2hlZCBidXQgbm90IGNvcmUgY29kZS4KLQkgKi8KLQl4ZW5faW5pdF9zcGlu bG9ja3MoKTsKLX0KLQotc3RhdGljIHZvaWQgX19pbml0IHhlbl9zbXBfcHJlcGFyZV9jcHVzKHVu c2lnbmVkIGludCBtYXhfY3B1cykKLXsKLQl1bnNpZ25lZCBjcHU7Ci0JdW5zaWduZWQgaW50IGk7 Ci0KLQlpZiAoc2tpcF9pb2FwaWNfc2V0dXApIHsKLQkJY2hhciAqbSA9IChtYXhfY3B1cyA9PSAw KSA/Ci0JCQkiVGhlIG5vc21wIHBhcmFtZXRlciBpcyBpbmNvbXBhdGlibGUgd2l0aCBYZW47ICIg XAotCQkJInVzZSBYZW4gZG9tMF9tYXhfdmNwdXM9MSBwYXJhbWV0ZXIiIDoKLQkJCSJUaGUgbm9h cGljIHBhcmFtZXRlciBpcyBpbmNvbXBhdGlibGUgd2l0aCBYZW4iOwotCi0JCXhlbl9yYXdfcHJp bnRrKG0pOwotCQlwYW5pYyhtKTsKLQl9Ci0JeGVuX2luaXRfbG9ja19jcHUoMCk7Ci0KLQlzbXBf c3RvcmVfYm9vdF9jcHVfaW5mbygpOwotCWNwdV9kYXRhKDApLng4Nl9tYXhfY29yZXMgPSAxOwot Ci0JZm9yX2VhY2hfcG9zc2libGVfY3B1KGkpIHsKLQkJemFsbG9jX2NwdW1hc2tfdmFyKCZwZXJf Y3B1KGNwdV9zaWJsaW5nX21hcCwgaSksIEdGUF9LRVJORUwpOwotCQl6YWxsb2NfY3B1bWFza192 YXIoJnBlcl9jcHUoY3B1X2NvcmVfbWFwLCBpKSwgR0ZQX0tFUk5FTCk7Ci0JCXphbGxvY19jcHVt YXNrX3ZhcigmcGVyX2NwdShjcHVfbGxjX3NoYXJlZF9tYXAsIGkpLCBHRlBfS0VSTkVMKTsKLQl9 Ci0Jc2V0X2NwdV9zaWJsaW5nX21hcCgwKTsKLQotCXhlbl9wbXVfaW5pdCgwKTsKLQotCWlmICh4 ZW5fc21wX2ludHJfaW5pdCgwKSkKLQkJQlVHKCk7Ci0KLQlpZiAoIWFsbG9jX2NwdW1hc2tfdmFy KCZ4ZW5fY3B1X2luaXRpYWxpemVkX21hcCwgR0ZQX0tFUk5FTCkpCi0JCXBhbmljKCJjb3VsZCBu b3QgYWxsb2NhdGUgeGVuX2NwdV9pbml0aWFsaXplZF9tYXBcbiIpOwotCi0JY3B1bWFza19jb3B5 KHhlbl9jcHVfaW5pdGlhbGl6ZWRfbWFwLCBjcHVtYXNrX29mKDApKTsKLQotCS8qIFJlc3RyaWN0 IHRoZSBwb3NzaWJsZV9tYXAgYWNjb3JkaW5nIHRvIG1heF9jcHVzLiAqLwotCXdoaWxlICgobnVt X3Bvc3NpYmxlX2NwdXMoKSA+IDEpICYmIChudW1fcG9zc2libGVfY3B1cygpID4gbWF4X2NwdXMp KSB7Ci0JCWZvciAoY3B1ID0gbnJfY3B1X2lkcyAtIDE7ICFjcHVfcG9zc2libGUoY3B1KTsgY3B1 LS0pCi0JCQljb250aW51ZTsKLQkJc2V0X2NwdV9wb3NzaWJsZShjcHUsIGZhbHNlKTsKLQl9Ci0K LQlmb3JfZWFjaF9wb3NzaWJsZV9jcHUoY3B1KQotCQlzZXRfY3B1X3ByZXNlbnQoY3B1LCB0cnVl KTsKLX0KLQotc3RhdGljIGludAotY3B1X2luaXRpYWxpemVfY29udGV4dCh1bnNpZ25lZCBpbnQg Y3B1LCBzdHJ1Y3QgdGFza19zdHJ1Y3QgKmlkbGUpCi17Ci0Jc3RydWN0IHZjcHVfZ3Vlc3RfY29u dGV4dCAqY3R4dDsKLQlzdHJ1Y3QgZGVzY19zdHJ1Y3QgKmdkdDsKLQl1bnNpZ25lZCBsb25nIGdk dF9tZm47Ci0KLQkvKiB1c2VkIHRvIHRlbGwgY3B1X2luaXQoKSB0aGF0IGl0IGNhbiBwcm9jZWVk IHdpdGggaW5pdGlhbGl6YXRpb24gKi8KLQljcHVtYXNrX3NldF9jcHUoY3B1LCBjcHVfY2FsbG91 dF9tYXNrKTsKLQlpZiAoY3B1bWFza190ZXN0X2FuZF9zZXRfY3B1KGNwdSwgeGVuX2NwdV9pbml0 aWFsaXplZF9tYXApKQotCQlyZXR1cm4gMDsKLQotCWN0eHQgPSBremFsbG9jKHNpemVvZigqY3R4 dCksIEdGUF9LRVJORUwpOwotCWlmIChjdHh0ID09IE5VTEwpCi0JCXJldHVybiAtRU5PTUVNOwot Ci0JZ2R0ID0gZ2V0X2NwdV9nZHRfdGFibGUoY3B1KTsKLQotI2lmZGVmIENPTkZJR19YODZfMzIK LQljdHh0LT51c2VyX3JlZ3MuZnMgPSBfX0tFUk5FTF9QRVJDUFU7Ci0JY3R4dC0+dXNlcl9yZWdz LmdzID0gX19LRVJORUxfU1RBQ0tfQ0FOQVJZOwotI2VuZGlmCi0JbWVtc2V0KCZjdHh0LT5mcHVf Y3R4dCwgMCwgc2l6ZW9mKGN0eHQtPmZwdV9jdHh0KSk7Ci0KLQljdHh0LT51c2VyX3JlZ3MuZWlw ID0gKHVuc2lnbmVkIGxvbmcpY3B1X2JyaW5ndXBfYW5kX2lkbGU7Ci0JY3R4dC0+ZmxhZ3MgPSBW R0NGX0lOX0tFUk5FTDsKLQljdHh0LT51c2VyX3JlZ3MuZWZsYWdzID0gMHgxMDAwOyAvKiBJT1BM X1JJTkcxICovCi0JY3R4dC0+dXNlcl9yZWdzLmRzID0gX19VU0VSX0RTOwotCWN0eHQtPnVzZXJf cmVncy5lcyA9IF9fVVNFUl9EUzsKLQljdHh0LT51c2VyX3JlZ3Muc3MgPSBfX0tFUk5FTF9EUzsK LQotCXhlbl9jb3B5X3RyYXBfaW5mbyhjdHh0LT50cmFwX2N0eHQpOwotCi0JY3R4dC0+bGR0X2Vu dHMgPSAwOwotCi0JQlVHX09OKCh1bnNpZ25lZCBsb25nKWdkdCAmIH5QQUdFX01BU0spOwotCi0J Z2R0X21mbiA9IGFyYml0cmFyeV92aXJ0X3RvX21mbihnZHQpOwotCW1ha2VfbG93bWVtX3BhZ2Vf cmVhZG9ubHkoZ2R0KTsKLQltYWtlX2xvd21lbV9wYWdlX3JlYWRvbmx5KG1mbl90b192aXJ0KGdk dF9tZm4pKTsKLQotCWN0eHQtPmdkdF9mcmFtZXNbMF0gPSBnZHRfbWZuOwotCWN0eHQtPmdkdF9l bnRzICAgICAgPSBHRFRfRU5UUklFUzsKLQotCWN0eHQtPmtlcm5lbF9zcyA9IF9fS0VSTkVMX0RT OwotCWN0eHQtPmtlcm5lbF9zcCA9IGlkbGUtPnRocmVhZC5zcDA7Ci0KLSNpZmRlZiBDT05GSUdf WDg2XzMyCi0JY3R4dC0+ZXZlbnRfY2FsbGJhY2tfY3MgICAgID0gX19LRVJORUxfQ1M7Ci0JY3R4 dC0+ZmFpbHNhZmVfY2FsbGJhY2tfY3MgID0gX19LRVJORUxfQ1M7Ci0jZWxzZQotCWN0eHQtPmdz X2Jhc2Vfa2VybmVsID0gcGVyX2NwdV9vZmZzZXQoY3B1KTsKLSNlbmRpZgotCWN0eHQtPmV2ZW50 X2NhbGxiYWNrX2VpcCAgICA9Ci0JCSh1bnNpZ25lZCBsb25nKXhlbl9oeXBlcnZpc29yX2NhbGxi YWNrOwotCWN0eHQtPmZhaWxzYWZlX2NhbGxiYWNrX2VpcCA9Ci0JCSh1bnNpZ25lZCBsb25nKXhl bl9mYWlsc2FmZV9jYWxsYmFjazsKLQljdHh0LT51c2VyX3JlZ3MuY3MgPSBfX0tFUk5FTF9DUzsK LQlwZXJfY3B1KHhlbl9jcjMsIGNwdSkgPSBfX3BhKHN3YXBwZXJfcGdfZGlyKTsKLQotCWN0eHQt PnVzZXJfcmVncy5lc3AgPSBpZGxlLT50aHJlYWQuc3AwIC0gc2l6ZW9mKHN0cnVjdCBwdF9yZWdz KTsKLQljdHh0LT5jdHJscmVnWzNdID0geGVuX3Bmbl90b19jcjModmlydF90b19nZm4oc3dhcHBl cl9wZ19kaXIpKTsKLQlpZiAoSFlQRVJWSVNPUl92Y3B1X29wKFZDUFVPUF9pbml0aWFsaXNlLCB4 ZW5fdmNwdV9ucihjcHUpLCBjdHh0KSkKLQkJQlVHKCk7Ci0KLQlrZnJlZShjdHh0KTsKLQlyZXR1 cm4gMDsKLX0KLQotc3RhdGljIGludCB4ZW5fY3B1X3VwKHVuc2lnbmVkIGludCBjcHUsIHN0cnVj dCB0YXNrX3N0cnVjdCAqaWRsZSkKLXsKLQlpbnQgcmM7Ci0KLQljb21tb25fY3B1X3VwKGNwdSwg aWRsZSk7Ci0KLQl4ZW5fc2V0dXBfcnVuc3RhdGVfaW5mbyhjcHUpOwotCi0JLyoKLQkgKiBQViBW Q1BVcyBhcmUgYWx3YXlzIHN1Y2Nlc3NmdWxseSB0YWtlbiBkb3duIChzZWUgJ3doaWxlJyBsb29w Ci0JICogaW4geGVuX2NwdV9kaWUoKSksIHNvIC1FQlVTWSBpcyBhbiBlcnJvci4KLQkgKi8KLQly YyA9IGNwdV9jaGVja191cF9wcmVwYXJlKGNwdSk7Ci0JaWYgKHJjKQotCQlyZXR1cm4gcmM7Ci0K LQkvKiBtYWtlIHN1cmUgaW50ZXJydXB0cyBzdGFydCBibG9ja2VkICovCi0JcGVyX2NwdSh4ZW5f dmNwdSwgY3B1KS0+ZXZ0Y2huX3VwY2FsbF9tYXNrID0gMTsKLQotCXJjID0gY3B1X2luaXRpYWxp emVfY29udGV4dChjcHUsIGlkbGUpOwotCWlmIChyYykKLQkJcmV0dXJuIHJjOwotCi0JeGVuX3Bt dV9pbml0KGNwdSk7Ci0KLQlyYyA9IEhZUEVSVklTT1JfdmNwdV9vcChWQ1BVT1BfdXAsIHhlbl92 Y3B1X25yKGNwdSksIE5VTEwpOwotCUJVR19PTihyYyk7Ci0KLQl3aGlsZSAoY3B1X3JlcG9ydF9z dGF0ZShjcHUpICE9IENQVV9PTkxJTkUpCi0JCUhZUEVSVklTT1Jfc2NoZWRfb3AoU0NIRURPUF95 aWVsZCwgTlVMTCk7Ci0KLQlyZXR1cm4gMDsKLX0KLQotc3RhdGljIHZvaWQgeGVuX3NtcF9jcHVz X2RvbmUodW5zaWduZWQgaW50IG1heF9jcHVzKQotewotfQotCi0jaWZkZWYgQ09ORklHX0hPVFBM VUdfQ1BVCi1zdGF0aWMgaW50IHhlbl9jcHVfZGlzYWJsZSh2b2lkKQotewotCXVuc2lnbmVkIGlu dCBjcHUgPSBzbXBfcHJvY2Vzc29yX2lkKCk7Ci0JaWYgKGNwdSA9PSAwKQotCQlyZXR1cm4gLUVC VVNZOwotCi0JY3B1X2Rpc2FibGVfY29tbW9uKCk7Ci0KLQlsb2FkX2NyMyhzd2FwcGVyX3BnX2Rp cik7Ci0JcmV0dXJuIDA7Ci19Ci0KLXN0YXRpYyB2b2lkIHhlbl9wdl9jcHVfZGllKHVuc2lnbmVk IGludCBjcHUpCi17Ci0Jd2hpbGUgKEhZUEVSVklTT1JfdmNwdV9vcChWQ1BVT1BfaXNfdXAsCi0J CQkJICB4ZW5fdmNwdV9ucihjcHUpLCBOVUxMKSkgewotCQlfX3NldF9jdXJyZW50X3N0YXRlKFRB U0tfVU5JTlRFUlJVUFRJQkxFKTsKLQkJc2NoZWR1bGVfdGltZW91dChIWi8xMCk7Ci0JfQotCi0J aWYgKGNvbW1vbl9jcHVfZGllKGNwdSkgPT0gMCkgewotCQl4ZW5fc21wX2ludHJfZnJlZShjcHUp OwotCQl4ZW5fdW5pbml0X2xvY2tfY3B1KGNwdSk7Ci0JCXhlbl90ZWFyZG93bl90aW1lcihjcHUp OwotCQl4ZW5fcG11X2ZpbmlzaChjcHUpOwotCX0KLX0KLQotc3RhdGljIHZvaWQgeGVuX3BsYXlf ZGVhZCh2b2lkKSAvKiB1c2VkIG9ubHkgd2l0aCBIT1RQTFVHX0NQVSAqLwotewotCXBsYXlfZGVh ZF9jb21tb24oKTsKLQlIWVBFUlZJU09SX3ZjcHVfb3AoVkNQVU9QX2Rvd24sIHhlbl92Y3B1X25y KHNtcF9wcm9jZXNzb3JfaWQoKSksIE5VTEwpOwotCWNwdV9icmluZ3VwKCk7Ci0JLyoKLQkgKiBj b21taXQgNGIwYzBmMjk0ICh0aWNrOiBDbGVhbnVwIE5PSFogcGVyIGNwdSBkYXRhIG9uIGNwdSBk b3duKQotCSAqIGNsZWFycyBjZXJ0YWluIGRhdGEgdGhhdCB0aGUgY3B1X2lkbGUgbG9vcCAod2hp Y2ggY2FsbGVkIHVzCi0JICogYW5kIHRoYXQgd2UgcmV0dXJuIGZyb20pIGV4cGVjdHMuIFRoZSBv bmx5IHdheSB0byBnZXQgdGhhdAotCSAqIGRhdGEgYmFjayBpcyB0byBjYWxsOgotCSAqLwotCXRp Y2tfbm9oel9pZGxlX2VudGVyKCk7Ci0KLQljcHVfc3RhcnR1cF9lbnRyeShDUFVIUF9BUF9PTkxJ TkVfSURMRSk7Ci19Ci0KLSNlbHNlIC8qICFDT05GSUdfSE9UUExVR19DUFUgKi8KLXN0YXRpYyBp bnQgeGVuX2NwdV9kaXNhYmxlKHZvaWQpCi17Ci0JcmV0dXJuIC1FTk9TWVM7Ci19Ci0KLXN0YXRp YyB2b2lkIHhlbl9wdl9jcHVfZGllKHVuc2lnbmVkIGludCBjcHUpCi17Ci0JQlVHKCk7Ci19Ci0K LXN0YXRpYyB2b2lkIHhlbl9wbGF5X2RlYWQodm9pZCkKLXsKLQlCVUcoKTsKLX0KLQotI2VuZGlm Ci1zdGF0aWMgdm9pZCBzdG9wX3NlbGYodm9pZCAqdikKLXsKLQlpbnQgY3B1ID0gc21wX3Byb2Nl c3Nvcl9pZCgpOwotCi0JLyogbWFrZSBzdXJlIHdlJ3JlIG5vdCBwaW5uaW5nIHNvbWV0aGluZyBk b3duICovCi0JbG9hZF9jcjMoc3dhcHBlcl9wZ19kaXIpOwotCS8qIHNob3VsZCBzZXQgdXAgYSBt aW5pbWFsIGdkdCAqLwotCi0Jc2V0X2NwdV9vbmxpbmUoY3B1LCBmYWxzZSk7Ci0KLQlIWVBFUlZJ U09SX3ZjcHVfb3AoVkNQVU9QX2Rvd24sIHhlbl92Y3B1X25yKGNwdSksIE5VTEwpOwotCUJVRygp OwotfQotCi1zdGF0aWMgdm9pZCB4ZW5fc3RvcF9vdGhlcl9jcHVzKGludCB3YWl0KQotewotCXNt cF9jYWxsX2Z1bmN0aW9uKHN0b3Bfc2VsZiwgTlVMTCwgd2FpdCk7Ci19Ci0KIHZvaWQgeGVuX3Nt cF9zZW5kX3Jlc2NoZWR1bGUoaW50IGNwdSkKIHsKIAl4ZW5fc2VuZF9JUElfb25lKGNwdSwgWEVO X1JFU0NIRURVTEVfVkVDVE9SKTsKQEAgLTY5NywzNiArMjQ4LDMgQEAgc3RhdGljIGlycXJldHVy bl90IHhlbl9jYWxsX2Z1bmN0aW9uX3NpbmdsZV9pbnRlcnJ1cHQoaW50IGlycSwgdm9pZCAqZGV2 X2lkKQogCiAJcmV0dXJuIElSUV9IQU5ETEVEOwogfQotCi1zdGF0aWMgaXJxcmV0dXJuX3QgeGVu X2lycV93b3JrX2ludGVycnVwdChpbnQgaXJxLCB2b2lkICpkZXZfaWQpCi17Ci0JaXJxX2VudGVy KCk7Ci0JaXJxX3dvcmtfcnVuKCk7Ci0JaW5jX2lycV9zdGF0KGFwaWNfaXJxX3dvcmtfaXJxcyk7 Ci0JaXJxX2V4aXQoKTsKLQotCXJldHVybiBJUlFfSEFORExFRDsKLX0KLQotc3RhdGljIGNvbnN0 IHN0cnVjdCBzbXBfb3BzIHhlbl9zbXBfb3BzIF9faW5pdGNvbnN0ID0gewotCS5zbXBfcHJlcGFy ZV9ib290X2NwdSA9IHhlbl9wdl9zbXBfcHJlcGFyZV9ib290X2NwdSwKLQkuc21wX3ByZXBhcmVf Y3B1cyA9IHhlbl9zbXBfcHJlcGFyZV9jcHVzLAotCS5zbXBfY3B1c19kb25lID0geGVuX3NtcF9j cHVzX2RvbmUsCi0KLQkuY3B1X3VwID0geGVuX2NwdV91cCwKLQkuY3B1X2RpZSA9IHhlbl9wdl9j cHVfZGllLAotCS5jcHVfZGlzYWJsZSA9IHhlbl9jcHVfZGlzYWJsZSwKLQkucGxheV9kZWFkID0g eGVuX3BsYXlfZGVhZCwKLQotCS5zdG9wX290aGVyX2NwdXMgPSB4ZW5fc3RvcF9vdGhlcl9jcHVz LAotCS5zbXBfc2VuZF9yZXNjaGVkdWxlID0geGVuX3NtcF9zZW5kX3Jlc2NoZWR1bGUsCi0KLQku c2VuZF9jYWxsX2Z1bmNfaXBpID0geGVuX3NtcF9zZW5kX2NhbGxfZnVuY3Rpb25faXBpLAotCS5z ZW5kX2NhbGxfZnVuY19zaW5nbGVfaXBpID0geGVuX3NtcF9zZW5kX2NhbGxfZnVuY3Rpb25fc2lu Z2xlX2lwaSwKLX07Ci0KLXZvaWQgX19pbml0IHhlbl9zbXBfaW5pdCh2b2lkKQotewotCXNtcF9v cHMgPSB4ZW5fc21wX29wczsKLQl4ZW5fZmlsbF9wb3NzaWJsZV9tYXAoKTsKLX0KZGlmZiAtLWdp dCBhL2FyY2gveDg2L3hlbi9zbXAuaCBiL2FyY2gveDg2L3hlbi9zbXAuaAppbmRleCAyZThjZDU2 Li44ZWJiNmFjIDEwMDY0NAotLS0gYS9hcmNoL3g4Ni94ZW4vc21wLmgKKysrIGIvYXJjaC94ODYv eGVuL3NtcC5oCkBAIC0xNyw2ICsxNywxMSBAQCB2b2lkIHhlbl9zbXBfaW50cl9mcmVlX3B2KHVu c2lnbmVkIGludCBjcHUpOwogdm9pZCB4ZW5fc21wX3NlbmRfcmVzY2hlZHVsZShpbnQgY3B1KTsK IHZvaWQgeGVuX3NtcF9zZW5kX2NhbGxfZnVuY3Rpb25faXBpKGNvbnN0IHN0cnVjdCBjcHVtYXNr ICptYXNrKTsKIHZvaWQgeGVuX3NtcF9zZW5kX2NhbGxfZnVuY3Rpb25fc2luZ2xlX2lwaShpbnQg Y3B1KTsKKworc3RydWN0IHhlbl9jb21tb25faXJxIHsKKwlpbnQgaXJxOworCWNoYXIgKm5hbWU7 Cit9OwogI2Vsc2UgLyogQ09ORklHX1NNUCAqLwogCiBzdGF0aWMgaW5saW5lIGludCB4ZW5fc21w X2ludHJfaW5pdCh1bnNpZ25lZCBpbnQgY3B1KQpkaWZmIC0tZ2l0IGEvYXJjaC94ODYveGVuL3Nt cF9wdi5jIGIvYXJjaC94ODYveGVuL3NtcF9wdi5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4 IDAwMDAwMDAuLjNhNjFlMGUKLS0tIC9kZXYvbnVsbAorKysgYi9hcmNoL3g4Ni94ZW4vc21wX3B2 LmMKQEAgLTAsMCArMSw1MDAgQEAKKy8qCisgKiBYZW4gU01QIHN1cHBvcnQKKyAqCisgKiBUaGlz IGZpbGUgaW1wbGVtZW50cyB0aGUgWGVuIHZlcnNpb25zIG9mIHNtcF9vcHMuICBTTVAgdW5kZXIg WGVuIGlzCisgKiB2ZXJ5IHN0cmFpZ2h0Zm9yd2FyZC4gIEJyaW5naW5nIGEgQ1BVIHVwIGlzIHNp bXBseSBhIG1hdHRlciBvZgorICogbG9hZGluZyBpdHMgaW5pdGlhbCBjb250ZXh0IGFuZCBzZXR0 aW5nIGl0IHJ1bm5pbmcuCisgKgorICogSVBJcyBhcmUgaGFuZGxlZCB0aHJvdWdoIHRoZSBYZW4g ZXZlbnQgbWVjaGFuaXNtLgorICoKKyAqIEJlY2F1c2UgdmlydHVhbCBDUFVzIGNhbiBiZSBzY2hl ZHVsZWQgb250byBhbnkgcmVhbCBDUFUsIHRoZXJlJ3Mgbm8KKyAqIHVzZWZ1bCB0b3BvbG9neSBp bmZvcm1hdGlvbiBmb3IgdGhlIGtlcm5lbCB0byBtYWtlIHVzZSBvZi4gIEFzIGEKKyAqIHJlc3Vs dCwgYWxsIENQVXMgYXJlIHRyZWF0ZWQgYXMgaWYgdGhleSdyZSBzaW5nbGUtY29yZSBhbmQKKyAq IHNpbmdsZS10aHJlYWRlZC4KKyAqLworI2luY2x1ZGUgPGxpbnV4L3NjaGVkLmg+CisjaW5jbHVk ZSA8bGludXgvZXJyLmg+CisjaW5jbHVkZSA8bGludXgvc2xhYi5oPgorI2luY2x1ZGUgPGxpbnV4 L3NtcC5oPgorI2luY2x1ZGUgPGxpbnV4L2lycV93b3JrLmg+CisjaW5jbHVkZSA8bGludXgvdGlj ay5oPgorI2luY2x1ZGUgPGxpbnV4L25taS5oPgorCisjaW5jbHVkZSA8YXNtL3BhcmF2aXJ0Lmg+ CisjaW5jbHVkZSA8YXNtL2Rlc2MuaD4KKyNpbmNsdWRlIDxhc20vcGd0YWJsZS5oPgorI2luY2x1 ZGUgPGFzbS9jcHUuaD4KKworI2luY2x1ZGUgPHhlbi9pbnRlcmZhY2UveGVuLmg+CisjaW5jbHVk ZSA8eGVuL2ludGVyZmFjZS92Y3B1Lmg+CisjaW5jbHVkZSA8eGVuL2ludGVyZmFjZS94ZW5wbXUu aD4KKworI2luY2x1ZGUgPGFzbS94ZW4vaW50ZXJmYWNlLmg+CisjaW5jbHVkZSA8YXNtL3hlbi9o eXBlcmNhbGwuaD4KKworI2luY2x1ZGUgPHhlbi94ZW4uaD4KKyNpbmNsdWRlIDx4ZW4vcGFnZS5o PgorI2luY2x1ZGUgPHhlbi9ldmVudHMuaD4KKworI2luY2x1ZGUgPHhlbi9odmMtY29uc29sZS5o PgorI2luY2x1ZGUgInhlbi1vcHMuaCIKKyNpbmNsdWRlICJtbXUuaCIKKyNpbmNsdWRlICJzbXAu aCIKKyNpbmNsdWRlICJwbXUuaCIKKworY3B1bWFza192YXJfdCB4ZW5fY3B1X2luaXRpYWxpemVk X21hcDsKKworc3RhdGljIERFRklORV9QRVJfQ1BVKHN0cnVjdCB4ZW5fY29tbW9uX2lycSwgeGVu X2lycV93b3JrKSA9IHsgLmlycSA9IC0xIH07CitzdGF0aWMgREVGSU5FX1BFUl9DUFUoc3RydWN0 IHhlbl9jb21tb25faXJxLCB4ZW5fcG11X2lycSkgPSB7IC5pcnEgPSAtMSB9OworCitzdGF0aWMg aXJxcmV0dXJuX3QgeGVuX2lycV93b3JrX2ludGVycnVwdChpbnQgaXJxLCB2b2lkICpkZXZfaWQp OworCitzdGF0aWMgdm9pZCBjcHVfYnJpbmd1cCh2b2lkKQoreworCWludCBjcHU7CisKKwljcHVf aW5pdCgpOworCXRvdWNoX3NvZnRsb2NrdXBfd2F0Y2hkb2coKTsKKwlwcmVlbXB0X2Rpc2FibGUo KTsKKworCS8qIFBWSCBydW5zIGluIHJpbmcgMCBhbmQgYWxsb3dzIHVzIHRvIGRvIG5hdGl2ZSBz eXNjYWxscy4gWWF5ISAqLworCWlmICgheGVuX2ZlYXR1cmUoWEVORkVBVF9zdXBlcnZpc29yX21v ZGVfa2VybmVsKSkgeworCQl4ZW5fZW5hYmxlX3N5c2VudGVyKCk7CisJCXhlbl9lbmFibGVfc3lz Y2FsbCgpOworCX0KKwljcHUgPSBzbXBfcHJvY2Vzc29yX2lkKCk7CisJc21wX3N0b3JlX2NwdV9p bmZvKGNwdSk7CisJY3B1X2RhdGEoY3B1KS54ODZfbWF4X2NvcmVzID0gMTsKKwlzZXRfY3B1X3Np YmxpbmdfbWFwKGNwdSk7CisKKwl4ZW5fc2V0dXBfY3B1X2Nsb2NrZXZlbnRzKCk7CisKKwlub3Rp ZnlfY3B1X3N0YXJ0aW5nKGNwdSk7CisKKwlzZXRfY3B1X29ubGluZShjcHUsIHRydWUpOworCisJ Y3B1X3NldF9zdGF0ZV9vbmxpbmUoY3B1KTsgIC8qIEltcGxpZXMgZnVsbCBtZW1vcnkgYmFycmll ci4gKi8KKworCS8qIFdlIGNhbiB0YWtlIGludGVycnVwdHMgbm93OiB3ZSdyZSBvZmZpY2lhbGx5 ICJ1cCIuICovCisJbG9jYWxfaXJxX2VuYWJsZSgpOworfQorCithc21saW5rYWdlIF9fdmlzaWJs ZSB2b2lkIGNwdV9icmluZ3VwX2FuZF9pZGxlKHZvaWQpCit7CisJY3B1X2JyaW5ndXAoKTsKKwlj cHVfc3RhcnR1cF9lbnRyeShDUFVIUF9BUF9PTkxJTkVfSURMRSk7Cit9CisKK3ZvaWQgeGVuX3Nt cF9pbnRyX2ZyZWVfcHYodW5zaWduZWQgaW50IGNwdSkKK3sKKwlpZiAocGVyX2NwdSh4ZW5faXJx X3dvcmssIGNwdSkuaXJxID49IDApIHsKKwkJdW5iaW5kX2Zyb21faXJxaGFuZGxlcihwZXJfY3B1 KHhlbl9pcnFfd29yaywgY3B1KS5pcnEsIE5VTEwpOworCQlwZXJfY3B1KHhlbl9pcnFfd29yaywg Y3B1KS5pcnEgPSAtMTsKKwkJa2ZyZWUocGVyX2NwdSh4ZW5faXJxX3dvcmssIGNwdSkubmFtZSk7 CisJCXBlcl9jcHUoeGVuX2lycV93b3JrLCBjcHUpLm5hbWUgPSBOVUxMOworCX0KKworCWlmIChw ZXJfY3B1KHhlbl9wbXVfaXJxLCBjcHUpLmlycSA+PSAwKSB7CisJCXVuYmluZF9mcm9tX2lycWhh bmRsZXIocGVyX2NwdSh4ZW5fcG11X2lycSwgY3B1KS5pcnEsIE5VTEwpOworCQlwZXJfY3B1KHhl bl9wbXVfaXJxLCBjcHUpLmlycSA9IC0xOworCQlrZnJlZShwZXJfY3B1KHhlbl9wbXVfaXJxLCBj cHUpLm5hbWUpOworCQlwZXJfY3B1KHhlbl9wbXVfaXJxLCBjcHUpLm5hbWUgPSBOVUxMOworCX0K K30KKworaW50IHhlbl9zbXBfaW50cl9pbml0X3B2KHVuc2lnbmVkIGludCBjcHUpCit7CisJaW50 IHJjOworCWNoYXIgKmNhbGxmdW5jX25hbWUsICpwbXVfbmFtZTsKKworCWNhbGxmdW5jX25hbWUg PSBrYXNwcmludGYoR0ZQX0tFUk5FTCwgImlycXdvcmslZCIsIGNwdSk7CisJcmMgPSBiaW5kX2lw aV90b19pcnFoYW5kbGVyKFhFTl9JUlFfV09SS19WRUNUT1IsCisJCQkJICAgIGNwdSwKKwkJCQkg ICAgeGVuX2lycV93b3JrX2ludGVycnVwdCwKKwkJCQkgICAgSVJRRl9QRVJDUFV8SVJRRl9OT0JB TEFOQ0lORywKKwkJCQkgICAgY2FsbGZ1bmNfbmFtZSwKKwkJCQkgICAgTlVMTCk7CisJaWYgKHJj IDwgMCkKKwkJZ290byBmYWlsOworCXBlcl9jcHUoeGVuX2lycV93b3JrLCBjcHUpLmlycSA9IHJj OworCXBlcl9jcHUoeGVuX2lycV93b3JrLCBjcHUpLm5hbWUgPSBjYWxsZnVuY19uYW1lOworCisJ aWYgKGlzX3hlbl9wbXUoY3B1KSkgeworCQlwbXVfbmFtZSA9IGthc3ByaW50ZihHRlBfS0VSTkVM LCAicG11JWQiLCBjcHUpOworCQlyYyA9IGJpbmRfdmlycV90b19pcnFoYW5kbGVyKFZJUlFfWEVO UE1VLCBjcHUsCisJCQkJCSAgICAgeGVuX3BtdV9pcnFfaGFuZGxlciwKKwkJCQkJICAgICBJUlFG X1BFUkNQVXxJUlFGX05PQkFMQU5DSU5HLAorCQkJCQkgICAgIHBtdV9uYW1lLCBOVUxMKTsKKwkJ aWYgKHJjIDwgMCkKKwkJCWdvdG8gZmFpbDsKKwkJcGVyX2NwdSh4ZW5fcG11X2lycSwgY3B1KS5p cnEgPSByYzsKKwkJcGVyX2NwdSh4ZW5fcG11X2lycSwgY3B1KS5uYW1lID0gcG11X25hbWU7CisJ fQorCisJcmV0dXJuIDA7CisKKyBmYWlsOgorCXhlbl9zbXBfaW50cl9mcmVlX3B2KGNwdSk7CisJ cmV0dXJuIHJjOworfQorCitzdGF0aWMgdm9pZCBfX2luaXQgeGVuX2ZpbGxfcG9zc2libGVfbWFw KHZvaWQpCit7CisJaW50IGksIHJjOworCisJaWYgKHhlbl9pbml0aWFsX2RvbWFpbigpKQorCQly ZXR1cm47CisKKwlmb3IgKGkgPSAwOyBpIDwgbnJfY3B1X2lkczsgaSsrKSB7CisJCXJjID0gSFlQ RVJWSVNPUl92Y3B1X29wKFZDUFVPUF9pc191cCwgaSwgTlVMTCk7CisJCWlmIChyYyA+PSAwKSB7 CisJCQludW1fcHJvY2Vzc29ycysrOworCQkJc2V0X2NwdV9wb3NzaWJsZShpLCB0cnVlKTsKKwkJ fQorCX0KK30KKworc3RhdGljIHZvaWQgX19pbml0IHhlbl9maWx0ZXJfY3B1X21hcHModm9pZCkK K3sKKwlpbnQgaSwgcmM7CisJdW5zaWduZWQgaW50IHN1YnRyYWN0ID0gMDsKKworCWlmICgheGVu X2luaXRpYWxfZG9tYWluKCkpCisJCXJldHVybjsKKworCW51bV9wcm9jZXNzb3JzID0gMDsKKwlk aXNhYmxlZF9jcHVzID0gMDsKKwlmb3IgKGkgPSAwOyBpIDwgbnJfY3B1X2lkczsgaSsrKSB7CisJ CXJjID0gSFlQRVJWSVNPUl92Y3B1X29wKFZDUFVPUF9pc191cCwgaSwgTlVMTCk7CisJCWlmIChy YyA+PSAwKSB7CisJCQludW1fcHJvY2Vzc29ycysrOworCQkJc2V0X2NwdV9wb3NzaWJsZShpLCB0 cnVlKTsKKwkJfSBlbHNlIHsKKwkJCXNldF9jcHVfcG9zc2libGUoaSwgZmFsc2UpOworCQkJc2V0 X2NwdV9wcmVzZW50KGksIGZhbHNlKTsKKwkJCXN1YnRyYWN0Kys7CisJCX0KKwl9CisjaWZkZWYg Q09ORklHX0hPVFBMVUdfQ1BVCisJLyogVGhpcyBpcyBha2luIHRvIHVzaW5nICducl9jcHVzJyBv biB0aGUgTGludXggY29tbWFuZCBsaW5lLgorCSAqIFdoaWNoIGlzIE9LIGFzIHdoZW4gd2UgdXNl ICdkb20wX21heF92Y3B1cz1YJyB3ZSBjYW4gb25seQorCSAqIGhhdmUgdXAgdG8gWCwgd2hpbGUg bnJfY3B1X2lkcyBpcyBncmVhdGVyIHRoYW4gWC4gVGhpcworCSAqIG5vcm1hbGx5IGlzIG5vdCBh IHByb2JsZW0sIGV4Y2VwdCB3aGVuIENQVSBob3RwbHVnZ2luZworCSAqIGlzIGludm9sdmVkIGFu ZCB0aGVuIHRoZXJlIG1pZ2h0IGJlIG1vcmUgdGhhbiBYIENQVXMKKwkgKiBpbiB0aGUgZ3Vlc3Qg LSB3aGljaCB3aWxsIG5vdCB3b3JrIGFzIHRoZXJlIGlzIG5vCisJICogaHlwZXJjYWxsIHRvIGV4 cGFuZCB0aGUgbWF4IG51bWJlciBvZiBWQ1BVcyBhbiBhbHJlYWR5CisJICogcnVubmluZyBndWVz dCBoYXMuIFNvIGNhcCBpdCB1cCB0byBYLiAqLworCWlmIChzdWJ0cmFjdCkKKwkJbnJfY3B1X2lk cyA9IG5yX2NwdV9pZHMgLSBzdWJ0cmFjdDsKKyNlbmRpZgorCit9CisKK3N0YXRpYyB2b2lkIF9f aW5pdCB4ZW5fcHZfc21wX3ByZXBhcmVfYm9vdF9jcHUodm9pZCkKK3sKKwlCVUdfT04oc21wX3By b2Nlc3Nvcl9pZCgpICE9IDApOworCW5hdGl2ZV9zbXBfcHJlcGFyZV9ib290X2NwdSgpOworCisJ aWYgKCF4ZW5fZmVhdHVyZShYRU5GRUFUX3dyaXRhYmxlX3BhZ2VfdGFibGVzKSkKKwkJLyogV2Un dmUgc3dpdGNoZWQgdG8gdGhlICJyZWFsIiBwZXItY3B1IGdkdCwgc28gbWFrZQorCQkgKiBzdXJl IHRoZSBvbGQgbWVtb3J5IGNhbiBiZSByZWN5Y2xlZC4gKi8KKwkJbWFrZV9sb3dtZW1fcGFnZV9y ZWFkd3JpdGUoeGVuX2luaXRpYWxfZ2R0KTsKKworI2lmZGVmIENPTkZJR19YODZfMzIKKwkvKgor CSAqIFhlbiBzdGFydHMgdXMgd2l0aCBYRU5fRkxBVF9SSU5HMV9EUywgYnV0IGxpbnV4IGNvZGUK KwkgKiBleHBlY3RzIF9fVVNFUl9EUworCSAqLworCWxvYWRzZWdtZW50KGRzLCBfX1VTRVJfRFMp OworCWxvYWRzZWdtZW50KGVzLCBfX1VTRVJfRFMpOworI2VuZGlmCisKKwl4ZW5fZmlsdGVyX2Nw dV9tYXBzKCk7CisJeGVuX3NldHVwX3ZjcHVfaW5mb19wbGFjZW1lbnQoKTsKKworCS8qCisJICog VGhlIGFsdGVybmF0aXZlIGxvZ2ljICh3aGljaCBwYXRjaGVzIHRoZSB1bmxvY2svbG9jaykgcnVu cyBiZWZvcmUKKwkgKiB0aGUgc21wIGJvb3R1cCB1cCBjb2RlIGlzIGFjdGl2YXRlZC4gSGVuY2Ug d2UgbmVlZCB0byBzZXQgdGhpcyB1cAorCSAqIHRoZSBjb3JlIGtlcm5lbCBpcyBiZWluZyBwYXRj aGVkLiBPdGhlcndpc2Ugd2Ugd2lsbCBoYXZlIG9ubHkKKwkgKiBtb2R1bGVzIHBhdGNoZWQgYnV0 IG5vdCBjb3JlIGNvZGUuCisJICovCisJeGVuX2luaXRfc3BpbmxvY2tzKCk7Cit9CisKK3N0YXRp YyB2b2lkIF9faW5pdCB4ZW5fc21wX3ByZXBhcmVfY3B1cyh1bnNpZ25lZCBpbnQgbWF4X2NwdXMp Cit7CisJdW5zaWduZWQgY3B1OworCXVuc2lnbmVkIGludCBpOworCisJaWYgKHNraXBfaW9hcGlj X3NldHVwKSB7CisJCWNoYXIgKm0gPSAobWF4X2NwdXMgPT0gMCkgPworCQkJIlRoZSBub3NtcCBw YXJhbWV0ZXIgaXMgaW5jb21wYXRpYmxlIHdpdGggWGVuOyAiIFwKKwkJCSJ1c2UgWGVuIGRvbTBf bWF4X3ZjcHVzPTEgcGFyYW1ldGVyIiA6CisJCQkiVGhlIG5vYXBpYyBwYXJhbWV0ZXIgaXMgaW5j b21wYXRpYmxlIHdpdGggWGVuIjsKKworCQl4ZW5fcmF3X3ByaW50ayhtKTsKKwkJcGFuaWMobSk7 CisJfQorCXhlbl9pbml0X2xvY2tfY3B1KDApOworCisJc21wX3N0b3JlX2Jvb3RfY3B1X2luZm8o KTsKKwljcHVfZGF0YSgwKS54ODZfbWF4X2NvcmVzID0gMTsKKworCWZvcl9lYWNoX3Bvc3NpYmxl X2NwdShpKSB7CisJCXphbGxvY19jcHVtYXNrX3ZhcigmcGVyX2NwdShjcHVfc2libGluZ19tYXAs IGkpLCBHRlBfS0VSTkVMKTsKKwkJemFsbG9jX2NwdW1hc2tfdmFyKCZwZXJfY3B1KGNwdV9jb3Jl X21hcCwgaSksIEdGUF9LRVJORUwpOworCQl6YWxsb2NfY3B1bWFza192YXIoJnBlcl9jcHUoY3B1 X2xsY19zaGFyZWRfbWFwLCBpKSwgR0ZQX0tFUk5FTCk7CisJfQorCXNldF9jcHVfc2libGluZ19t YXAoMCk7CisKKwl4ZW5fcG11X2luaXQoMCk7CisKKwlpZiAoeGVuX3NtcF9pbnRyX2luaXQoMCkp CisJCUJVRygpOworCisJaWYgKCFhbGxvY19jcHVtYXNrX3ZhcigmeGVuX2NwdV9pbml0aWFsaXpl ZF9tYXAsIEdGUF9LRVJORUwpKQorCQlwYW5pYygiY291bGQgbm90IGFsbG9jYXRlIHhlbl9jcHVf aW5pdGlhbGl6ZWRfbWFwXG4iKTsKKworCWNwdW1hc2tfY29weSh4ZW5fY3B1X2luaXRpYWxpemVk X21hcCwgY3B1bWFza19vZigwKSk7CisKKwkvKiBSZXN0cmljdCB0aGUgcG9zc2libGVfbWFwIGFj Y29yZGluZyB0byBtYXhfY3B1cy4gKi8KKwl3aGlsZSAoKG51bV9wb3NzaWJsZV9jcHVzKCkgPiAx KSAmJiAobnVtX3Bvc3NpYmxlX2NwdXMoKSA+IG1heF9jcHVzKSkgeworCQlmb3IgKGNwdSA9IG5y X2NwdV9pZHMgLSAxOyAhY3B1X3Bvc3NpYmxlKGNwdSk7IGNwdS0tKQorCQkJY29udGludWU7CisJ CXNldF9jcHVfcG9zc2libGUoY3B1LCBmYWxzZSk7CisJfQorCisJZm9yX2VhY2hfcG9zc2libGVf Y3B1KGNwdSkKKwkJc2V0X2NwdV9wcmVzZW50KGNwdSwgdHJ1ZSk7Cit9CisKK3N0YXRpYyBpbnQK K2NwdV9pbml0aWFsaXplX2NvbnRleHQodW5zaWduZWQgaW50IGNwdSwgc3RydWN0IHRhc2tfc3Ry dWN0ICppZGxlKQoreworCXN0cnVjdCB2Y3B1X2d1ZXN0X2NvbnRleHQgKmN0eHQ7CisJc3RydWN0 IGRlc2Nfc3RydWN0ICpnZHQ7CisJdW5zaWduZWQgbG9uZyBnZHRfbWZuOworCisJLyogdXNlZCB0 byB0ZWxsIGNwdV9pbml0KCkgdGhhdCBpdCBjYW4gcHJvY2VlZCB3aXRoIGluaXRpYWxpemF0aW9u ICovCisJY3B1bWFza19zZXRfY3B1KGNwdSwgY3B1X2NhbGxvdXRfbWFzayk7CisJaWYgKGNwdW1h c2tfdGVzdF9hbmRfc2V0X2NwdShjcHUsIHhlbl9jcHVfaW5pdGlhbGl6ZWRfbWFwKSkKKwkJcmV0 dXJuIDA7CisKKwljdHh0ID0ga3phbGxvYyhzaXplb2YoKmN0eHQpLCBHRlBfS0VSTkVMKTsKKwlp ZiAoY3R4dCA9PSBOVUxMKQorCQlyZXR1cm4gLUVOT01FTTsKKworCWdkdCA9IGdldF9jcHVfZ2R0 X3RhYmxlKGNwdSk7CisKKyNpZmRlZiBDT05GSUdfWDg2XzMyCisJY3R4dC0+dXNlcl9yZWdzLmZz ID0gX19LRVJORUxfUEVSQ1BVOworCWN0eHQtPnVzZXJfcmVncy5ncyA9IF9fS0VSTkVMX1NUQUNL X0NBTkFSWTsKKyNlbmRpZgorCW1lbXNldCgmY3R4dC0+ZnB1X2N0eHQsIDAsIHNpemVvZihjdHh0 LT5mcHVfY3R4dCkpOworCisJY3R4dC0+dXNlcl9yZWdzLmVpcCA9ICh1bnNpZ25lZCBsb25nKWNw dV9icmluZ3VwX2FuZF9pZGxlOworCWN0eHQtPmZsYWdzID0gVkdDRl9JTl9LRVJORUw7CisJY3R4 dC0+dXNlcl9yZWdzLmVmbGFncyA9IDB4MTAwMDsgLyogSU9QTF9SSU5HMSAqLworCWN0eHQtPnVz ZXJfcmVncy5kcyA9IF9fVVNFUl9EUzsKKwljdHh0LT51c2VyX3JlZ3MuZXMgPSBfX1VTRVJfRFM7 CisJY3R4dC0+dXNlcl9yZWdzLnNzID0gX19LRVJORUxfRFM7CisKKwl4ZW5fY29weV90cmFwX2lu Zm8oY3R4dC0+dHJhcF9jdHh0KTsKKworCWN0eHQtPmxkdF9lbnRzID0gMDsKKworCUJVR19PTigo dW5zaWduZWQgbG9uZylnZHQgJiB+UEFHRV9NQVNLKTsKKworCWdkdF9tZm4gPSBhcmJpdHJhcnlf dmlydF90b19tZm4oZ2R0KTsKKwltYWtlX2xvd21lbV9wYWdlX3JlYWRvbmx5KGdkdCk7CisJbWFr ZV9sb3dtZW1fcGFnZV9yZWFkb25seShtZm5fdG9fdmlydChnZHRfbWZuKSk7CisKKwljdHh0LT5n ZHRfZnJhbWVzWzBdID0gZ2R0X21mbjsKKwljdHh0LT5nZHRfZW50cyAgICAgID0gR0RUX0VOVFJJ RVM7CisKKwljdHh0LT5rZXJuZWxfc3MgPSBfX0tFUk5FTF9EUzsKKwljdHh0LT5rZXJuZWxfc3Ag PSBpZGxlLT50aHJlYWQuc3AwOworCisjaWZkZWYgQ09ORklHX1g4Nl8zMgorCWN0eHQtPmV2ZW50 X2NhbGxiYWNrX2NzICAgICA9IF9fS0VSTkVMX0NTOworCWN0eHQtPmZhaWxzYWZlX2NhbGxiYWNr X2NzICA9IF9fS0VSTkVMX0NTOworI2Vsc2UKKwljdHh0LT5nc19iYXNlX2tlcm5lbCA9IHBlcl9j cHVfb2Zmc2V0KGNwdSk7CisjZW5kaWYKKwljdHh0LT5ldmVudF9jYWxsYmFja19laXAgICAgPQor CQkodW5zaWduZWQgbG9uZyl4ZW5faHlwZXJ2aXNvcl9jYWxsYmFjazsKKwljdHh0LT5mYWlsc2Fm ZV9jYWxsYmFja19laXAgPQorCQkodW5zaWduZWQgbG9uZyl4ZW5fZmFpbHNhZmVfY2FsbGJhY2s7 CisJY3R4dC0+dXNlcl9yZWdzLmNzID0gX19LRVJORUxfQ1M7CisJcGVyX2NwdSh4ZW5fY3IzLCBj cHUpID0gX19wYShzd2FwcGVyX3BnX2Rpcik7CisKKwljdHh0LT51c2VyX3JlZ3MuZXNwID0gaWRs ZS0+dGhyZWFkLnNwMCAtIHNpemVvZihzdHJ1Y3QgcHRfcmVncyk7CisJY3R4dC0+Y3RybHJlZ1sz XSA9IHhlbl9wZm5fdG9fY3IzKHZpcnRfdG9fZ2ZuKHN3YXBwZXJfcGdfZGlyKSk7CisJaWYgKEhZ UEVSVklTT1JfdmNwdV9vcChWQ1BVT1BfaW5pdGlhbGlzZSwgeGVuX3ZjcHVfbnIoY3B1KSwgY3R4 dCkpCisJCUJVRygpOworCisJa2ZyZWUoY3R4dCk7CisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBp bnQgeGVuX2NwdV91cCh1bnNpZ25lZCBpbnQgY3B1LCBzdHJ1Y3QgdGFza19zdHJ1Y3QgKmlkbGUp Cit7CisJaW50IHJjOworCisJY29tbW9uX2NwdV91cChjcHUsIGlkbGUpOworCisJeGVuX3NldHVw X3J1bnN0YXRlX2luZm8oY3B1KTsKKworCS8qCisJICogUFYgVkNQVXMgYXJlIGFsd2F5cyBzdWNj ZXNzZnVsbHkgdGFrZW4gZG93biAoc2VlICd3aGlsZScgbG9vcAorCSAqIGluIHhlbl9jcHVfZGll KCkpLCBzbyAtRUJVU1kgaXMgYW4gZXJyb3IuCisJICovCisJcmMgPSBjcHVfY2hlY2tfdXBfcHJl cGFyZShjcHUpOworCWlmIChyYykKKwkJcmV0dXJuIHJjOworCisJLyogbWFrZSBzdXJlIGludGVy cnVwdHMgc3RhcnQgYmxvY2tlZCAqLworCXBlcl9jcHUoeGVuX3ZjcHUsIGNwdSktPmV2dGNobl91 cGNhbGxfbWFzayA9IDE7CisKKwlyYyA9IGNwdV9pbml0aWFsaXplX2NvbnRleHQoY3B1LCBpZGxl KTsKKwlpZiAocmMpCisJCXJldHVybiByYzsKKworCXhlbl9wbXVfaW5pdChjcHUpOworCisJcmMg PSBIWVBFUlZJU09SX3ZjcHVfb3AoVkNQVU9QX3VwLCB4ZW5fdmNwdV9ucihjcHUpLCBOVUxMKTsK KwlCVUdfT04ocmMpOworCisJd2hpbGUgKGNwdV9yZXBvcnRfc3RhdGUoY3B1KSAhPSBDUFVfT05M SU5FKQorCQlIWVBFUlZJU09SX3NjaGVkX29wKFNDSEVET1BfeWllbGQsIE5VTEwpOworCisJcmV0 dXJuIDA7Cit9CisKK3N0YXRpYyB2b2lkIHhlbl9zbXBfY3B1c19kb25lKHVuc2lnbmVkIGludCBt YXhfY3B1cykKK3sKK30KKworI2lmZGVmIENPTkZJR19IT1RQTFVHX0NQVQorc3RhdGljIGludCB4 ZW5fY3B1X2Rpc2FibGUodm9pZCkKK3sKKwl1bnNpZ25lZCBpbnQgY3B1ID0gc21wX3Byb2Nlc3Nv cl9pZCgpOworCWlmIChjcHUgPT0gMCkKKwkJcmV0dXJuIC1FQlVTWTsKKworCWNwdV9kaXNhYmxl X2NvbW1vbigpOworCisJbG9hZF9jcjMoc3dhcHBlcl9wZ19kaXIpOworCXJldHVybiAwOworfQor CitzdGF0aWMgdm9pZCB4ZW5fcHZfY3B1X2RpZSh1bnNpZ25lZCBpbnQgY3B1KQoreworCXdoaWxl IChIWVBFUlZJU09SX3ZjcHVfb3AoVkNQVU9QX2lzX3VwLAorCQkJCSAgeGVuX3ZjcHVfbnIoY3B1 KSwgTlVMTCkpIHsKKwkJX19zZXRfY3VycmVudF9zdGF0ZShUQVNLX1VOSU5URVJSVVBUSUJMRSk7 CisJCXNjaGVkdWxlX3RpbWVvdXQoSFovMTApOworCX0KKworCWlmIChjb21tb25fY3B1X2RpZShj cHUpID09IDApIHsKKwkJeGVuX3NtcF9pbnRyX2ZyZWUoY3B1KTsKKwkJeGVuX3VuaW5pdF9sb2Nr X2NwdShjcHUpOworCQl4ZW5fdGVhcmRvd25fdGltZXIoY3B1KTsKKwkJeGVuX3BtdV9maW5pc2go Y3B1KTsKKwl9Cit9CisKK3N0YXRpYyB2b2lkIHhlbl9wbGF5X2RlYWQodm9pZCkgLyogdXNlZCBv bmx5IHdpdGggSE9UUExVR19DUFUgKi8KK3sKKwlwbGF5X2RlYWRfY29tbW9uKCk7CisJSFlQRVJW SVNPUl92Y3B1X29wKFZDUFVPUF9kb3duLCB4ZW5fdmNwdV9ucihzbXBfcHJvY2Vzc29yX2lkKCkp LCBOVUxMKTsKKwljcHVfYnJpbmd1cCgpOworCS8qCisJICogY29tbWl0IDRiMGMwZjI5NCAodGlj azogQ2xlYW51cCBOT0haIHBlciBjcHUgZGF0YSBvbiBjcHUgZG93bikKKwkgKiBjbGVhcnMgY2Vy dGFpbiBkYXRhIHRoYXQgdGhlIGNwdV9pZGxlIGxvb3AgKHdoaWNoIGNhbGxlZCB1cworCSAqIGFu ZCB0aGF0IHdlIHJldHVybiBmcm9tKSBleHBlY3RzLiBUaGUgb25seSB3YXkgdG8gZ2V0IHRoYXQK KwkgKiBkYXRhIGJhY2sgaXMgdG8gY2FsbDoKKwkgKi8KKwl0aWNrX25vaHpfaWRsZV9lbnRlcigp OworCisJY3B1X3N0YXJ0dXBfZW50cnkoQ1BVSFBfQVBfT05MSU5FX0lETEUpOworfQorCisjZWxz ZSAvKiAhQ09ORklHX0hPVFBMVUdfQ1BVICovCitzdGF0aWMgaW50IHhlbl9jcHVfZGlzYWJsZSh2 b2lkKQoreworCXJldHVybiAtRU5PU1lTOworfQorCitzdGF0aWMgdm9pZCB4ZW5fcHZfY3B1X2Rp ZSh1bnNpZ25lZCBpbnQgY3B1KQoreworCUJVRygpOworfQorCitzdGF0aWMgdm9pZCB4ZW5fcGxh eV9kZWFkKHZvaWQpCit7CisJQlVHKCk7Cit9CisKKyNlbmRpZgorc3RhdGljIHZvaWQgc3RvcF9z ZWxmKHZvaWQgKnYpCit7CisJaW50IGNwdSA9IHNtcF9wcm9jZXNzb3JfaWQoKTsKKworCS8qIG1h a2Ugc3VyZSB3ZSdyZSBub3QgcGlubmluZyBzb21ldGhpbmcgZG93biAqLworCWxvYWRfY3IzKHN3 YXBwZXJfcGdfZGlyKTsKKwkvKiBzaG91bGQgc2V0IHVwIGEgbWluaW1hbCBnZHQgKi8KKworCXNl dF9jcHVfb25saW5lKGNwdSwgZmFsc2UpOworCisJSFlQRVJWSVNPUl92Y3B1X29wKFZDUFVPUF9k b3duLCB4ZW5fdmNwdV9ucihjcHUpLCBOVUxMKTsKKwlCVUcoKTsKK30KKworc3RhdGljIHZvaWQg eGVuX3N0b3Bfb3RoZXJfY3B1cyhpbnQgd2FpdCkKK3sKKwlzbXBfY2FsbF9mdW5jdGlvbihzdG9w X3NlbGYsIE5VTEwsIHdhaXQpOworfQorCitzdGF0aWMgaXJxcmV0dXJuX3QgeGVuX2NhbGxfZnVu Y3Rpb25faW50ZXJydXB0KGludCBpcnEsIHZvaWQgKmRldl9pZCkKK3sKKwlpcnFfZW50ZXIoKTsK KwlnZW5lcmljX3NtcF9jYWxsX2Z1bmN0aW9uX2ludGVycnVwdCgpOworCWluY19pcnFfc3RhdChp cnFfY2FsbF9jb3VudCk7CisJaXJxX2V4aXQoKTsKKworCXJldHVybiBJUlFfSEFORExFRDsKK30K Kworc3RhdGljIGlycXJldHVybl90IHhlbl9pcnFfd29ya19pbnRlcnJ1cHQoaW50IGlycSwgdm9p ZCAqZGV2X2lkKQoreworCWlycV9lbnRlcigpOworCWlycV93b3JrX3J1bigpOworCWluY19pcnFf c3RhdChhcGljX2lycV93b3JrX2lycXMpOworCWlycV9leGl0KCk7CisKKwlyZXR1cm4gSVJRX0hB TkRMRUQ7Cit9CisKK3N0YXRpYyBjb25zdCBzdHJ1Y3Qgc21wX29wcyB4ZW5fc21wX29wcyBfX2lu aXRjb25zdCA9IHsKKwkuc21wX3ByZXBhcmVfYm9vdF9jcHUgPSB4ZW5fcHZfc21wX3ByZXBhcmVf Ym9vdF9jcHUsCisJLnNtcF9wcmVwYXJlX2NwdXMgPSB4ZW5fc21wX3ByZXBhcmVfY3B1cywKKwku c21wX2NwdXNfZG9uZSA9IHhlbl9zbXBfY3B1c19kb25lLAorCisJLmNwdV91cCA9IHhlbl9jcHVf dXAsCisJLmNwdV9kaWUgPSB4ZW5fcHZfY3B1X2RpZSwKKwkuY3B1X2Rpc2FibGUgPSB4ZW5fY3B1 X2Rpc2FibGUsCisJLnBsYXlfZGVhZCA9IHhlbl9wbGF5X2RlYWQsCisKKwkuc3RvcF9vdGhlcl9j cHVzID0geGVuX3N0b3Bfb3RoZXJfY3B1cywKKwkuc21wX3NlbmRfcmVzY2hlZHVsZSA9IHhlbl9z bXBfc2VuZF9yZXNjaGVkdWxlLAorCisJLnNlbmRfY2FsbF9mdW5jX2lwaSA9IHhlbl9zbXBfc2Vu ZF9jYWxsX2Z1bmN0aW9uX2lwaSwKKwkuc2VuZF9jYWxsX2Z1bmNfc2luZ2xlX2lwaSA9IHhlbl9z bXBfc2VuZF9jYWxsX2Z1bmN0aW9uX3NpbmdsZV9pcGksCit9OworCit2b2lkIF9faW5pdCB4ZW5f c21wX2luaXQodm9pZCkKK3sKKwlzbXBfb3BzID0geGVuX3NtcF9vcHM7CisJeGVuX2ZpbGxfcG9z c2libGVfbWFwKCk7Cit9Ci0tIAoyLjkuMwoKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fClhlbi1kZXZlbCBtYWlsaW5nIGxpc3QKWGVuLWRldmVsQGxpc3Rz Lnhlbi5vcmcKaHR0cHM6Ly9saXN0cy54ZW4ub3JnL3hlbi1kZXZlbAo=