From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A6FFDC369B7 for ; Mon, 14 Apr 2025 08:37:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc: To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=1B7cZTxnGD7gq1+LaNCynvw/A9LQUPM3dE0eb6YDMnY=; b=XlmH7Uwg2A6Lq9m7z+fUm+dmFe P5QzHXPvbhmgmqyQj/+KQcrZj0kpIX2CTjvpOpz8TKJnG4dcdLFDa6Zoj9U3mDr9y0scOq84f44JW bnGfCCi7BW48NOsUk80X7hdOdwDonCgRmnqJqrOROdOrdA6XfwTImozBpR3rrguk+rzTBmonMfPDN 08jKXu/FXkHY5tVjaxjeSn9Qse7mdVHKOoOGH7bogIKICjt90xPY2UgBuevV3xhXFJxG+fJs3tqFd bUWGIcB0dZYADPp9BBVg2eQ2NXVD3X0muOr+mLc2U6B/6TIDvAA1S9bEd4Li86xLYyhNFxv2CDx9g r8r6XSnQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1u4FJb-000000017jp-1KHf; Mon, 14 Apr 2025 08:37:15 +0000 Received: from nyc.source.kernel.org ([147.75.193.91]) by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) id 1u2bou-00000008PGm-4B5x; Wed, 09 Apr 2025 20:14:51 +0000 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by nyc.source.kernel.org (Postfix) with ESMTP id 40F0FA48618; Wed, 9 Apr 2025 20:09:19 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 062F8C4CEE2; Wed, 9 Apr 2025 20:14:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1744229687; bh=XGWQ22s+RUjd5KmvBFM6Iqn5Ss0EmY1LQjC9nWMaoJY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lUzyGmeWATJpa5UY4zuoX/lgQWI01ocY8aWn6TJCAyqJNHQ/pfkTjRVjA/vA2a9PM xTSuEs4KNqEwcYCQ0SjDa+MADaJxckjhRF4Yv7oFCgx0FUdnuOicLAOLGUr/xADIeR Yrww//q791ecj+pduAv+5wXW1HrH2DdVvaAfUPJT+3cWuVjDk0WQfIzzRtXvfHbt9z mWhegxsiEU03Ew5JLSeHBAUTxJBvwRzvILIxBnCvfXjEJmfe4oJeVwJkUz/h117ZNu 8rllWDrXvagNRGSCZzXOiKHZPQGk0w71K0VMn+ZqdoZ5dgK1+JxibMb4KucTcp6IRh AkzPA5e/qQmjA== From: =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= To: Simon Horman , Simon Horman , Nick Kossifidis , Song Shuai , Li Zhengyu , kexec@lists.infradead.org Cc: Dave Young , Yixun Lan , Xianting Tian , linux-riscv@lists.infradead.org, =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= Subject: [PATCH 1/4] RISC-V: Add support for riscv kexec/kdump on kexec-tools Date: Wed, 9 Apr 2025 22:14:23 +0200 Message-ID: <20250409201428.648717-2-bjorn@kernel.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250409201428.648717-1-bjorn@kernel.org> References: <20250409201428.648717-1-bjorn@kernel.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250409_131449_278147_B834163E X-CRM114-Status: GOOD ( 39.24 ) X-Mailman-Approved-At: Mon, 14 Apr 2025 01:36:58 -0700 X-BeenThere: kexec@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "kexec" Errors-To: kexec-bounces+kexec=archiver.kernel.org@lists.infradead.org From: Nick Kossifidis This patch adds support for loading the ELF kernel image. It parses the current/provided device tree to determine the system's memory layout, and /proc/iomem for the various kernel segments. Tested on Qemu's rv64 virt machine and SoC of T-Head RISC-V Xuantie 910 CPU. Now, some history: The first stab at supporting kexec-tools on RISC-V was done by Nick Kossifidis. The initial patch has since then had a number of improvements/fixes by other authors. Given, this is the first commit for RISC-V, carrying the fixes/changes commits in the upstream tree does not really add anything (bisectability). Instead all the fixes that were applied to Nick's first commit is outlined below: Yixun Lan, and Xianting Tian: * Fixed a failure to fail to find free memory area for dtb load when using initrd image [1]. * Fixed memory range size calculation in kexec/arch/riscv/crashdump-riscv.c:85 Simon Horman: * RISC-V: distribute purgatory/riscv/Makefile Include purgatory/riscv/Makefile in distribution tarball. Local patch as it is planned to suggest this as a fix for the patch that introduced this problem. [2] Song Shuai: * RISC-V: Fix the undeclared ‘EM_RISCV’ build failure Use local `elf.h` instead of `linux/elf.h` to fix this build error: ``` kexec/arch/riscv/crashdump-riscv.c:17:13: error: ‘EM_RISCV’ undeclared here (not in a function); did you mean ‘EM_CRIS’? .machine = EM_RISCV, ^~~~~~~~ EM_CRIS ``` * RISC-V: Correct the usage of command line option RISC-V process OPT_CMDLINE with the "command-line" partten, but the riscv_opts_usage shows the "cmdline" option. So correct the usage's output. * RISC-V: Use linux,usable-memory-range for crash kernel Now we use "memeory::linux,usable-memory" to indicate the available memory for the crash kernel. While booting with UEFI, the crash kernel would use efi.memmap to re-populate memblock and then first kernel's memory would be corrputed. Consequently, the /proc/vmcore file failed to create in my local test. And according to "chosen" dtschema [3], the available memory for the crash kernel should be held via "chosen::linux,usable-memory-range" property which will re-cap memblock even after UEFI's re-population. * RISC-V: Get memory ranges from iomem When booting with UEFI, Linux marks the Runtime Code/Data memory as no-map and then exports it to "Reserved" iomem_resource. Kexc-tools uses dtb_get_memory_ranges() function to get memory ranges via parsing dtb, but it can't see the Reserved EFI Runtime memory. That would corrupt EFI Runtime memory and fail the kexeced kernel to deal EFI stuff. In my test, the kexeced kernel warned "efi: System table signature incorrect!" and then paniced at efi_call_rts() due to the null efi.runtime. So we should use /proc/iomem to get memory ranges. Björn Töpel: * Massaged this commit message! * Fixed up the build, by adding missing RV stub. * RISC-V: Only cap the upper/end usable memory window When loading the initrd in the kexec_load flow, memory for the segments are searched from end to start. Only the max_usable should be capped, after a successful initrd addtion. Currently min/max usable is set to the same value, making it impossible from subsequent segment allocations to success. * RISC-V: Make get_memory_ranges() properly exclude "Reserved" regions The get_memory_ranges() did not exclude "Reserved" regions from "System RAM" regions. It simply added "Reserved" as IOMEM, and IOMEM is not considered when looking for holes to place kexec segments. Instead, do a two pass of the /proc/iomem file. First pass, adds all the "System RAM" memory, and the second pass removes all intersecting "Reserved" regions. [1] https://lore.kernel.org/linux-riscv/CALecT5gQWn0PRO4Q24b6qkrfVE5OxsCp65TuhWTb30ceK_OJ0A@mail.gmail.com/ [2] https://lore.kernel.org/kexec/20221020031548.47587-1-xianting.tian@linux.alibaba.com/ [3] https://github.com/devicetree-org/dt-schema/blob/main/dtschema/schemas/chosen.yaml Tested-by: Yixun Lan Co-developed-by: Xianting Tian Co-developed-by: Yixun Lan Signed-off-by: Nick Kossifidis Signed-off-by: Simon Horman Signed-off-by: Song Shuai Signed-off-by: Björn Töpel --- configure.ac | 3 + include/elf.h | 1 + kexec/Makefile | 1 + kexec/arch/riscv/Makefile | 35 ++ kexec/arch/riscv/crashdump-riscv.c | 140 ++++++++ kexec/arch/riscv/include/arch/options.h | 43 +++ kexec/arch/riscv/iomem.h | 10 + kexec/arch/riscv/kexec-elf-riscv.c | 255 ++++++++++++++ kexec/arch/riscv/kexec-riscv.c | 431 +++++++++++++++++++++++ kexec/arch/riscv/kexec-riscv.h | 32 ++ kexec/dt-ops.c | 442 +++++++++++++++++++++++- kexec/dt-ops.h | 7 + kexec/kexec-syscall.h | 4 + purgatory/Makefile | 1 + purgatory/arch/riscv/Makefile | 7 + 15 files changed, 1411 insertions(+), 1 deletion(-) create mode 100644 kexec/arch/riscv/Makefile create mode 100644 kexec/arch/riscv/crashdump-riscv.c create mode 100644 kexec/arch/riscv/include/arch/options.h create mode 100644 kexec/arch/riscv/iomem.h create mode 100644 kexec/arch/riscv/kexec-elf-riscv.c create mode 100644 kexec/arch/riscv/kexec-riscv.c create mode 100644 kexec/arch/riscv/kexec-riscv.h create mode 100644 purgatory/arch/riscv/Makefile diff --git a/configure.ac b/configure.ac index 43cdb64bc91b..fa96d1782f4f 100644 --- a/configure.ac +++ b/configure.ac @@ -61,6 +61,9 @@ case $target_cpu in loongarch*) ARCH="loongarch" ;; + riscv32|riscv64) + ARCH="riscv" + ;; * ) AC_MSG_ERROR([unsupported architecture $target_cpu]) ;; diff --git a/include/elf.h b/include/elf.h index 1c8d2ccf6d26..93a5ee5eeffa 100644 --- a/include/elf.h +++ b/include/elf.h @@ -259,6 +259,7 @@ typedef struct #define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ #define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ #define EM_AARCH64 183 /* ARM AARCH64 */ +#define EM_RISCV 243 /* RISC-V */ #define EM_LOONGARCH 258 /* Loongson Loongarch*/ #define EM_NUM 184 diff --git a/kexec/Makefile b/kexec/Makefile index e969d1e18c5a..8b5851decaea 100644 --- a/kexec/Makefile +++ b/kexec/Makefile @@ -92,6 +92,7 @@ include $(srcdir)/kexec/arch/mips/Makefile include $(srcdir)/kexec/arch/cris/Makefile include $(srcdir)/kexec/arch/ppc/Makefile include $(srcdir)/kexec/arch/ppc64/Makefile +include $(srcdir)/kexec/arch/riscv/Makefile include $(srcdir)/kexec/arch/s390/Makefile include $(srcdir)/kexec/arch/sh/Makefile include $(srcdir)/kexec/arch/x86_64/Makefile diff --git a/kexec/arch/riscv/Makefile b/kexec/arch/riscv/Makefile new file mode 100644 index 000000000000..f26cc9025e77 --- /dev/null +++ b/kexec/arch/riscv/Makefile @@ -0,0 +1,35 @@ +# +# kexec riscv +# +riscv_KEXEC_SRCS = kexec/arch/riscv/kexec-riscv.c +riscv_KEXEC_SRCS += kexec/arch/riscv/kexec-elf-riscv.c +riscv_KEXEC_SRCS += kexec/arch/riscv/crashdump-riscv.c + +riscv_MEM_REGIONS = kexec/mem_regions.c + +riscv_DT_OPS += kexec/dt-ops.c + +riscv_ARCH_REUSE_INITRD = + +riscv_CPPFLAGS += -I $(srcdir)/kexec/ + +dist += kexec/arch/riscv/Makefile $(riscv_KEXEC_SRCS) \ + kexec/arch/riscv/kexec-riscv.h \ + kexec/arch/riscv/include/arch/options.h + +ifdef HAVE_LIBFDT + +LIBS += -lfdt + +else + +include $(srcdir)/kexec/libfdt/Makefile.libfdt + +libfdt_SRCS += $(LIBFDT_SRCS:%=kexec/libfdt/%) + +riscv_CPPFLAGS += -I$(srcdir)/kexec/libfdt + +riscv_KEXEC_SRCS += $(libfdt_SRCS) + +endif + diff --git a/kexec/arch/riscv/crashdump-riscv.c b/kexec/arch/riscv/crashdump-riscv.c new file mode 100644 index 000000000000..336d7a7f5646 --- /dev/null +++ b/kexec/arch/riscv/crashdump-riscv.c @@ -0,0 +1,140 @@ +#include +#include +#include + +#include "kexec.h" +#include "crashdump.h" +#include "kexec-elf.h" +#include "mem_regions.h" + +static struct crash_elf_info elf_info = { +#if __riscv_xlen == 64 + .class = ELFCLASS64, +#else + .class = ELFCLASS32, +#endif + .data = ELFDATA2LSB, + .machine = EM_RISCV, +}; + +static struct memory_ranges crash_mem_ranges = {0}; +struct memory_range elfcorehdr_mem = {0}; + +static unsigned long long get_page_offset(struct kexec_info *info) +{ + unsigned long long vaddr_off = 0; + unsigned long long page_size = sysconf(_SC_PAGESIZE); + unsigned long long init_start = get_kernel_sym("_sinittext"); + + /* + * Begining of init section is aligned to page size + */ + vaddr_off = init_start - page_size; + + return vaddr_off; +} + +int load_elfcorehdr(struct kexec_info *info) +{ + struct memory_range crashkern_range = {0}; + struct memory_range *ranges = NULL; + unsigned long start = 0; + unsigned long end = 0; + unsigned long buf_size = 0; + unsigned long elfcorehdr_addr = 0; + void* buf = NULL; + int i = 0; + int ret = 0; + + ret = parse_iomem_single("Kernel code\n", &start, NULL); + if (ret) { + fprintf(stderr, "Cannot determine kernel physical base addr\n"); + return -EINVAL; + } + elf_info.kern_paddr_start = start; + + ret = parse_iomem_single("Kernel bss\n", NULL, &end); + if (ret) { + fprintf(stderr, "Cannot determine kernel physical bss addr\n"); + return -EINVAL; + } + elf_info.kern_paddr_start = start; + elf_info.kern_size = end - start; + + elf_info.kern_vaddr_start = get_kernel_sym("_text"); + if (!elf_info.kern_vaddr_start) { + elf_info.kern_vaddr_start = UINT64_MAX; + } + + elf_info.page_offset = get_page_offset(info); + dbgprintf("page_offset: %016llx\n", elf_info.page_offset); + + ret = parse_iomem_single("Crash kernel\n", &start, &end); + if (ret) { + fprintf(stderr, "Cannot determine kernel physical bss addr\n"); + return -EINVAL; + } + crashkern_range.start = start; + crashkern_range.end = end; + crashkern_range.type = RANGE_RESERVED; + + ranges = info->memory_range; + for (i = 0; i < info->memory_ranges; i++) { + ret = mem_regions_alloc_and_add(&crash_mem_ranges, + ranges[i].start, + ranges[i].end - ranges[i].start + 1, + ranges[i].type); + if (ret ) { + fprintf(stderr, "Could not create crash_mem_ranges\n"); + return ret; + } + } + + ret = mem_regions_alloc_and_exclude(&crash_mem_ranges, + &crashkern_range); + if (ret) { + fprintf(stderr, "Could not exclude crashkern_range\n"); + return ret; + } + +#if __riscv_xlen == 64 + crash_create_elf64_headers(info, &elf_info, crash_mem_ranges.ranges, + crash_mem_ranges.size, &buf, &buf_size, + ELF_CORE_HEADER_ALIGN); + +#else + crash_create_elf32_headers(info, &elf_info, crash_mem_ranges.ranges, + crash_mem_ranges.size, &buf, &buf_size, + ELF_CORE_HEADER_ALIGN); +#endif + + + elfcorehdr_addr = add_buffer_phys_virt(info, buf, buf_size, + buf_size, 0, + crashkern_range.start, + crashkern_range.end, + -1, 0); + + elfcorehdr_mem.start = elfcorehdr_addr; + elfcorehdr_mem.end = elfcorehdr_addr + buf_size - 1; + + dbgprintf("%s: elfcorehdr 0x%llx-0x%llx\n", __func__, + elfcorehdr_mem.start, elfcorehdr_mem.end); + + return 0; +} + +int is_crashkernel_mem_reserved(void) +{ + uint64_t start = 0; + uint64_t end = 0; + + return parse_iomem_single("Crash kernel\n", &start, &end) == 0 ? + (start != end) : 0; +} + +int get_crash_kernel_load_range(uint64_t *start, uint64_t *end) +{ + return parse_iomem_single("Crash kernel\n", start, end); +} + diff --git a/kexec/arch/riscv/include/arch/options.h b/kexec/arch/riscv/include/arch/options.h new file mode 100644 index 000000000000..7c24184b1f3e --- /dev/null +++ b/kexec/arch/riscv/include/arch/options.h @@ -0,0 +1,43 @@ +#ifndef KEXEC_ARCH_RISCV_OPTIONS_H +#define KEXEC_ARCH_RISCV_OPTIONS_H + +#define OPT_APPEND ((OPT_MAX)+0) +#define OPT_DTB ((OPT_MAX)+1) +#define OPT_INITRD ((OPT_MAX)+2) +#define OPT_CMDLINE ((OPT_MAX)+3) +#define OPT_REUSE_CMDLINE ((OPT_MAX)+4) +#define OPT_ARCH_MAX ((OPT_MAX)+5) + +/* Options relevant to the architecture (excluding loader-specific ones), + * in this case none: + */ +#define KEXEC_ARCH_OPTIONS \ + KEXEC_OPTIONS \ + { "append", 1, 0, OPT_APPEND}, \ + { "dtb", 1, 0, OPT_DTB }, \ + { "initrd", 1, 0, OPT_INITRD }, \ + { "command-line", 1, 0, OPT_CMDLINE}, \ + { "reuse-cmdline", 0, NULL, OPT_REUSE_CMDLINE }, \ + + +#define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR "" + +/* The following two #defines list ALL of the options added by all of the + * architecture's loaders. + * o main() uses this complete list to scan for its options, ignoring + * arch-specific/loader-specific ones. + * o Then, arch_process_options() uses this complete list to scan for its + * options, ignoring general/loader-specific ones. + * o Then, the file_type[n].load re-scans for options, using + * KEXEC_ARCH_OPTIONS plus its loader-specific options subset. + * Any unrecognised options cause an error here. + * + * This is done so that main()'s/arch_process_options()'s getopt_long() calls + * don't choose a kernel filename from random arguments to options they don't + * recognise -- as they now recognise (if not act upon) all possible options. + */ +#define KEXEC_ALL_OPTIONS KEXEC_ARCH_OPTIONS + +#define KEXEC_ALL_OPT_STR KEXEC_ARCH_OPT_STR + +#endif /* KEXEC_ARCH_RISCV_OPTIONS_H */ diff --git a/kexec/arch/riscv/iomem.h b/kexec/arch/riscv/iomem.h new file mode 100644 index 000000000000..7671e26a9594 --- /dev/null +++ b/kexec/arch/riscv/iomem.h @@ -0,0 +1,10 @@ +#ifndef IOMEM_H +#define IOMEM_H + +#define SYSTEM_RAM "System RAM\n" +#define KERNEL_CODE "Kernel code\n" +#define KERNEL_DATA "Kernel data\n" +#define CRASH_KERNEL "Crash kernel\n" +#define IOMEM_RESERVED "Reserved\n" + +#endif diff --git a/kexec/arch/riscv/kexec-elf-riscv.c b/kexec/arch/riscv/kexec-elf-riscv.c new file mode 100644 index 000000000000..f3c011c4c1dc --- /dev/null +++ b/kexec/arch/riscv/kexec-elf-riscv.c @@ -0,0 +1,255 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2019 FORTH-ICS/CARV + * Nick Kossifidis + */ + +#include "kexec.h" +#include "dt-ops.h" /* For dtb_set/clear_initrd() */ +#include /* For ELF header handling */ +#include /* For EFBIG/EINVAL */ +#include /* For getpagesize() */ +#include "kexec-syscall.h" /* For KEXEC_ON_CRASH */ +#include "kexec-riscv.h" + + +/*********\ +* HELPERS * +\*********/ + +/* + * Go through the available physical memory regions and + * find one that can hold an image of the specified size. + * Note: This is called after get_memory_ranges so + * info->memory_range[] should be populated. Also note that + * memory ranges are sorted, so we'll return the first region + * that's big enough for holding the image. + */ +static int elf_riscv_find_pbase(struct kexec_info *info, off_t *addr, + off_t size) +{ + int i = 0; + off_t start = 0; + off_t end = 0; + int ret = 0; + + /* + * If this image is for a crash kernel, use the region + * the primary kernel has already reserved for us. + */ + if (info->kexec_flags & KEXEC_ON_CRASH) { + ret = get_crash_kernel_load_range((uint64_t *) &start, + (uint64_t *) &end); + if (!ret) { + /* + * Kernel should be aligned to the nearest + * hugepage (2MB for RV64, 4MB for RV32). + */ +#if __riscv_xlen == 64 + start = _ALIGN_UP(start, 0x200000); +#else + start = _ALIGN_UP(start, 0x400000); +#endif + if (end > start && ((end - start) >= size)) { + *addr = start; + return 0; + } + + return -EFBIG; + } else + return ENOCRASHKERNEL; + } + + for (i = 0; i < info->memory_ranges; i++) { + if (info->memory_range[i].type != RANGE_RAM) + continue; + + start = info->memory_range[i].start; + end = info->memory_range[i].end; + +#if __riscv_xlen == 64 + start = _ALIGN_UP(start, 0x200000); +#else + start = _ALIGN_UP(start, 0x400000); +#endif + + if (end > start && ((end - start) >= size)) { + *addr = start; + return 0; + } + } + + return -EFBIG; +} + +/**************\ +* ENTRY POINTS * +\**************/ + +int elf_riscv_probe(const char *buf, off_t len) +{ + struct mem_ehdr ehdr = {0}; + int ret = 0; + + ret = build_elf_exec_info(buf, len, &ehdr, 0); + if (ret < 0) + goto cleanup; + + if (ehdr.e_machine != EM_RISCV) { + fprintf(stderr, "Not for this architecture.\n"); + ret = -EINVAL; + goto cleanup; + } + + ret = 0; + + cleanup: + free_elf_info(&ehdr); + return ret; +} + +void elf_riscv_usage(void) +{ +} + +int elf_riscv_load(int argc, char **argv, const char *buf, off_t len, + struct kexec_info *info) +{ + struct mem_ehdr ehdr = {0}; + struct mem_phdr *phdr = NULL; + off_t new_base_addr = 0; + off_t kernel_size = 0; + off_t page_size = getpagesize(); + off_t max_addr = 0; + off_t old_base_addr = 0; + off_t old_start_addr = 0; + int i = 0; + int ret = 0; + + if (info->file_mode) { + fprintf(stderr, "kexec_file not supported on this " + "architecture\n"); + return -EINVAL; + } + + /* Parse the ELF file */ + ret = build_elf_exec_info(buf, len, &ehdr, 0); + if (ret < 0) { + fprintf(stderr, "ELF exec parse failed\n"); + return -EINVAL; + } + + max_addr = elf_max_addr(&ehdr); + old_base_addr = max_addr; + old_start_addr = max_addr; + + /* + * Get the memory footprint, base physical + * and start address of the ELF image + */ + for (i = 0; i < ehdr.e_phnum; i++) { + phdr = &ehdr.e_phdr[i]; + if (phdr->p_type != PT_LOAD) + continue; + + /* + * Note: According to ELF spec the loadable regions + * are sorted on p_vaddr, not p_paddr. + */ + if (old_base_addr > phdr->p_paddr) + old_base_addr = phdr->p_paddr; + + if (phdr->p_vaddr == ehdr.e_entry || + phdr->p_paddr == ehdr.e_entry) + old_start_addr = phdr->p_paddr; + + kernel_size += _ALIGN_UP(phdr->p_memsz, page_size); + } + + if (old_base_addr == max_addr || kernel_size == 0) { + fprintf(stderr, "No loadable segments present on the " + "provided ELF image\n"); + return -EINVAL; + } + + if (old_start_addr == max_addr) { + fprintf(stderr, "Could not find the entry point address of " + "provided ELF image\n"); + return -EINVAL; + } + + dbgprintf("Got ELF with total memsz %luKB\n" + "Base paddr: 0x%lX, start_addr: 0x%lX\n", + kernel_size / 1024, old_base_addr, old_start_addr); + + /* Get a continuous physical region that can hold the kernel */ + ret = elf_riscv_find_pbase(info, &new_base_addr, kernel_size); + if (ret < 0) { + fprintf(stderr, "Could not find a memory region for the " + "provided ELF image\n"); + return ret; + } + + dbgprintf("New base paddr for the ELF: 0x%lX\n", new_base_addr); + + /* Re-set the base physical address of the ELF */ + for (i = 0; i < ehdr.e_phnum; i++) { + phdr = &ehdr.e_phdr[i]; + if (phdr->p_type != PT_LOAD) + continue; + + phdr->p_paddr -= old_base_addr; + phdr->p_paddr += new_base_addr; + } + + /* Re-set the entry point address */ + ehdr.e_entry = (old_start_addr - old_base_addr) + new_base_addr; + info->entry = (void *) ehdr.e_entry; + dbgprintf("New entry point for the ELF: 0x%llX\n", ehdr.e_entry); + + + /* Load the ELF executable */ + ret = elf_exec_load(&ehdr, info); + if (ret < 0) { + fprintf(stderr, "ELF exec load failed\n"); + return ret; + } + + ret = load_extra_segments(info, new_base_addr, + kernel_size, max_addr); + return ret; +} + + +/*******\ +* STUBS * +\*******/ + +int machine_verify_elf_rel(struct mem_ehdr *ehdr) +{ + if (ehdr->ei_data != ELFDATA2LSB) + return 0; +#if __riscv_xlen == 64 + if (ehdr->ei_class != ELFCLASS64) +#else + if (ehdr->ei_class != ELFCLASS32) +#endif + return 0; + if (ehdr->e_machine != EM_RISCV) + return 0; + return 1; +} + +void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr), + struct mem_sym *UNUSED(sym), + unsigned long r_type, + void *UNUSED(location), + unsigned long UNUSED(address), + unsigned long UNUSED(value)) +{ + switch (r_type) { + default: + die("Unknown rela relocation: %lu\n", r_type); + break; + } +} diff --git a/kexec/arch/riscv/kexec-riscv.c b/kexec/arch/riscv/kexec-riscv.c new file mode 100644 index 000000000000..38d9a394aadd --- /dev/null +++ b/kexec/arch/riscv/kexec-riscv.c @@ -0,0 +1,431 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2019 FORTH-ICS/CARV + * Nick Kossifidis + */ + +#include "kexec-syscall.h" /* For KEXEC_ARCH_RISCV */ +#include "kexec.h" /* For OPT_MAX and concat_cmdline() */ +#include "mem_regions.h" /* For mem_regions_sort() */ +#include "dt-ops.h" /* For dtb_set_bootargs() */ +#include /* For KEXEC_ARCH_OPTIONS */ +#include /* For struct option */ +#include /* For stat() and struct stat */ +#include /* For free() */ +#include /* For EINVAL */ +#include /* For DeviceTree handling */ +#include "kexec-riscv.h" +#include "iomem.h" +#include + +const struct arch_map_entry arches[] = { + { "riscv32", KEXEC_ARCH_RISCV }, + { "riscv64", KEXEC_ARCH_RISCV }, + { NULL, 0 }, +}; + + +struct file_type file_type[] = { + {"elf-riscv", elf_riscv_probe, elf_riscv_load, elf_riscv_usage}, +}; +int file_types = sizeof(file_type) / sizeof(file_type[0]); + +static const char riscv_opts_usage[] = +" --append=STRING Append STRING to the kernel command line.\n" +" --dtb=FILE Use FILE as the device tree blob.\n" +" --initrd=FILE Use FILE as the kernel initial ramdisk.\n" +" --command-line=STRING Use STRING as the kernel's command line.\n" +" --reuse-cmdline Use kernel command line from running system.\n"; + +static struct riscv_opts arch_options = {0}; +static struct fdt_image provided_fdt = {0}; + +/****************\ +* COMMON HELPERS * +\****************/ + +int load_extra_segments(struct kexec_info *info, uint64_t kernel_base, + uint64_t kernel_size, uint64_t max_addr) +{ + struct fdt_image *fdt = arch_options.fdt; + char *initrd_buf = NULL; + off_t initrd_size = 0; + uint64_t initrd_base = 0; + uint64_t start = 0; + uint64_t end = 0; + uint64_t min_usable = kernel_base + kernel_size; + uint64_t max_usable = max_addr; + int ret = 0; + + /* Prepare the device tree */ + if (info->kexec_flags & KEXEC_ON_CRASH) { + ret = load_elfcorehdr(info); + if (ret) { + fprintf(stderr, "Couldn't create elfcorehdr\n"); + return ret; + } + + ret = dtb_add_range_property(&fdt->buf, &fdt->size, + elfcorehdr_mem.start, elfcorehdr_mem.end, + "chosen", "linux,elfcorehdr"); + if (ret) { + fprintf(stderr, "Couldn't add elfcorehdr to fdt\n"); + return ret; + } + + ret = get_crash_kernel_load_range(&start, &end); + if (ret) { + fprintf(stderr, "Couldn't get crashkenel region\n"); + return ret; + } + + ret = dtb_add_range_property(&fdt->buf, &fdt->size, start, end, + "chosen", "linux,usable-memory-range"); + if (ret) { + fprintf(stderr, "Couldn't add usable-memory-range to fdt\n"); + return ret; + } + + max_usable = end; + } else { + /* + * Make sure we remove elfcorehdr and usable-memory-range + * when switching from crash kernel to a normal one. + */ + dtb_delete_property(fdt->buf, "chosen", "linux,elfcorehdr"); + dtb_delete_property(fdt->buf, "chosen", "linux,usable-memory-range"); + } + + /* Do we need to include an initrd image ? */ + if (!arch_options.initrd_path && !arch_options.initrd_end) + dtb_clear_initrd(&fdt->buf, &fdt->size); + else if (arch_options.initrd_path) { + if (arch_options.initrd_end) + fprintf(stderr, "Warning: An initrd image was provided" + ", will ignore reuseinitrd\n"); + + initrd_buf = slurp_file(arch_options.initrd_path, + &initrd_size); + if (!initrd_buf) { + fprintf(stderr, "Couldn't read provided initrd\n"); + return -EINVAL; + } + + initrd_base = add_buffer_phys_virt(info, initrd_buf, + initrd_size, + initrd_size, 0, + min_usable, + max_usable, -1, 0); + + dtb_set_initrd(&fdt->buf, &fdt->size, initrd_base, + initrd_base + initrd_size); + + dbgprintf("Base addr for initrd image: 0x%lX\n", initrd_base); + max_usable = initrd_base; + } + + /* Add device tree */ + add_buffer_phys_virt(info, fdt->buf, fdt->size, fdt->size, 0, + min_usable, max_usable, -1, 0); + + return 0; +} + + +/**************\ +* ENTRY POINTS * +\**************/ + +void arch_usage(void) +{ + printf(riscv_opts_usage); +} + +int arch_process_options(int argc, char **argv) +{ + static const struct option options[] = { + KEXEC_ARCH_OPTIONS + { 0 }, + }; + static const char short_options[] = KEXEC_ARCH_OPT_STR; + struct stat st = {0}; + char *append = NULL; + char *cmdline = NULL; + void *tmp = NULL; + off_t tmp_size = 0; + int opt = 0; + int ret = 0; + + while ((opt = getopt_long(argc, argv, short_options, + options, 0)) != -1) { + switch (opt) { + case OPT_APPEND: + append = optarg; + break; + case OPT_CMDLINE: + if (cmdline) + fprintf(stderr, + "Warning: Kernel's cmdline " + "set twice !\n"); + cmdline = optarg; + break; + case OPT_REUSE_CMDLINE: + if (cmdline) + fprintf(stderr, + "Warning: Kernel's cmdline " + "set twice !\n"); + cmdline = get_command_line(); + break; + case OPT_DTB: + ret = stat(optarg, &st); + if (ret) { + fprintf(stderr, + "Could not find the provided dtb !\n"); + return -EINVAL; + } + arch_options.fdt_path = optarg; + break; + case OPT_INITRD: + ret = stat(optarg, &st); + if (ret) { + fprintf(stderr, + "Could not find the provided " + "initrd image !\n"); + return -EINVAL; + } + arch_options.initrd_path = optarg; + break; + default: + break; + } + } + + /* Handle Kernel's command line */ + if (append && !cmdline) + fprintf(stderr, "Warning: No cmdline provided, " + "using append string as cmdline\n"); + if (!append && !cmdline) + fprintf(stderr, "Warning: No cmdline or append string " + "provided\n"); + + if (append || cmdline) + /* + * Note that this also handles the case where "cmdline" + * or "append" is NULL. + */ + arch_options.cmdline = concat_cmdline(cmdline, append); + + /* Handle FDT image */ + if (!arch_options.fdt_path) { + ret = stat("/sys/firmware/fdt", &st); + if (ret) { + fprintf(stderr, "No dtb provided and " + "/sys/firmware/fdt is not present\n"); + return -EINVAL; + } + fprintf(stderr, "Warning: No dtb provided, " + "using /sys/firmware/fdt\n"); + arch_options.fdt_path = "/sys/firmware/fdt"; + } + + tmp = slurp_file(arch_options.fdt_path, &tmp_size); + if (!tmp) { + fprintf(stderr, "Couldn't read provided fdt\n"); + return -EINVAL; + } + + ret = fdt_check_header(tmp); + if (ret) { + fprintf(stderr, "Got an ivalid fdt image !\n"); + free(tmp); + return -EINVAL; + } + provided_fdt.buf = tmp; + provided_fdt.size = tmp_size; + + if (arch_options.cmdline) { + ret = dtb_set_bootargs(&provided_fdt.buf, &provided_fdt.size, + arch_options.cmdline); + if (ret < 0) { + fprintf(stderr, "Could not set bootargs on " + "the fdt image\n"); + return ret; + } + } + + arch_options.fdt = &provided_fdt; + + return 0; +} + +/* + * This one is called after arch_process_options so we already + * have an fdt image in place. + */ +void arch_reuse_initrd(void) +{ + const uint32_t *prop32 = NULL; + uint32_t addr_cells = 0; + const void *prop = 0; + int prop_size = 0; + uint64_t initrd_start = 0; + uint64_t initrd_end = 0; + int chosen_offset = 0; + struct fdt_image *fdt = &provided_fdt; + + chosen_offset = fdt_subnode_offset(fdt->buf, 0, "chosen"); + if (chosen_offset < 0) { + fprintf(stderr, "No /chosen node found on fdt image " + "unable to reuse initrd\n"); + return; + } + + prop32 = fdt_getprop(fdt->buf, 0, "#address-cells", NULL); + if (!prop32) { + fprintf(stderr, "No #address-cells property on root node\n"); + return; + } + addr_cells = be32_to_cpu(*prop32); + + prop = fdt_getprop(fdt->buf, chosen_offset, + "linux,initrd-start", &prop_size); + if (!prop) { + fprintf(stderr, "Could not get linux,initrd-start\n"); + return; + } + dtb_extract_int_property(&initrd_start, prop, addr_cells); + + prop = fdt_getprop(fdt->buf, chosen_offset, + "linux,initrd-end", &prop_size); + if (!prop) { + fprintf(stderr, "Could not get linux,initrd-end\n"); + return; + } + dtb_extract_int_property(&initrd_end, prop, addr_cells); + + arch_options.initrd_start = initrd_start; + arch_options.initrd_end = initrd_end; + dbgprintf("initrd_start: 0x%lX, initrd_end: 0x%lX\n", + initrd_start, initrd_end); + +} + +static bool to_be_excluded(char *str, unsigned long long start, unsigned long long end) +{ + if (!strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL))) { + uint64_t load_start, load_end; + + if (!get_crash_kernel_load_range(&load_start, &load_end) && + (load_start == start) && (load_end == end)) + return false; + + return true; + } + + if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) || + !strncmp(str, KERNEL_CODE, strlen(KERNEL_CODE)) || + !strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA))) + return false; + else + return true; +} + +int get_memory_ranges(struct memory_range **range, int *num_ranges, + unsigned long kexec_flags) +{ + struct memory_ranges sysmem_ranges = {0}; + const char *iomem = proc_iomem(); + struct memory_range excl_range; + unsigned long long start, end; + int consumed, count, ret = 0; + FILE *fp = NULL, *sp = NULL; + char line[MAX_LINE], *str; + + fp = fopen(iomem, "r"); + if (!fp) { + fprintf(stderr, "Cannot open %s: %s\n", iomem, strerror(errno)); + return -1; + } + + sp = fopen(iomem, "r"); + if (!sp) { + fprintf(stderr, "Cannot open %s: %s\n", iomem, strerror(errno)); + ret = -1; + goto err; + } + + /* + * Perform two passes: First add all System RAM, and then + * exclude the "Reserved" ranges" + */ + while (fgets(line, sizeof(line), fp) != 0) { + count = sscanf(line, "%llx-%llx : %n", &start, &end, &consumed); + if (count != 2) + continue; + str = line + consumed; + + if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM))) { + ret = mem_regions_alloc_and_add(&sysmem_ranges, + start, end - start + 1, RANGE_RAM); + if (ret) { + fprintf(stderr, + "Cannot allocate memory for ranges\n"); + ret = -ENOMEM; + goto err; + } + + } + } + + while (fgets(line, sizeof(line), sp) != 0) { + count = sscanf(line, "%llx-%llx : %n", &start, &end, &consumed); + if (count != 2) + continue; + str = line + consumed; + + if (to_be_excluded(str, start, end)) { + excl_range.start = start; + excl_range.end = end; + + ret = mem_regions_alloc_and_exclude(&sysmem_ranges, &excl_range); + if (ret) { + fprintf(stderr, + "Cannot allocate memory for ranges (exclude)\n"); + ret = -ENOMEM; + goto err; + } + } + } + + *range = sysmem_ranges.ranges; + *num_ranges = sysmem_ranges.size; + + dbgprint_mem_range("System RAM ranges;", + sysmem_ranges.ranges, sysmem_ranges.size); + + ret = 0; + err: + if (fp) + fclose(fp); + if (sp) + fclose(sp); + return ret; +} + +/*******\ +* STUBS * +\*******/ + +int arch_compat_trampoline(struct kexec_info *UNUSED(info)) +{ + return 0; +} + +void arch_update_purgatory(struct kexec_info *UNUSED(info)) +{ +} + +int arch_do_exclude_segment(struct kexec_info *UNUSED(info), struct kexec_segment *UNUSED(segment)) +{ + return 0; +} diff --git a/kexec/arch/riscv/kexec-riscv.h b/kexec/arch/riscv/kexec-riscv.h new file mode 100644 index 000000000000..c4323a65dacf --- /dev/null +++ b/kexec/arch/riscv/kexec-riscv.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2019 FORTH-ICS/CARV + * Nick Kossifidis + */ + +struct fdt_image { + char *buf; + off_t size; +}; + +struct riscv_opts { + char *cmdline; + char *fdt_path; + char *initrd_path; + uint64_t initrd_start; + uint64_t initrd_end; + struct fdt_image *fdt; +}; + +/* crashdump-riscv.c */ +extern struct memory_range elfcorehdr_mem; +int load_elfcorehdr(struct kexec_info *info); + +/* kexec-riscv.c */ +int load_extra_segments(struct kexec_info *info, uint64_t kernel_base, + uint64_t kernel_size, uint64_t max_addr); + +int elf_riscv_probe(const char *buf, off_t len); +void elf_riscv_usage(void); +int elf_riscv_load(int argc, char **argv, const char *buf, off_t len, + struct kexec_info *info); diff --git a/kexec/dt-ops.c b/kexec/dt-ops.c index 0a96b75f65aa..3e285ab2043b 100644 --- a/kexec/dt-ops.c +++ b/kexec/dt-ops.c @@ -4,9 +4,11 @@ #include #include #include +#include #include "kexec.h" #include "dt-ops.h" +#include "mem_regions.h" static const char n_chosen[] = "chosen"; @@ -95,7 +97,7 @@ int dtb_set_property(char **dtb, off_t *dtb_size, const char *node, strcpy(new_node, "/"); strcat(new_node, node); - + nodeoffset = fdt_path_offset(new_dtb, new_node); if (nodeoffset == -FDT_ERR_NOTFOUND) { @@ -174,3 +176,441 @@ int dtb_delete_property(char *dtb, const char *node, const char *prop) free(new_node); return result; } + +static int dtb_get_num_cells(char *dtb, int nodeoffset, uint32_t *addr_cells, + uint32_t *size_cells, bool recursive) +{ + const uint32_t *prop32 = NULL; + int curr_offset = nodeoffset; + int prop_len = 0; + *addr_cells = 0; + *size_cells = 0; + + do { + prop32 = fdt_getprop(dtb, curr_offset, "#address-cells", &prop_len); + curr_offset = fdt_parent_offset(dtb, curr_offset); + } while (!prop32 && prop_len == -FDT_ERR_NOTFOUND && recursive); + + if (!prop32) { + dbgprintf("Could not get #address-cells property for %s (%s)\n", + fdt_get_name(dtb, nodeoffset, NULL), fdt_strerror(nodeoffset)); + return -EINVAL; + } + *addr_cells = fdt32_to_cpu(*prop32); + + curr_offset = nodeoffset; + do { + prop32 = fdt_getprop(dtb, curr_offset, "#size-cells", &prop_len); + curr_offset = fdt_parent_offset(dtb, curr_offset); + } while (!prop32 && prop_len == -FDT_ERR_NOTFOUND && recursive); + + if (!prop32) { + dbgprintf("Could not get #size-cells property for %s (%s)\n", + fdt_get_name(dtb, nodeoffset, NULL), fdt_strerror(nodeoffset)); + return -EINVAL; + } + *size_cells = fdt32_to_cpu(*prop32); + + dbgprintf("%s: #address-cells:%d #size-cells:%d\n", + fdt_get_name(dtb, nodeoffset, NULL), *addr_cells, *size_cells); + + return 0; +} + +void dtb_extract_int_property(uint64_t *val, const void *buf, uint32_t cells) +{ + const uint32_t *prop32 = NULL; + const uint64_t *prop64 = NULL; + + if (cells == 1) { + prop32 = (const uint32_t *) buf; + *val = (uint64_t) be32_to_cpu(*prop32); + } else { + /* Skip any leading cells */ + prop64 = (const uint64_t *) (uint32_t *)buf + cells - 2; + *val = (uint64_t) be64_to_cpu(*prop64); + } +} + +void dtb_fill_int_property(void *buf, uint64_t val, uint32_t cells) +{ + uint32_t prop32 = 0; + uint64_t prop64 = 0; + + if (cells == 1) { + prop32 = cpu_to_fdt32((uint32_t) val); + memcpy(buf, &prop32, sizeof(uint32_t)); + } else { + prop64 = cpu_to_fdt64(val); + /* Skip any leading cells */ + memcpy((uint64_t *)(uint32_t *)buf + cells - 2, + &prop64, sizeof(uint64_t)); + } +} + +int dtb_add_range_property(char **dtb, off_t *dtb_size, uint64_t start, uint64_t end, + const char *parent, const char *name) +{ + uint32_t addr_cells = 0; + uint32_t size_cells = 0; + char *nodepath = NULL; + void *prop = NULL; + int nodeoffset = 0; + int prop_size = 0; + int ret = 0; + + nodepath = malloc(strlen("/") + strlen(parent) + 1); + if (!nodepath) { + dbgprintf("%s: malloc failed\n", __func__); + return -ENOMEM; + } + + strcpy(nodepath, "/"); + strcat(nodepath, parent); + + nodeoffset = fdt_path_offset(*dtb, nodepath); + if (nodeoffset < 0) { + dbgprintf("%s: fdt_path_offset(%s) failed: %s\n", __func__, + nodepath, fdt_strerror(nodeoffset)); + free(nodepath); + return nodeoffset; + } + free(nodepath); + + ret = dtb_get_num_cells(*dtb, nodeoffset, &addr_cells, &size_cells, true); + if (ret < 0) + return ret; + + /* Can the range fit with the given address/size cells ? */ + if ((addr_cells == 1) && (start >= (1ULL << 32))) + return -EINVAL; + + if ((size_cells == 1) && ((end - start + 1) >= (1ULL << 32))) + return -EINVAL; + + prop_size = sizeof(uint32_t) * (addr_cells + size_cells); + prop = malloc(prop_size); + + dtb_fill_int_property(prop, start, addr_cells); + dtb_fill_int_property((void *)((uint32_t *)prop + addr_cells), + end - start + 1, size_cells); + + /* Add by node path name */ + return dtb_set_property(dtb, dtb_size, parent, name, prop, prop_size); +} + +/************************\ +* MEMORY RANGES HANDLING * +\************************/ + +static int dtb_add_memory_range(struct memory_ranges *mem_ranges, uint64_t start, + uint64_t end, unsigned type) +{ + struct memory_range this_region = {0}; + struct memory_range *ranges = mem_ranges->ranges; + int i = 0; + int ret = 0; + + if (start == end) { + dbgprintf("Ignoring empty region\n"); + return -EINVAL; + } + + /* Check if we are adding an existing region */ + for (i = 0; i < mem_ranges->size; i++) { + if (start == ranges[i].start && end == ranges[i].end) { + dbgprintf("Duplicate: 0x%lx - 0x%lx\n", start, end); + + if (type == ranges[i].type) + return 0; + else if (type == RANGE_RESERVED) { + ranges[i].type = RANGE_RESERVED; + return 0; + } + + dbgprintf("Conflicting types for region: 0x%lx - 0x%lx\n", + start, end); + return -EINVAL; + } + } + + /* + * Reserved regions may be part of an existing /memory + * region and shouldn't overlap according to spec, so + * since we add /memory regions first, we can exclude + * reserved regions here from the existing /memory regions + * included in ranges[], so that we don't have the same + * region twice. + */ + if (type == RANGE_RESERVED) { + this_region.start = start; + this_region.end = end - 1; + this_region.type = type; + ret = mem_regions_exclude(mem_ranges, &this_region); + if (ret) + return ret; + } + + ret = mem_regions_alloc_and_add(mem_ranges, start, + end - start, type); + + return ret; +} + +static int dtb_add_memory_region(char *dtb, int nodeoffset, + struct memory_ranges *mem_ranges, int type) +{ + uint32_t root_addr_cells = 0; + uint32_t root_size_cells = 0; + uint64_t addr = 0; + uint64_t size = 0; + const char *reg = NULL; + int prop_size = 0; + int offset = 0; + int entry_size = 0; + int num_entries = 0; + int ret = 0; + + /* + * Get address-cells and size-cells properties (according to + * binding spec these are the same as in the root node) + */ + ret = dtb_get_num_cells(dtb, 0, &root_addr_cells, &root_size_cells, false); + if (ret < 0) { + dbgprintf("No address/size cells on root node !\n"); + return ret; + } + + /* + * Parse the reg array, acording to device tree spec it includes + * an arbitary number of
pairs + */ + entry_size = (root_addr_cells + root_size_cells) * sizeof(uint32_t); + reg = fdt_getprop(dtb, nodeoffset, "reg", &prop_size); + if (!reg) { + dbgprintf("Warning: Malformed memory region with no reg property (%s) !\n", + fdt_get_name(dtb, nodeoffset, NULL)); + return -EINVAL; + } + + num_entries = prop_size / entry_size; + dbgprintf("Got region with %i entries: %s\n", num_entries, + fdt_get_name(dtb, nodeoffset, NULL)); + + for (num_entries--; num_entries >= 0; num_entries--) { + offset = num_entries * entry_size; + + dtb_extract_int_property(&addr, reg + offset, + root_addr_cells); + offset += root_addr_cells * sizeof(uint32_t); + + dtb_extract_int_property(&size, reg + offset, + root_size_cells); + + ret = dtb_add_memory_range(mem_ranges, addr, + addr + size, type); + if (ret) + return ret; + } + + return 0; +} + +static int dtb_parse_memory_reservations_table(char *dtb, struct memory_ranges *mem_ranges) +{ + int total_memrsrv = 0; + uint64_t addr = 0; + uint64_t size = 0; + int ret = 0; + int i = 0; + + total_memrsrv = fdt_num_mem_rsv(dtb); + for (i = 0; i < total_memrsrv; i++) { + ret = fdt_get_mem_rsv(dtb, i, &addr, &size); + if (ret) + continue; + ret = dtb_add_memory_range(mem_ranges, addr, addr + size - 1, + RANGE_RESERVED); + if (ret) + return ret; + } + + return 0; +} + +static int dtb_get_reserved_memory_node(char *dtb) +{ + uint32_t root_addr_cells = 0; + uint32_t root_size_cells = 0; + uint32_t addr_cells = 0; + uint32_t size_cells = 0; + int prop_size = 0; + int nodeoffset = 0; + int ret = 0; + + /* Get address / size cells from root node */ + ret = dtb_get_num_cells(dtb, 0, &root_addr_cells, &root_size_cells, false); + if (ret < 0) { + dbgprintf("No address/size cells on root node !\n"); + return ret; + } + + /* This calls fdt_next_node internaly */ + nodeoffset = fdt_subnode_offset(dtb, 0, "reserved-memory"); + if (nodeoffset == -FDT_ERR_NOTFOUND) { + return nodeoffset; + } else if (nodeoffset < 0) { + dbgprintf("Error while looking for reserved-memory: %s\n", + fdt_strerror(nodeoffset)); + return nodeoffset; + } + + /* Look for the ranges property */ + fdt_getprop(dtb, nodeoffset, "ranges", &prop_size); + if (prop_size < 0) { + fprintf(stderr, "Malformed reserved-memory node (no ranges property) !\n"); + return -EINVAL; + } + + /* Verify address-cells / size-cells */ + ret = dtb_get_num_cells(dtb, nodeoffset, &addr_cells, &size_cells, false); + if (ret < 0) { + dbgprintf("No address/size cells property on reserved-memory node\n"); + return ret; + } + + if (addr_cells != root_addr_cells) { + fprintf(stderr, "Invalid #address-cells property on reserved-memory node\n"); + return -EINVAL; + } + + if (size_cells != root_size_cells) { + fprintf(stderr, "Invalid #size-cells property on reserved-memory node\n"); + return -EINVAL; + + } + + return nodeoffset; +} + +static int dtb_parse_reserved_memory_node(char *dtb, struct memory_ranges *mem_ranges) +{ + int nodeoffset = 0; + int node_depth = 0; + int parent_depth = 0; + int ret = 0; + + nodeoffset = dtb_get_reserved_memory_node(dtb); + if (nodeoffset == -FDT_ERR_NOTFOUND) + return 0; + else if (nodeoffset < 0) + return nodeoffset; + + /* Got the parent node, check for sub-nodes */ + + /* fdt_next_node() increases or decreases depth */ + node_depth = parent_depth; + nodeoffset = fdt_next_node(dtb, nodeoffset, &node_depth); + if (ret < 0) { + dbgprintf("Unable to get next node: %s\n", + fdt_strerror(ret)); + return -EINVAL; + } + + while (node_depth != parent_depth) { + + ret = dtb_add_memory_region(dtb, nodeoffset, + mem_ranges, RANGE_RESERVED); + if (ret) + return ret; + + nodeoffset = fdt_next_node(dtb, nodeoffset, &node_depth); + if (ret < 0) { + dbgprintf("Unable to get next node: %s\n", + fdt_strerror(ret)); + return -EINVAL; + } + } + + return 0; +} + +static int dtb_parse_memory_nodes(char *dtb, struct memory_ranges *mem_ranges) +{ + int nodeoffset = 0; + int num_regions = 0; + const char* dev_type = 0; + int prop_size = 0; + int ret = 0; + + for (; ; num_regions++) { + nodeoffset = fdt_subnode_offset(dtb, nodeoffset, + "memory"); + if (nodeoffset < 0) + break; + + dbgprintf("Got memory node at depth: %i\n", fdt_node_depth(dtb, nodeoffset)); + + /* Look for the device_type property */ + dev_type = fdt_getprop(dtb, nodeoffset, "device_type", &prop_size); + if (prop_size < 0) { + fprintf(stderr, "Malformed /memory node (no device-type property) !\n"); + return -EINVAL; + } + + if (strncmp(dev_type, "memory", prop_size)) { + dbgprintf("Got unknown dev_type property: %s\n", dev_type); + continue; + } + + ret = dtb_add_memory_region(dtb, nodeoffset, mem_ranges, RANGE_RAM); + if (ret) + return ret; + } + + if (!num_regions) { + dbgprintf("Malformed dtb, no /memory nodes present !\n"); + return -EINVAL; + } + + dbgprintf("Got %i /memory nodes\n", num_regions); + + return 0; +} + +int dtb_get_memory_ranges(char *dtb, struct memory_ranges *mem_ranges, struct memory_ranges *extra_ranges) +{ + int i = 0; + int ret = 0; + + /* Fill mem_ranges[] by parsing the device tree */ + ret = dtb_parse_memory_nodes(dtb, mem_ranges); + if (ret) + return ret; + + ret = dtb_parse_memory_reservations_table(dtb, mem_ranges); + if (ret) + return ret; + + ret = dtb_parse_reserved_memory_node(dtb, mem_ranges); + if (ret) + return ret; + + /* Append any extra ranges provided by the caller (e.g. initrd) */ + for (i = 0; extra_ranges != NULL && i < extra_ranges->size; i++) { + dbgprintf("Adding extra range: 0x%llx - 0x%llx (%s)\n", + extra_ranges->ranges[i].start, + extra_ranges->ranges[i].end, + extra_ranges->ranges[i].type == RANGE_RESERVED ? + "RANGE_RESERVED" : "RANGE_RAM"); + + ret = dtb_add_memory_range(mem_ranges, extra_ranges->ranges[i].start, + extra_ranges->ranges[i].end, extra_ranges->ranges[i].type); + if (ret) + return ret; + } + + mem_regions_sort(mem_ranges); + + return 0; +} diff --git a/kexec/dt-ops.h b/kexec/dt-ops.h index 03659ce283db..3014205d8e98 100644 --- a/kexec/dt-ops.h +++ b/kexec/dt-ops.h @@ -11,4 +11,11 @@ int dtb_set_property(char **dtb, off_t *dtb_size, const char *node, int dtb_delete_property(char *dtb, const char *node, const char *prop); +void dtb_extract_int_property(uint64_t *val, const void *buf, uint32_t cells); +void dtb_fill_int_property(void *buf, uint64_t val, uint32_t cells); +int dtb_add_range_property(char **dtb, off_t *dtb_size, uint64_t start, uint64_t end, + const char *node, const char* parent); +int dtb_get_memory_ranges(char *dtb, struct memory_ranges *mem_ranges, + struct memory_ranges *extra_ranges); + #endif diff --git a/kexec/kexec-syscall.h b/kexec/kexec-syscall.h index cc32c0162aec..89591ad17e7d 100644 --- a/kexec/kexec-syscall.h +++ b/kexec/kexec-syscall.h @@ -140,6 +140,7 @@ static inline long kexec_file_load(int kernel_fd, int initrd_fd, #define KEXEC_ARCH_MIPS_LE (10 << 16) #define KEXEC_ARCH_MIPS ( 8 << 16) #define KEXEC_ARCH_CRIS (76 << 16) +#define KEXEC_ARCH_RISCV (243 << 16) #define KEXEC_ARCH_LOONGARCH (258 << 16) #define KEXEC_MAX_SEGMENTS 16 @@ -187,5 +188,8 @@ static inline long kexec_file_load(int kernel_fd, int initrd_fd, #if defined(__loongarch__) #define KEXEC_ARCH_NATIVE KEXEC_ARCH_LOONGARCH #endif +#if defined(__riscv__) || defined(__riscv) +#define KEXEC_ARCH_NATIVE KEXEC_ARCH_RISCV +#endif #endif /* KEXEC_SYSCALL_H */ diff --git a/purgatory/Makefile b/purgatory/Makefile index 4d2d07134bd5..7d1175f2445c 100644 --- a/purgatory/Makefile +++ b/purgatory/Makefile @@ -25,6 +25,7 @@ include $(srcdir)/purgatory/arch/ia64/Makefile include $(srcdir)/purgatory/arch/mips/Makefile include $(srcdir)/purgatory/arch/ppc/Makefile include $(srcdir)/purgatory/arch/ppc64/Makefile +include $(srcdir)/purgatory/arch/riscv/Makefile include $(srcdir)/purgatory/arch/s390/Makefile include $(srcdir)/purgatory/arch/sh/Makefile include $(srcdir)/purgatory/arch/x86_64/Makefile diff --git a/purgatory/arch/riscv/Makefile b/purgatory/arch/riscv/Makefile new file mode 100644 index 000000000000..49a6fef4a904 --- /dev/null +++ b/purgatory/arch/riscv/Makefile @@ -0,0 +1,7 @@ +# +# Purgatory riscv +# + +riscv_PURGATORY_SRCS = + +dist += purgatory/arch/riscv/Makefile $(riscv_PURGATORY_SRCS) -- 2.45.2 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 9C096C369A6 for ; Wed, 9 Apr 2025 20:14:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=X9Pk1ufdKj8GQD3IckA458d3z+cIyh++uv/PI7sPOOM=; b=OrEafHNeXsvfkQ BRV/Eu38CqrTAJ5eMlgMRV3pD1RQau/HoeEcBQjpAarAuQG3MQqYZs12p55XEVK17XA3fFrjGb33b f5dP6T+U51JufZA8av5Voefx08cHOKEJxVXvJ6doPDARtVXJZuanzPGM9cEL3VU30aSLqYWOAfTkF CGHhkN5vszpLrwScnPYn2CZJmWf+5U67HeX/HawPWz0CrS+qFuczWVavHENhTvQUkQHzEkeOijNVw XmCpgMRcNT4EdR82CUmESsMeapDxTbv3kdElwGE7OMVJ/db3RP74j7bpCelk5oQNdoqIphtRBkM77 FfrygcU7hdVX9Ia0Fodg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1u2box-00000008PIs-3Euv; Wed, 09 Apr 2025 20:14:51 +0000 Received: from nyc.source.kernel.org ([147.75.193.91]) by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) id 1u2bou-00000008PGm-4B5x; Wed, 09 Apr 2025 20:14:51 +0000 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by nyc.source.kernel.org (Postfix) with ESMTP id 40F0FA48618; Wed, 9 Apr 2025 20:09:19 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 062F8C4CEE2; Wed, 9 Apr 2025 20:14:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1744229687; bh=XGWQ22s+RUjd5KmvBFM6Iqn5Ss0EmY1LQjC9nWMaoJY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lUzyGmeWATJpa5UY4zuoX/lgQWI01ocY8aWn6TJCAyqJNHQ/pfkTjRVjA/vA2a9PM xTSuEs4KNqEwcYCQ0SjDa+MADaJxckjhRF4Yv7oFCgx0FUdnuOicLAOLGUr/xADIeR Yrww//q791ecj+pduAv+5wXW1HrH2DdVvaAfUPJT+3cWuVjDk0WQfIzzRtXvfHbt9z mWhegxsiEU03Ew5JLSeHBAUTxJBvwRzvILIxBnCvfXjEJmfe4oJeVwJkUz/h117ZNu 8rllWDrXvagNRGSCZzXOiKHZPQGk0w71K0VMn+ZqdoZ5dgK1+JxibMb4KucTcp6IRh AkzPA5e/qQmjA== From: =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= To: Simon Horman , Simon Horman , Nick Kossifidis , Song Shuai , Li Zhengyu , kexec@lists.infradead.org Cc: Dave Young , Yixun Lan , Xianting Tian , linux-riscv@lists.infradead.org, =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= Subject: [PATCH 1/4] RISC-V: Add support for riscv kexec/kdump on kexec-tools Date: Wed, 9 Apr 2025 22:14:23 +0200 Message-ID: <20250409201428.648717-2-bjorn@kernel.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250409201428.648717-1-bjorn@kernel.org> References: <20250409201428.648717-1-bjorn@kernel.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250409_131449_278147_B834163E X-CRM114-Status: GOOD ( 39.24 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org RnJvbTogTmljayBLb3NzaWZpZGlzIDxtaWNrQGljcy5mb3J0aC5ncj4KClRoaXMgcGF0Y2ggYWRk cyBzdXBwb3J0IGZvciBsb2FkaW5nIHRoZSBFTEYga2VybmVsIGltYWdlLiBJdCBwYXJzZXMKdGhl IGN1cnJlbnQvcHJvdmlkZWQgZGV2aWNlIHRyZWUgdG8gZGV0ZXJtaW5lIHRoZSBzeXN0ZW0ncyBt ZW1vcnkKbGF5b3V0LCBhbmQgL3Byb2MvaW9tZW0gZm9yIHRoZSB2YXJpb3VzIGtlcm5lbCBzZWdt ZW50cy4KClRlc3RlZCBvbiBRZW11J3MgcnY2NCB2aXJ0IG1hY2hpbmUgYW5kIFNvQyBvZiBULUhl YWQgUklTQy1WIFh1YW50aWUKOTEwIENQVS4KCk5vdywgc29tZSBoaXN0b3J5OiBUaGUgZmlyc3Qg c3RhYiBhdCBzdXBwb3J0aW5nIGtleGVjLXRvb2xzIG9uIFJJU0MtVgp3YXMgZG9uZSBieSBOaWNr IEtvc3NpZmlkaXMuIFRoZSBpbml0aWFsIHBhdGNoIGhhcyBzaW5jZSB0aGVuIGhhZCBhCm51bWJl ciBvZiBpbXByb3ZlbWVudHMvZml4ZXMgYnkgb3RoZXIgYXV0aG9ycy4gR2l2ZW4sIHRoaXMgaXMg dGhlCmZpcnN0IGNvbW1pdCBmb3IgUklTQy1WLCBjYXJyeWluZyB0aGUgZml4ZXMvY2hhbmdlcyBj b21taXRzIGluIHRoZQp1cHN0cmVhbSB0cmVlIGRvZXMgbm90IHJlYWxseSBhZGQgYW55dGhpbmcg KGJpc2VjdGFiaWxpdHkpLgoKSW5zdGVhZCBhbGwgdGhlIGZpeGVzIHRoYXQgd2VyZSBhcHBsaWVk IHRvIE5pY2sncyBmaXJzdCBjb21taXQgaXMKb3V0bGluZWQgYmVsb3c6CgpZaXh1biBMYW4sIGFu ZCBYaWFudGluZyBUaWFuOgogICogRml4ZWQgYSBmYWlsdXJlIHRvIGZhaWwgdG8gZmluZCBmcmVl IG1lbW9yeSBhcmVhIGZvciBkdGIgbG9hZCB3aGVuCiAgICB1c2luZyBpbml0cmQgaW1hZ2UgWzFd LgogICogRml4ZWQgbWVtb3J5IHJhbmdlIHNpemUgY2FsY3VsYXRpb24gaW4KICAgIGtleGVjL2Fy Y2gvcmlzY3YvY3Jhc2hkdW1wLXJpc2N2LmM6ODUKClNpbW9uIEhvcm1hbjoKICAqIFJJU0MtVjog ZGlzdHJpYnV0ZSBwdXJnYXRvcnkvcmlzY3YvTWFrZWZpbGUKCiAgICBJbmNsdWRlIHB1cmdhdG9y eS9yaXNjdi9NYWtlZmlsZSBpbiBkaXN0cmlidXRpb24gdGFyYmFsbC4KCiAgICBMb2NhbCBwYXRj aCBhcyBpdCBpcyBwbGFubmVkIHRvIHN1Z2dlc3QgdGhpcyBhcyBhIGZpeCBmb3IgdGhlCiAgICBw YXRjaCB0aGF0IGludHJvZHVjZWQgdGhpcyBwcm9ibGVtLiBbMl0KClNvbmcgU2h1YWk6CiAgKiBS SVNDLVY6IEZpeCB0aGUgdW5kZWNsYXJlZCDigJhFTV9SSVNDVuKAmSBidWlsZCBmYWlsdXJlCgog ICAgVXNlIGxvY2FsIGBlbGYuaGAgaW5zdGVhZCBvZiBgbGludXgvZWxmLmhgIHRvIGZpeCB0aGlz IGJ1aWxkCiAgICBlcnJvcjoKCiAgICBgYGAKICAgIGtleGVjL2FyY2gvcmlzY3YvY3Jhc2hkdW1w LXJpc2N2LmM6MTc6MTM6IGVycm9yOiDigJhFTV9SSVNDVuKAmSB1bmRlY2xhcmVkIGhlcmUgKG5v dCBpbiBhIGZ1bmN0aW9uKTsgZGlkIHlvdSBtZWFuIOKAmEVNX0NSSVPigJk/CiAgICAgIC5tYWNo aW5lID0gRU1fUklTQ1YsCiAgICAgICAgICAgICAgICAgXn5+fn5+fn4KICAgICAgICAgICAgICAg ICBFTV9DUklTCiAgICBgYGAKCiAgKiBSSVNDLVY6IENvcnJlY3QgdGhlIHVzYWdlIG9mIGNvbW1h bmQgbGluZSBvcHRpb24KCiAgICBSSVNDLVYgcHJvY2VzcyBPUFRfQ01ETElORSB3aXRoIHRoZSAi Y29tbWFuZC1saW5lIiBwYXJ0dGVuLCBidXQKICAgIHRoZSByaXNjdl9vcHRzX3VzYWdlIHNob3dz IHRoZSAiY21kbGluZSIgb3B0aW9uLiBTbyBjb3JyZWN0IHRoZQogICAgdXNhZ2UncyBvdXRwdXQu CgogICogUklTQy1WOiBVc2UgbGludXgsdXNhYmxlLW1lbW9yeS1yYW5nZSBmb3IgY3Jhc2gga2Vy bmVsCgogICAgTm93IHdlIHVzZSAibWVtZW9yeTo6bGludXgsdXNhYmxlLW1lbW9yeSIgdG8gaW5k aWNhdGUgdGhlCiAgICBhdmFpbGFibGUgbWVtb3J5IGZvciB0aGUgY3Jhc2gga2VybmVsLgoKICAg IFdoaWxlIGJvb3Rpbmcgd2l0aCBVRUZJLCB0aGUgY3Jhc2gga2VybmVsIHdvdWxkIHVzZSBlZmku bWVtbWFwIHRvCiAgICByZS1wb3B1bGF0ZSBtZW1ibG9jayBhbmQgdGhlbiBmaXJzdCBrZXJuZWwn cyBtZW1vcnkgd291bGQgYmUKICAgIGNvcnJwdXRlZC4gQ29uc2VxdWVudGx5LCB0aGUgL3Byb2Mv dm1jb3JlIGZpbGUgZmFpbGVkIHRvIGNyZWF0ZSBpbgogICAgbXkgbG9jYWwgdGVzdC4KCiAgICBB bmQgYWNjb3JkaW5nIHRvICJjaG9zZW4iIGR0c2NoZW1hIFszXSwgdGhlIGF2YWlsYWJsZSBtZW1v cnkgZm9yCiAgICB0aGUgY3Jhc2gga2VybmVsIHNob3VsZCBiZSBoZWxkIHZpYQogICAgImNob3Nl bjo6bGludXgsdXNhYmxlLW1lbW9yeS1yYW5nZSIgcHJvcGVydHkgd2hpY2ggd2lsbCByZS1jYXAK ICAgIG1lbWJsb2NrIGV2ZW4gYWZ0ZXIgVUVGSSdzIHJlLXBvcHVsYXRpb24uCgogICogUklTQy1W OiBHZXQgbWVtb3J5IHJhbmdlcyBmcm9tIGlvbWVtCgogICAgV2hlbiBib290aW5nIHdpdGggVUVG SSwgTGludXggbWFya3MgdGhlIFJ1bnRpbWUgQ29kZS9EYXRhIG1lbW9yeQogICAgYXMgbm8tbWFw IGFuZCB0aGVuIGV4cG9ydHMgaXQgdG8gIlJlc2VydmVkIiBpb21lbV9yZXNvdXJjZS4KCiAgICBL ZXhjLXRvb2xzIHVzZXMgZHRiX2dldF9tZW1vcnlfcmFuZ2VzKCkgZnVuY3Rpb24gdG8gZ2V0IG1l bW9yeQogICAgcmFuZ2VzIHZpYSBwYXJzaW5nIGR0YiwgYnV0IGl0IGNhbid0IHNlZSB0aGUgUmVz ZXJ2ZWQgRUZJIFJ1bnRpbWUKICAgIG1lbW9yeS4gVGhhdCB3b3VsZCBjb3JydXB0IEVGSSBSdW50 aW1lIG1lbW9yeSBhbmQgZmFpbCB0aGUga2V4ZWNlZAogICAga2VybmVsIHRvIGRlYWwgRUZJIHN0 dWZmLgoKICAgIEluIG15IHRlc3QsIHRoZSBrZXhlY2VkIGtlcm5lbCB3YXJuZWQgImVmaTogU3lz dGVtIHRhYmxlIHNpZ25hdHVyZQogICAgaW5jb3JyZWN0ISIgYW5kIHRoZW4gcGFuaWNlZCBhdCBl ZmlfY2FsbF9ydHMoKSBkdWUgdG8gdGhlIG51bGwKICAgIGVmaS5ydW50aW1lLgoKICAgIFNvIHdl IHNob3VsZCB1c2UgL3Byb2MvaW9tZW0gdG8gZ2V0IG1lbW9yeSByYW5nZXMuCgpCasO2cm4gVMO2 cGVsOgogICogTWFzc2FnZWQgdGhpcyBjb21taXQgbWVzc2FnZSEKICAqIEZpeGVkIHVwIHRoZSBi dWlsZCwgYnkgYWRkaW5nIG1pc3NpbmcgUlYgc3R1Yi4KICAqIFJJU0MtVjogT25seSBjYXAgdGhl IHVwcGVyL2VuZCB1c2FibGUgbWVtb3J5IHdpbmRvdwoKICAgIFdoZW4gbG9hZGluZyB0aGUgaW5p dHJkIGluIHRoZSBrZXhlY19sb2FkIGZsb3csIG1lbW9yeSBmb3IgdGhlCiAgICBzZWdtZW50cyBh cmUgc2VhcmNoZWQgZnJvbSBlbmQgdG8gc3RhcnQuIE9ubHkgdGhlIG1heF91c2FibGUKICAgIHNo b3VsZCBiZSBjYXBwZWQsIGFmdGVyIGEgc3VjY2Vzc2Z1bCBpbml0cmQgYWRkdGlvbi4KCiAgICBD dXJyZW50bHkgbWluL21heCB1c2FibGUgaXMgc2V0IHRvIHRoZSBzYW1lIHZhbHVlLCBtYWtpbmcg aXQKICAgIGltcG9zc2libGUgZnJvbSBzdWJzZXF1ZW50IHNlZ21lbnQgYWxsb2NhdGlvbnMgdG8g c3VjY2Vzcy4KCiAgKiBSSVNDLVY6IE1ha2UgZ2V0X21lbW9yeV9yYW5nZXMoKSBwcm9wZXJseSBl eGNsdWRlICJSZXNlcnZlZCIKICAgIHJlZ2lvbnMKCiAgICBUaGUgZ2V0X21lbW9yeV9yYW5nZXMo KSBkaWQgbm90IGV4Y2x1ZGUgIlJlc2VydmVkIiByZWdpb25zIGZyb20KICAgICJTeXN0ZW0gUkFN IiByZWdpb25zLiBJdCBzaW1wbHkgYWRkZWQgIlJlc2VydmVkIiBhcyBJT01FTSwgYW5kCiAgICBJ T01FTSBpcyBub3QgY29uc2lkZXJlZCB3aGVuIGxvb2tpbmcgZm9yIGhvbGVzIHRvIHBsYWNlIGtl eGVjCiAgICBzZWdtZW50cy4KCiAgICBJbnN0ZWFkLCBkbyBhIHR3byBwYXNzIG9mIHRoZSAvcHJv Yy9pb21lbSBmaWxlLiBGaXJzdCBwYXNzLCBhZGRzCiAgICBhbGwgdGhlICJTeXN0ZW0gUkFNIiBt ZW1vcnksIGFuZCB0aGUgc2Vjb25kIHBhc3MgcmVtb3ZlcyBhbGwKICAgIGludGVyc2VjdGluZyAi UmVzZXJ2ZWQiIHJlZ2lvbnMuCgpbMV0gaHR0cHM6Ly9sb3JlLmtlcm5lbC5vcmcvbGludXgtcmlz Y3YvQ0FMZWNUNWdRV24wUFJPNFEyNGI2cWtyZlZFNU94c0NwNjVUdWhXVGIzMGNlS19PSjBBQG1h aWwuZ21haWwuY29tLwpbMl0gaHR0cHM6Ly9sb3JlLmtlcm5lbC5vcmcva2V4ZWMvMjAyMjEwMjAw MzE1NDguNDc1ODctMS14aWFudGluZy50aWFuQGxpbnV4LmFsaWJhYmEuY29tLwpbM10gaHR0cHM6 Ly9naXRodWIuY29tL2RldmljZXRyZWUtb3JnL2R0LXNjaGVtYS9ibG9iL21haW4vZHRzY2hlbWEv c2NoZW1hcy9jaG9zZW4ueWFtbAoKVGVzdGVkLWJ5OiBZaXh1biBMYW4gPHlpeHVuLmxhbkBnbWFp bC5jb20+CkNvLWRldmVsb3BlZC1ieTogWGlhbnRpbmcgVGlhbiA8eGlhbnRpbmcudGlhbkBsaW51 eC5hbGliYWJhLmNvbT4KQ28tZGV2ZWxvcGVkLWJ5OiBZaXh1biBMYW4gPHlpeHVuLmxhbkBnbWFp bC5jb20+ClNpZ25lZC1vZmYtYnk6IE5pY2sgS29zc2lmaWRpcyA8bWlja0BpY3MuZm9ydGguZ3I+ ClNpZ25lZC1vZmYtYnk6IFNpbW9uIEhvcm1hbiA8aG9ybXNAa2VybmVsLm9yZz4KU2lnbmVkLW9m Zi1ieTogU29uZyBTaHVhaSA8c29uZ3NodWFpc2h1YWlAdGlueWxhYi5vcmc+ClNpZ25lZC1vZmYt Ynk6IEJqw7ZybiBUw7ZwZWwgPGJqb3JuQHJpdm9zaW5jLmNvbT4KLS0tCiBjb25maWd1cmUuYWMg ICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIDMgKwogaW5jbHVkZS9lbGYuaCAgICAgICAg ICAgICAgICAgICAgICAgICAgIHwgICAxICsKIGtleGVjL01ha2VmaWxlICAgICAgICAgICAgICAg ICAgICAgICAgICB8ICAgMSArCiBrZXhlYy9hcmNoL3Jpc2N2L01ha2VmaWxlICAgICAgICAgICAg ICAgfCAgMzUgKysKIGtleGVjL2FyY2gvcmlzY3YvY3Jhc2hkdW1wLXJpc2N2LmMgICAgICB8IDE0 MCArKysrKysrKwoga2V4ZWMvYXJjaC9yaXNjdi9pbmNsdWRlL2FyY2gvb3B0aW9ucy5oIHwgIDQz ICsrKwoga2V4ZWMvYXJjaC9yaXNjdi9pb21lbS5oICAgICAgICAgICAgICAgIHwgIDEwICsKIGtl eGVjL2FyY2gvcmlzY3Yva2V4ZWMtZWxmLXJpc2N2LmMgICAgICB8IDI1NSArKysrKysrKysrKysr Kwoga2V4ZWMvYXJjaC9yaXNjdi9rZXhlYy1yaXNjdi5jICAgICAgICAgIHwgNDMxICsrKysrKysr KysrKysrKysrKysrKysrCiBrZXhlYy9hcmNoL3Jpc2N2L2tleGVjLXJpc2N2LmggICAgICAgICAg fCAgMzIgKysKIGtleGVjL2R0LW9wcy5jICAgICAgICAgICAgICAgICAgICAgICAgICB8IDQ0MiAr KysrKysrKysrKysrKysrKysrKysrKy0KIGtleGVjL2R0LW9wcy5oICAgICAgICAgICAgICAgICAg ICAgICAgICB8ICAgNyArCiBrZXhlYy9rZXhlYy1zeXNjYWxsLmggICAgICAgICAgICAgICAgICAg fCAgIDQgKwogcHVyZ2F0b3J5L01ha2VmaWxlICAgICAgICAgICAgICAgICAgICAgIHwgICAxICsK IHB1cmdhdG9yeS9hcmNoL3Jpc2N2L01ha2VmaWxlICAgICAgICAgICB8ICAgNyArCiAxNSBmaWxl cyBjaGFuZ2VkLCAxNDExIGluc2VydGlvbnMoKyksIDEgZGVsZXRpb24oLSkKIGNyZWF0ZSBtb2Rl IDEwMDY0NCBrZXhlYy9hcmNoL3Jpc2N2L01ha2VmaWxlCiBjcmVhdGUgbW9kZSAxMDA2NDQga2V4 ZWMvYXJjaC9yaXNjdi9jcmFzaGR1bXAtcmlzY3YuYwogY3JlYXRlIG1vZGUgMTAwNjQ0IGtleGVj L2FyY2gvcmlzY3YvaW5jbHVkZS9hcmNoL29wdGlvbnMuaAogY3JlYXRlIG1vZGUgMTAwNjQ0IGtl eGVjL2FyY2gvcmlzY3YvaW9tZW0uaAogY3JlYXRlIG1vZGUgMTAwNjQ0IGtleGVjL2FyY2gvcmlz Y3Yva2V4ZWMtZWxmLXJpc2N2LmMKIGNyZWF0ZSBtb2RlIDEwMDY0NCBrZXhlYy9hcmNoL3Jpc2N2 L2tleGVjLXJpc2N2LmMKIGNyZWF0ZSBtb2RlIDEwMDY0NCBrZXhlYy9hcmNoL3Jpc2N2L2tleGVj LXJpc2N2LmgKIGNyZWF0ZSBtb2RlIDEwMDY0NCBwdXJnYXRvcnkvYXJjaC9yaXNjdi9NYWtlZmls ZQoKZGlmZiAtLWdpdCBhL2NvbmZpZ3VyZS5hYyBiL2NvbmZpZ3VyZS5hYwppbmRleCA0M2NkYjY0 YmM5MWIuLmZhOTZkMTc4MmY0ZiAxMDA2NDQKLS0tIGEvY29uZmlndXJlLmFjCisrKyBiL2NvbmZp Z3VyZS5hYwpAQCAtNjEsNiArNjEsOSBAQCBjYXNlICR0YXJnZXRfY3B1IGluCiAJbG9vbmdhcmNo KikKIAkJQVJDSD0ibG9vbmdhcmNoIgogCQk7OworCXJpc2N2MzJ8cmlzY3Y2NCkKKwkJQVJDSD0i cmlzY3YiCisJCTs7CiAJKiApCiAJCUFDX01TR19FUlJPUihbdW5zdXBwb3J0ZWQgYXJjaGl0ZWN0 dXJlICR0YXJnZXRfY3B1XSkKIAkJOzsKZGlmZiAtLWdpdCBhL2luY2x1ZGUvZWxmLmggYi9pbmNs dWRlL2VsZi5oCmluZGV4IDFjOGQyY2NmNmQyNi4uOTNhNWVlNWVlZmZhIDEwMDY0NAotLS0gYS9p bmNsdWRlL2VsZi5oCisrKyBiL2luY2x1ZGUvZWxmLmgKQEAgLTI1OSw2ICsyNTksNyBAQCB0eXBl ZGVmIHN0cnVjdAogI2RlZmluZSBFTV9BUkNfQTUJOTMJCS8qIEFSQyBDb3JlcyBUYW5nZW50LUE1 ICovCiAjZGVmaW5lIEVNX1hURU5TQQk5NAkJLyogVGVuc2lsaWNhIFh0ZW5zYSBBcmNoaXRlY3R1 cmUgKi8KICNkZWZpbmUgRU1fQUFSQ0g2NAkxODMJCS8qIEFSTSBBQVJDSDY0ICovCisjZGVmaW5l IEVNX1JJU0NWCTI0MwkJLyogUklTQy1WICovCiAjZGVmaW5lIEVNX0xPT05HQVJDSAkyNTgJCS8q IExvb25nc29uIExvb25nYXJjaCovCiAjZGVmaW5lIEVNX05VTQkJMTg0CiAKZGlmZiAtLWdpdCBh L2tleGVjL01ha2VmaWxlIGIva2V4ZWMvTWFrZWZpbGUKaW5kZXggZTk2OWQxZTE4YzVhLi44YjU4 NTFkZWNhZWEgMTAwNjQ0Ci0tLSBhL2tleGVjL01ha2VmaWxlCisrKyBiL2tleGVjL01ha2VmaWxl CkBAIC05Miw2ICs5Miw3IEBAIGluY2x1ZGUgJChzcmNkaXIpL2tleGVjL2FyY2gvbWlwcy9NYWtl ZmlsZQogaW5jbHVkZSAkKHNyY2Rpcikva2V4ZWMvYXJjaC9jcmlzL01ha2VmaWxlCiBpbmNsdWRl ICQoc3JjZGlyKS9rZXhlYy9hcmNoL3BwYy9NYWtlZmlsZQogaW5jbHVkZSAkKHNyY2Rpcikva2V4 ZWMvYXJjaC9wcGM2NC9NYWtlZmlsZQoraW5jbHVkZSAkKHNyY2Rpcikva2V4ZWMvYXJjaC9yaXNj di9NYWtlZmlsZQogaW5jbHVkZSAkKHNyY2Rpcikva2V4ZWMvYXJjaC9zMzkwL01ha2VmaWxlCiBp bmNsdWRlICQoc3JjZGlyKS9rZXhlYy9hcmNoL3NoL01ha2VmaWxlCiBpbmNsdWRlICQoc3JjZGly KS9rZXhlYy9hcmNoL3g4Nl82NC9NYWtlZmlsZQpkaWZmIC0tZ2l0IGEva2V4ZWMvYXJjaC9yaXNj di9NYWtlZmlsZSBiL2tleGVjL2FyY2gvcmlzY3YvTWFrZWZpbGUKbmV3IGZpbGUgbW9kZSAxMDA2 NDQKaW5kZXggMDAwMDAwMDAwMDAwLi5mMjZjYzkwMjVlNzcKLS0tIC9kZXYvbnVsbAorKysgYi9r ZXhlYy9hcmNoL3Jpc2N2L01ha2VmaWxlCkBAIC0wLDAgKzEsMzUgQEAKKyMKKyMga2V4ZWMgcmlz Y3YKKyMKK3Jpc2N2X0tFWEVDX1NSQ1MgPSAga2V4ZWMvYXJjaC9yaXNjdi9rZXhlYy1yaXNjdi5j CityaXNjdl9LRVhFQ19TUkNTICs9IGtleGVjL2FyY2gvcmlzY3Yva2V4ZWMtZWxmLXJpc2N2LmMK K3Jpc2N2X0tFWEVDX1NSQ1MgKz0ga2V4ZWMvYXJjaC9yaXNjdi9jcmFzaGR1bXAtcmlzY3YuYwor CityaXNjdl9NRU1fUkVHSU9OUyA9IGtleGVjL21lbV9yZWdpb25zLmMKKworcmlzY3ZfRFRfT1BT ICs9IGtleGVjL2R0LW9wcy5jCisKK3Jpc2N2X0FSQ0hfUkVVU0VfSU5JVFJEID0KKworcmlzY3Zf Q1BQRkxBR1MgKz0gLUkgJChzcmNkaXIpL2tleGVjLworCitkaXN0ICs9IGtleGVjL2FyY2gvcmlz Y3YvTWFrZWZpbGUgJChyaXNjdl9LRVhFQ19TUkNTKQkJCVwKKwlrZXhlYy9hcmNoL3Jpc2N2L2tl eGVjLXJpc2N2LmgJCQkJCVwKKwlrZXhlYy9hcmNoL3Jpc2N2L2luY2x1ZGUvYXJjaC9vcHRpb25z LmgKKworaWZkZWYgSEFWRV9MSUJGRFQKKworTElCUyArPSAtbGZkdAorCitlbHNlCisKK2luY2x1 ZGUgJChzcmNkaXIpL2tleGVjL2xpYmZkdC9NYWtlZmlsZS5saWJmZHQKKworbGliZmR0X1NSQ1Mg Kz0gJChMSUJGRFRfU1JDUzolPWtleGVjL2xpYmZkdC8lKQorCityaXNjdl9DUFBGTEFHUyArPSAt SSQoc3JjZGlyKS9rZXhlYy9saWJmZHQKKworcmlzY3ZfS0VYRUNfU1JDUyArPSAkKGxpYmZkdF9T UkNTKQorCitlbmRpZgorCmRpZmYgLS1naXQgYS9rZXhlYy9hcmNoL3Jpc2N2L2NyYXNoZHVtcC1y aXNjdi5jIGIva2V4ZWMvYXJjaC9yaXNjdi9jcmFzaGR1bXAtcmlzY3YuYwpuZXcgZmlsZSBtb2Rl IDEwMDY0NAppbmRleCAwMDAwMDAwMDAwMDAuLjMzNmQ3YTdmNTY0NgotLS0gL2Rldi9udWxsCisr KyBiL2tleGVjL2FyY2gvcmlzY3YvY3Jhc2hkdW1wLXJpc2N2LmMKQEAgLTAsMCArMSwxNDAgQEAK KyNpbmNsdWRlIDxlcnJuby5oPgorI2luY2x1ZGUgPGVsZi5oPgorI2luY2x1ZGUgPHVuaXN0ZC5o PgorCisjaW5jbHVkZSAia2V4ZWMuaCIKKyNpbmNsdWRlICJjcmFzaGR1bXAuaCIKKyNpbmNsdWRl ICJrZXhlYy1lbGYuaCIKKyNpbmNsdWRlICJtZW1fcmVnaW9ucy5oIgorCitzdGF0aWMgc3RydWN0 IGNyYXNoX2VsZl9pbmZvIGVsZl9pbmZvID0geworI2lmIF9fcmlzY3ZfeGxlbiA9PSA2NAorCS5j bGFzcwkJPSBFTEZDTEFTUzY0LAorI2Vsc2UKKwkuY2xhc3MJCT0gRUxGQ0xBU1MzMiwKKyNlbmRp ZgorCS5kYXRhCQk9IEVMRkRBVEEyTFNCLAorCS5tYWNoaW5lCT0gRU1fUklTQ1YsCit9OworCitz dGF0aWMgc3RydWN0IG1lbW9yeV9yYW5nZXMgY3Jhc2hfbWVtX3JhbmdlcyA9IHswfTsKK3N0cnVj dCBtZW1vcnlfcmFuZ2UgZWxmY29yZWhkcl9tZW0gPSB7MH07CisKK3N0YXRpYyB1bnNpZ25lZCBs b25nIGxvbmcgZ2V0X3BhZ2Vfb2Zmc2V0KHN0cnVjdCBrZXhlY19pbmZvICppbmZvKQoreworCXVu c2lnbmVkIGxvbmcgbG9uZyB2YWRkcl9vZmYgPSAwOworCXVuc2lnbmVkIGxvbmcgbG9uZyBwYWdl X3NpemUgPSBzeXNjb25mKF9TQ19QQUdFU0laRSk7CisJdW5zaWduZWQgbG9uZyBsb25nIGluaXRf c3RhcnQgPSBnZXRfa2VybmVsX3N5bSgiX3Npbml0dGV4dCIpOworCisJLyoKKwkgKiBCZWdpbmlu ZyBvZiBpbml0IHNlY3Rpb24gaXMgYWxpZ25lZCB0byBwYWdlIHNpemUKKwkgKi8KKwl2YWRkcl9v ZmYgPSBpbml0X3N0YXJ0IC0gcGFnZV9zaXplOworCisJcmV0dXJuIHZhZGRyX29mZjsKK30KKwor aW50IGxvYWRfZWxmY29yZWhkcihzdHJ1Y3Qga2V4ZWNfaW5mbyAqaW5mbykKK3sKKwlzdHJ1Y3Qg bWVtb3J5X3JhbmdlIGNyYXNoa2Vybl9yYW5nZSA9IHswfTsKKwlzdHJ1Y3QgbWVtb3J5X3Jhbmdl ICpyYW5nZXMgPSBOVUxMOworCXVuc2lnbmVkIGxvbmcgc3RhcnQgPSAwOworCXVuc2lnbmVkIGxv bmcgZW5kID0gMDsKKwl1bnNpZ25lZCBsb25nIGJ1Zl9zaXplID0gMDsKKwl1bnNpZ25lZCBsb25n IGVsZmNvcmVoZHJfYWRkciA9IDA7CisJdm9pZCogYnVmID0gTlVMTDsKKwlpbnQgaSA9IDA7CisJ aW50IHJldCA9IDA7CisKKwlyZXQgPSBwYXJzZV9pb21lbV9zaW5nbGUoIktlcm5lbCBjb2RlXG4i LCAmc3RhcnQsIE5VTEwpOworCWlmIChyZXQpIHsKKwkJZnByaW50ZihzdGRlcnIsICJDYW5ub3Qg ZGV0ZXJtaW5lIGtlcm5lbCBwaHlzaWNhbCBiYXNlIGFkZHJcbiIpOworCQlyZXR1cm4gLUVJTlZB TDsKKwl9CisJZWxmX2luZm8ua2Vybl9wYWRkcl9zdGFydCA9IHN0YXJ0OworCisJcmV0ID0gcGFy c2VfaW9tZW1fc2luZ2xlKCJLZXJuZWwgYnNzXG4iLCBOVUxMLCAmZW5kKTsKKwlpZiAocmV0KSB7 CisJCWZwcmludGYoc3RkZXJyLCAiQ2Fubm90IGRldGVybWluZSBrZXJuZWwgcGh5c2ljYWwgYnNz IGFkZHJcbiIpOworCQlyZXR1cm4gLUVJTlZBTDsKKwl9CisJZWxmX2luZm8ua2Vybl9wYWRkcl9z dGFydCA9IHN0YXJ0OworCWVsZl9pbmZvLmtlcm5fc2l6ZSA9IGVuZCAtIHN0YXJ0OworCisJZWxm X2luZm8ua2Vybl92YWRkcl9zdGFydCA9IGdldF9rZXJuZWxfc3ltKCJfdGV4dCIpOworCWlmICgh ZWxmX2luZm8ua2Vybl92YWRkcl9zdGFydCkgeworCQllbGZfaW5mby5rZXJuX3ZhZGRyX3N0YXJ0 ID0gVUlOVDY0X01BWDsKKwl9CisKKwllbGZfaW5mby5wYWdlX29mZnNldCA9IGdldF9wYWdlX29m ZnNldChpbmZvKTsKKwlkYmdwcmludGYoInBhZ2Vfb2Zmc2V0OiAgICUwMTZsbHhcbiIsIGVsZl9p bmZvLnBhZ2Vfb2Zmc2V0KTsKKworCXJldCA9IHBhcnNlX2lvbWVtX3NpbmdsZSgiQ3Jhc2gga2Vy bmVsXG4iLCAmc3RhcnQsICZlbmQpOworCWlmIChyZXQpIHsKKwkJZnByaW50ZihzdGRlcnIsICJD YW5ub3QgZGV0ZXJtaW5lIGtlcm5lbCBwaHlzaWNhbCBic3MgYWRkclxuIik7CisJCXJldHVybiAt RUlOVkFMOworCX0KKwljcmFzaGtlcm5fcmFuZ2Uuc3RhcnQgPSBzdGFydDsKKwljcmFzaGtlcm5f cmFuZ2UuZW5kID0gZW5kOworCWNyYXNoa2Vybl9yYW5nZS50eXBlID0gUkFOR0VfUkVTRVJWRUQ7 CisKKwlyYW5nZXMgPSBpbmZvLT5tZW1vcnlfcmFuZ2U7CisJZm9yIChpID0gMDsgaSA8IGluZm8t Pm1lbW9yeV9yYW5nZXM7IGkrKykgeworCQlyZXQgPSBtZW1fcmVnaW9uc19hbGxvY19hbmRfYWRk KCZjcmFzaF9tZW1fcmFuZ2VzLAorCQkJCQkJcmFuZ2VzW2ldLnN0YXJ0LAorCQkJCQkJcmFuZ2Vz W2ldLmVuZCAtIHJhbmdlc1tpXS5zdGFydCArIDEsCisJCQkJCQlyYW5nZXNbaV0udHlwZSk7CisJ CWlmIChyZXQgKSB7CisJCQlmcHJpbnRmKHN0ZGVyciwgIkNvdWxkIG5vdCBjcmVhdGUgY3Jhc2hf bWVtX3Jhbmdlc1xuIik7CisJCQlyZXR1cm4gcmV0OworCQl9CisJfQorCisJcmV0ID0gbWVtX3Jl Z2lvbnNfYWxsb2NfYW5kX2V4Y2x1ZGUoJmNyYXNoX21lbV9yYW5nZXMsCisJCQkJCSAgICAmY3Jh c2hrZXJuX3JhbmdlKTsKKwlpZiAocmV0KSB7CisJCWZwcmludGYoc3RkZXJyLCAiQ291bGQgbm90 IGV4Y2x1ZGUgY3Jhc2hrZXJuX3JhbmdlXG4iKTsKKwkJcmV0dXJuIHJldDsKKwl9CisKKyNpZiBf X3Jpc2N2X3hsZW4gPT0gNjQKKwljcmFzaF9jcmVhdGVfZWxmNjRfaGVhZGVycyhpbmZvLCAmZWxm X2luZm8sIGNyYXNoX21lbV9yYW5nZXMucmFuZ2VzLAorCQkJCSAgIGNyYXNoX21lbV9yYW5nZXMu c2l6ZSwgJmJ1ZiwgJmJ1Zl9zaXplLAorCQkJCSAgIEVMRl9DT1JFX0hFQURFUl9BTElHTik7CisK KyNlbHNlCisJY3Jhc2hfY3JlYXRlX2VsZjMyX2hlYWRlcnMoaW5mbywgJmVsZl9pbmZvLCBjcmFz aF9tZW1fcmFuZ2VzLnJhbmdlcywKKwkJCQkgICBjcmFzaF9tZW1fcmFuZ2VzLnNpemUsICZidWYs ICZidWZfc2l6ZSwKKwkJCQkgICBFTEZfQ09SRV9IRUFERVJfQUxJR04pOworI2VuZGlmCisKKwor CWVsZmNvcmVoZHJfYWRkciA9IGFkZF9idWZmZXJfcGh5c192aXJ0KGluZm8sIGJ1ZiwgYnVmX3Np emUsCisJCQkJCSAgICAgICBidWZfc2l6ZSwgMCwKKwkJCQkJICAgICAgIGNyYXNoa2Vybl9yYW5n ZS5zdGFydCwKKwkJCQkJICAgICAgIGNyYXNoa2Vybl9yYW5nZS5lbmQsCisJCQkJCSAgICAgICAt MSwgMCk7CisKKwllbGZjb3JlaGRyX21lbS5zdGFydCA9IGVsZmNvcmVoZHJfYWRkcjsKKwllbGZj b3JlaGRyX21lbS5lbmQgPSBlbGZjb3JlaGRyX2FkZHIgKyBidWZfc2l6ZSAtIDE7CisKKwlkYmdw cmludGYoIiVzOiBlbGZjb3JlaGRyIDB4JWxseC0weCVsbHhcbiIsIF9fZnVuY19fLAorCQkgIGVs ZmNvcmVoZHJfbWVtLnN0YXJ0LCBlbGZjb3JlaGRyX21lbS5lbmQpOworCisJcmV0dXJuIDA7Cit9 CisKK2ludCBpc19jcmFzaGtlcm5lbF9tZW1fcmVzZXJ2ZWQodm9pZCkKK3sKKwl1aW50NjRfdCBz dGFydCA9IDA7CisJdWludDY0X3QgZW5kID0gMDsKKworCXJldHVybiBwYXJzZV9pb21lbV9zaW5n bGUoIkNyYXNoIGtlcm5lbFxuIiwgJnN0YXJ0LCAmZW5kKSA9PSAwID8KKwkgICAgICAgKHN0YXJ0 ICE9IGVuZCkgOiAwOworfQorCitpbnQgZ2V0X2NyYXNoX2tlcm5lbF9sb2FkX3JhbmdlKHVpbnQ2 NF90ICpzdGFydCwgdWludDY0X3QgKmVuZCkKK3sKKwlyZXR1cm4gcGFyc2VfaW9tZW1fc2luZ2xl KCJDcmFzaCBrZXJuZWxcbiIsIHN0YXJ0LCBlbmQpOworfQorCmRpZmYgLS1naXQgYS9rZXhlYy9h cmNoL3Jpc2N2L2luY2x1ZGUvYXJjaC9vcHRpb25zLmggYi9rZXhlYy9hcmNoL3Jpc2N2L2luY2x1 ZGUvYXJjaC9vcHRpb25zLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMDAwMDAw Li43YzI0MTg0YjFmM2UKLS0tIC9kZXYvbnVsbAorKysgYi9rZXhlYy9hcmNoL3Jpc2N2L2luY2x1 ZGUvYXJjaC9vcHRpb25zLmgKQEAgLTAsMCArMSw0MyBAQAorI2lmbmRlZiBLRVhFQ19BUkNIX1JJ U0NWX09QVElPTlNfSAorI2RlZmluZSBLRVhFQ19BUkNIX1JJU0NWX09QVElPTlNfSAorCisjZGVm aW5lIE9QVF9BUFBFTkQJCSgoT1BUX01BWCkrMCkKKyNkZWZpbmUgT1BUX0RUQgkJCSgoT1BUX01B WCkrMSkKKyNkZWZpbmUgT1BUX0lOSVRSRAkJKChPUFRfTUFYKSsyKQorI2RlZmluZSBPUFRfQ01E TElORQkJKChPUFRfTUFYKSszKQorI2RlZmluZSBPUFRfUkVVU0VfQ01ETElORQkoKE9QVF9NQVgp KzQpCisjZGVmaW5lIE9QVF9BUkNIX01BWAkJKChPUFRfTUFYKSs1KQorCisvKiBPcHRpb25zIHJl bGV2YW50IHRvIHRoZSBhcmNoaXRlY3R1cmUgKGV4Y2x1ZGluZyBsb2FkZXItc3BlY2lmaWMgb25l cyksCisgKiBpbiB0aGlzIGNhc2Ugbm9uZToKKyAqLworI2RlZmluZSBLRVhFQ19BUkNIX09QVElP TlMgXAorCUtFWEVDX09QVElPTlMgXAorCXsgImFwcGVuZCIsCQkxLCAwLCBPUFRfQVBQRU5EfSwg XAorCXsgImR0YiIsCQkxLCAwLCBPUFRfRFRCIH0sIFwKKwl7ICJpbml0cmQiLAkJMSwgMCwgT1BU X0lOSVRSRCB9LCBcCisJeyAiY29tbWFuZC1saW5lIiwJMSwgMCwgT1BUX0NNRExJTkV9LCBcCisJ eyAicmV1c2UtY21kbGluZSIsCTAsIE5VTEwsIE9QVF9SRVVTRV9DTURMSU5FIH0sIFwKKworCisj ZGVmaW5lIEtFWEVDX0FSQ0hfT1BUX1NUUiBLRVhFQ19PUFRfU1RSICIiCisKKy8qIFRoZSBmb2xs b3dpbmcgdHdvICNkZWZpbmVzIGxpc3QgQUxMIG9mIHRoZSBvcHRpb25zIGFkZGVkIGJ5IGFsbCBv ZiB0aGUKKyAqIGFyY2hpdGVjdHVyZSdzIGxvYWRlcnMuCisgKiBvCW1haW4oKSB1c2VzIHRoaXMg Y29tcGxldGUgbGlzdCB0byBzY2FuIGZvciBpdHMgb3B0aW9ucywgaWdub3JpbmcKKyAqCWFyY2gt c3BlY2lmaWMvbG9hZGVyLXNwZWNpZmljIG9uZXMuCisgKiBvCVRoZW4sIGFyY2hfcHJvY2Vzc19v cHRpb25zKCkgdXNlcyB0aGlzIGNvbXBsZXRlIGxpc3QgdG8gc2NhbiBmb3IgaXRzCisgKglvcHRp b25zLCBpZ25vcmluZyBnZW5lcmFsL2xvYWRlci1zcGVjaWZpYyBvbmVzLgorICogbwlUaGVuLCB0 aGUgZmlsZV90eXBlW25dLmxvYWQgcmUtc2NhbnMgZm9yIG9wdGlvbnMsIHVzaW5nCisgKglLRVhF Q19BUkNIX09QVElPTlMgcGx1cyBpdHMgbG9hZGVyLXNwZWNpZmljIG9wdGlvbnMgc3Vic2V0Lgor ICoJQW55IHVucmVjb2duaXNlZCBvcHRpb25zIGNhdXNlIGFuIGVycm9yIGhlcmUuCisgKgorICog VGhpcyBpcyBkb25lIHNvIHRoYXQgbWFpbigpJ3MvYXJjaF9wcm9jZXNzX29wdGlvbnMoKSdzIGdl dG9wdF9sb25nKCkgY2FsbHMKKyAqIGRvbid0IGNob29zZSBhIGtlcm5lbCBmaWxlbmFtZSBmcm9t IHJhbmRvbSBhcmd1bWVudHMgdG8gb3B0aW9ucyB0aGV5IGRvbid0CisgKiByZWNvZ25pc2UgLS0g YXMgdGhleSBub3cgcmVjb2duaXNlIChpZiBub3QgYWN0IHVwb24pIGFsbCBwb3NzaWJsZSBvcHRp b25zLgorICovCisjZGVmaW5lIEtFWEVDX0FMTF9PUFRJT05TIEtFWEVDX0FSQ0hfT1BUSU9OUwor CisjZGVmaW5lIEtFWEVDX0FMTF9PUFRfU1RSIEtFWEVDX0FSQ0hfT1BUX1NUUgorCisjZW5kaWYg LyogS0VYRUNfQVJDSF9SSVNDVl9PUFRJT05TX0ggKi8KZGlmZiAtLWdpdCBhL2tleGVjL2FyY2gv cmlzY3YvaW9tZW0uaCBiL2tleGVjL2FyY2gvcmlzY3YvaW9tZW0uaApuZXcgZmlsZSBtb2RlIDEw MDY0NAppbmRleCAwMDAwMDAwMDAwMDAuLjc2NzFlMjZhOTU5NAotLS0gL2Rldi9udWxsCisrKyBi L2tleGVjL2FyY2gvcmlzY3YvaW9tZW0uaApAQCAtMCwwICsxLDEwIEBACisjaWZuZGVmIElPTUVN X0gKKyNkZWZpbmUgSU9NRU1fSAorCisjZGVmaW5lIFNZU1RFTV9SQU0JCSJTeXN0ZW0gUkFNXG4i CisjZGVmaW5lIEtFUk5FTF9DT0RFCQkiS2VybmVsIGNvZGVcbiIKKyNkZWZpbmUgS0VSTkVMX0RB VEEJCSJLZXJuZWwgZGF0YVxuIgorI2RlZmluZSBDUkFTSF9LRVJORUwJCSJDcmFzaCBrZXJuZWxc biIKKyNkZWZpbmUgSU9NRU1fUkVTRVJWRUQJCSJSZXNlcnZlZFxuIgorCisjZW5kaWYKZGlmZiAt LWdpdCBhL2tleGVjL2FyY2gvcmlzY3Yva2V4ZWMtZWxmLXJpc2N2LmMgYi9rZXhlYy9hcmNoL3Jp c2N2L2tleGVjLWVsZi1yaXNjdi5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAw MDAwMC4uZjNjMDExYzRjMWRjCi0tLSAvZGV2L251bGwKKysrIGIva2V4ZWMvYXJjaC9yaXNjdi9r ZXhlYy1lbGYtcmlzY3YuYwpAQCAtMCwwICsxLDI1NSBAQAorLyogU1BEWC1MaWNlbnNlLUlkZW50 aWZpZXI6IEdQTC0yLjAgKi8KKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTkgRk9SVEgtSUNTL0NB UlYKKyAqICAgICAgICAgICAgICBOaWNrIEtvc3NpZmlkaXMgPG1pY2tAaWNzLmZvcnRoLmdyPgor ICovCisKKyNpbmNsdWRlICJrZXhlYy5oIgorI2luY2x1ZGUgImR0LW9wcy5oIgkJLyogRm9yIGR0 Yl9zZXQvY2xlYXJfaW5pdHJkKCkgKi8KKyNpbmNsdWRlIDxlbGYuaD4JCS8qIEZvciBFTEYgaGVh ZGVyIGhhbmRsaW5nICovCisjaW5jbHVkZSA8ZXJybm8uaD4JCS8qIEZvciBFRkJJRy9FSU5WQUwg Ki8KKyNpbmNsdWRlIDx1bmlzdGQuaD4JCS8qIEZvciBnZXRwYWdlc2l6ZSgpICovCisjaW5jbHVk ZSAia2V4ZWMtc3lzY2FsbC5oIgkvKiBGb3IgS0VYRUNfT05fQ1JBU0ggKi8KKyNpbmNsdWRlICJr ZXhlYy1yaXNjdi5oIgorCisKKy8qKioqKioqKipcCisqIEhFTFBFUlMgKgorXCoqKioqKioqKi8K KworLyoKKyAqIEdvIHRocm91Z2ggdGhlIGF2YWlsYWJsZSBwaHlzaWNhbCBtZW1vcnkgcmVnaW9u cyBhbmQKKyAqIGZpbmQgb25lIHRoYXQgY2FuIGhvbGQgYW4gaW1hZ2Ugb2YgdGhlIHNwZWNpZmll ZCBzaXplLgorICogTm90ZTogVGhpcyBpcyBjYWxsZWQgYWZ0ZXIgZ2V0X21lbW9yeV9yYW5nZXMg c28KKyAqIGluZm8tPm1lbW9yeV9yYW5nZVtdIHNob3VsZCBiZSBwb3B1bGF0ZWQuIEFsc28gbm90 ZSB0aGF0CisgKiBtZW1vcnkgcmFuZ2VzIGFyZSBzb3J0ZWQsIHNvIHdlJ2xsIHJldHVybiB0aGUg Zmlyc3QgcmVnaW9uCisgKiB0aGF0J3MgYmlnIGVub3VnaCBmb3IgaG9sZGluZyB0aGUgaW1hZ2Uu CisgKi8KK3N0YXRpYyBpbnQgZWxmX3Jpc2N2X2ZpbmRfcGJhc2Uoc3RydWN0IGtleGVjX2luZm8g KmluZm8sIG9mZl90ICphZGRyLAorCQkJCW9mZl90IHNpemUpCit7CisJaW50IGkgPSAwOworCW9m Zl90IHN0YXJ0ID0gMDsKKwlvZmZfdCBlbmQgPSAwOworCWludCByZXQgPSAwOworCisJLyoKKwkg KiBJZiB0aGlzIGltYWdlIGlzIGZvciBhIGNyYXNoIGtlcm5lbCwgdXNlIHRoZSByZWdpb24KKwkg KiB0aGUgcHJpbWFyeSBrZXJuZWwgaGFzIGFscmVhZHkgcmVzZXJ2ZWQgZm9yIHVzLgorCSAqLwor CWlmIChpbmZvLT5rZXhlY19mbGFncyAmIEtFWEVDX09OX0NSQVNIKSB7CisJCXJldCA9IGdldF9j cmFzaF9rZXJuZWxfbG9hZF9yYW5nZSgodWludDY0X3QgKikgJnN0YXJ0LAorCQkJCQkJICAodWlu dDY0X3QgKikgJmVuZCk7CisJCWlmICghcmV0KSB7CisJCQkvKgorCQkJICogS2VybmVsIHNob3Vs ZCBiZSBhbGlnbmVkIHRvIHRoZSBuZWFyZXN0CisJCQkgKiBodWdlcGFnZSAoMk1CIGZvciBSVjY0 LCA0TUIgZm9yIFJWMzIpLgorCQkJICovCisjaWYgX19yaXNjdl94bGVuID09IDY0CisJCQlzdGFy dCA9IF9BTElHTl9VUChzdGFydCwgMHgyMDAwMDApOworI2Vsc2UKKwkJCXN0YXJ0ID0gX0FMSUdO X1VQKHN0YXJ0LCAweDQwMDAwMCk7CisjZW5kaWYKKwkJCWlmIChlbmQgPiBzdGFydCAmJiAoKGVu ZCAtIHN0YXJ0KSA+PSBzaXplKSkgeworCQkJCSphZGRyID0gc3RhcnQ7CisJCQkJcmV0dXJuIDA7 CisJCQl9CisKKwkJCXJldHVybiAtRUZCSUc7CisJCX0gZWxzZQorCQkJcmV0dXJuIEVOT0NSQVNI S0VSTkVMOworCX0KKworCWZvciAoaSA9IDA7IGkgPCBpbmZvLT5tZW1vcnlfcmFuZ2VzOyBpKysp IHsKKwkJaWYgKGluZm8tPm1lbW9yeV9yYW5nZVtpXS50eXBlICE9IFJBTkdFX1JBTSkKKwkJCWNv bnRpbnVlOworCisJCXN0YXJ0ID0gaW5mby0+bWVtb3J5X3JhbmdlW2ldLnN0YXJ0OworCQllbmQg PSBpbmZvLT5tZW1vcnlfcmFuZ2VbaV0uZW5kOworCisjaWYgX19yaXNjdl94bGVuID09IDY0CisJ CXN0YXJ0ID0gX0FMSUdOX1VQKHN0YXJ0LCAweDIwMDAwMCk7CisjZWxzZQorCQlzdGFydCA9IF9B TElHTl9VUChzdGFydCwgMHg0MDAwMDApOworI2VuZGlmCisKKwkJaWYgKGVuZCA+IHN0YXJ0ICYm ICgoZW5kIC0gc3RhcnQpID49IHNpemUpKSB7CisJCQkqYWRkciA9IHN0YXJ0OworCQkJcmV0dXJu IDA7CisJCX0KKwl9CisKKwlyZXR1cm4gLUVGQklHOworfQorCisvKioqKioqKioqKioqKipcCisq IEVOVFJZIFBPSU5UUyAqCitcKioqKioqKioqKioqKiovCisKK2ludCBlbGZfcmlzY3ZfcHJvYmUo Y29uc3QgY2hhciAqYnVmLCBvZmZfdCBsZW4pCit7CisJc3RydWN0IG1lbV9laGRyIGVoZHIgPSB7 MH07CisJaW50IHJldCA9IDA7CisKKwlyZXQgPSBidWlsZF9lbGZfZXhlY19pbmZvKGJ1ZiwgbGVu LCAmZWhkciwgMCk7CisJaWYgKHJldCA8IDApCisJCWdvdG8gY2xlYW51cDsKKworCWlmIChlaGRy LmVfbWFjaGluZSAhPSBFTV9SSVNDVikgeworCQlmcHJpbnRmKHN0ZGVyciwgIk5vdCBmb3IgdGhp cyBhcmNoaXRlY3R1cmUuXG4iKTsKKwkJcmV0ID0gLUVJTlZBTDsKKwkJZ290byBjbGVhbnVwOwor CX0KKworCXJldCA9IDA7CisKKyBjbGVhbnVwOgorCWZyZWVfZWxmX2luZm8oJmVoZHIpOworCXJl dHVybiByZXQ7Cit9CisKK3ZvaWQgZWxmX3Jpc2N2X3VzYWdlKHZvaWQpCit7Cit9CisKK2ludCBl bGZfcmlzY3ZfbG9hZChpbnQgYXJnYywgY2hhciAqKmFyZ3YsIGNvbnN0IGNoYXIgKmJ1Ziwgb2Zm X3QgbGVuLAorCQkgICBzdHJ1Y3Qga2V4ZWNfaW5mbyAqaW5mbykKK3sKKwlzdHJ1Y3QgbWVtX2Vo ZHIgZWhkciA9IHswfTsKKwlzdHJ1Y3QgbWVtX3BoZHIgKnBoZHIgPSBOVUxMOworCW9mZl90IG5l d19iYXNlX2FkZHIgPSAwOworCW9mZl90IGtlcm5lbF9zaXplID0gMDsKKwlvZmZfdCBwYWdlX3Np emUgPSBnZXRwYWdlc2l6ZSgpOworCW9mZl90IG1heF9hZGRyID0gMDsKKwlvZmZfdCBvbGRfYmFz ZV9hZGRyID0gMDsKKwlvZmZfdCBvbGRfc3RhcnRfYWRkciA9IDA7CisJaW50IGkgPSAwOworCWlu dCByZXQgPSAwOworCisJaWYgKGluZm8tPmZpbGVfbW9kZSkgeworCQlmcHJpbnRmKHN0ZGVyciwg ImtleGVjX2ZpbGUgbm90IHN1cHBvcnRlZCBvbiB0aGlzICIKKwkJCQkiYXJjaGl0ZWN0dXJlXG4i KTsKKwkJcmV0dXJuIC1FSU5WQUw7CisJfQorCisJLyogUGFyc2UgdGhlIEVMRiBmaWxlICovCisJ cmV0ID0gYnVpbGRfZWxmX2V4ZWNfaW5mbyhidWYsIGxlbiwgJmVoZHIsIDApOworCWlmIChyZXQg PCAwKSB7CisJCWZwcmludGYoc3RkZXJyLCAiRUxGIGV4ZWMgcGFyc2UgZmFpbGVkXG4iKTsKKwkJ cmV0dXJuIC1FSU5WQUw7CisJfQorCisJbWF4X2FkZHIgPSBlbGZfbWF4X2FkZHIoJmVoZHIpOwor CW9sZF9iYXNlX2FkZHIgPSBtYXhfYWRkcjsKKwlvbGRfc3RhcnRfYWRkciA9IG1heF9hZGRyOwor CisJLyoKKwkgKiBHZXQgdGhlIG1lbW9yeSBmb290cHJpbnQsIGJhc2UgcGh5c2ljYWwKKwkgKiBh bmQgc3RhcnQgYWRkcmVzcyBvZiB0aGUgRUxGIGltYWdlCisJICovCisJZm9yIChpID0gMDsgaSA8 IGVoZHIuZV9waG51bTsgaSsrKSB7CisJCXBoZHIgPSAmZWhkci5lX3BoZHJbaV07CisJCWlmIChw aGRyLT5wX3R5cGUgIT0gUFRfTE9BRCkKKwkJCWNvbnRpbnVlOworCisJCS8qCisJCSAqIE5vdGU6 IEFjY29yZGluZyB0byBFTEYgc3BlYyB0aGUgbG9hZGFibGUgcmVnaW9ucworCQkgKiBhcmUgc29y dGVkIG9uIHBfdmFkZHIsIG5vdCBwX3BhZGRyLgorCQkgKi8KKwkJaWYgKG9sZF9iYXNlX2FkZHIg PiBwaGRyLT5wX3BhZGRyKQorCQkJb2xkX2Jhc2VfYWRkciA9IHBoZHItPnBfcGFkZHI7CisKKwkJ aWYgKHBoZHItPnBfdmFkZHIgPT0gZWhkci5lX2VudHJ5IHx8CisJCSAgICBwaGRyLT5wX3BhZGRy ID09IGVoZHIuZV9lbnRyeSkKKwkJCW9sZF9zdGFydF9hZGRyID0gcGhkci0+cF9wYWRkcjsKKwor CQlrZXJuZWxfc2l6ZSArPSBfQUxJR05fVVAocGhkci0+cF9tZW1zeiwgcGFnZV9zaXplKTsKKwl9 CisKKwlpZiAob2xkX2Jhc2VfYWRkciA9PSBtYXhfYWRkciB8fCBrZXJuZWxfc2l6ZSA9PSAwKSB7 CisJCWZwcmludGYoc3RkZXJyLCAiTm8gbG9hZGFibGUgc2VnbWVudHMgcHJlc2VudCBvbiB0aGUg IgorCQkJCSJwcm92aWRlZCBFTEYgaW1hZ2VcbiIpOworCQlyZXR1cm4gLUVJTlZBTDsKKwl9CisK KwlpZiAob2xkX3N0YXJ0X2FkZHIgPT0gbWF4X2FkZHIpIHsKKwkJZnByaW50ZihzdGRlcnIsICJD b3VsZCBub3QgZmluZCB0aGUgZW50cnkgcG9pbnQgYWRkcmVzcyBvZiAiCisJCQkJInByb3ZpZGVk IEVMRiBpbWFnZVxuIik7CisJCXJldHVybiAtRUlOVkFMOworCX0KKworCWRiZ3ByaW50ZigiR290 IEVMRiB3aXRoIHRvdGFsIG1lbXN6ICVsdUtCXG4iCisJCSAgIkJhc2UgcGFkZHI6IDB4JWxYLCBz dGFydF9hZGRyOiAweCVsWFxuIiwKKwkJICBrZXJuZWxfc2l6ZSAvIDEwMjQsIG9sZF9iYXNlX2Fk ZHIsIG9sZF9zdGFydF9hZGRyKTsKKworCS8qIEdldCBhIGNvbnRpbnVvdXMgcGh5c2ljYWwgcmVn aW9uIHRoYXQgY2FuIGhvbGQgdGhlIGtlcm5lbCAqLworCXJldCA9IGVsZl9yaXNjdl9maW5kX3Bi YXNlKGluZm8sICZuZXdfYmFzZV9hZGRyLCBrZXJuZWxfc2l6ZSk7CisJaWYgKHJldCA8IDApIHsK KwkJZnByaW50ZihzdGRlcnIsICJDb3VsZCBub3QgZmluZCBhIG1lbW9yeSByZWdpb24gZm9yIHRo ZSAiCisJCQkJInByb3ZpZGVkIEVMRiBpbWFnZVxuIik7CisJCXJldHVybiByZXQ7CisJfQorCisJ ZGJncHJpbnRmKCJOZXcgYmFzZSBwYWRkciBmb3IgdGhlIEVMRjogMHglbFhcbiIsIG5ld19iYXNl X2FkZHIpOworCisJLyogUmUtc2V0IHRoZSBiYXNlIHBoeXNpY2FsIGFkZHJlc3Mgb2YgdGhlIEVM RiAqLworCWZvciAoaSA9IDA7IGkgPCBlaGRyLmVfcGhudW07IGkrKykgeworCQlwaGRyID0gJmVo ZHIuZV9waGRyW2ldOworCQlpZiAocGhkci0+cF90eXBlICE9IFBUX0xPQUQpCisJCQljb250aW51 ZTsKKworCQlwaGRyLT5wX3BhZGRyIC09IG9sZF9iYXNlX2FkZHI7CisJCXBoZHItPnBfcGFkZHIg Kz0gbmV3X2Jhc2VfYWRkcjsKKwl9CisKKwkvKiBSZS1zZXQgdGhlIGVudHJ5IHBvaW50IGFkZHJl c3MgKi8KKwllaGRyLmVfZW50cnkgPSAob2xkX3N0YXJ0X2FkZHIgLSBvbGRfYmFzZV9hZGRyKSAr IG5ld19iYXNlX2FkZHI7CisJaW5mby0+ZW50cnkgPSAodm9pZCAqKSBlaGRyLmVfZW50cnk7CisJ ZGJncHJpbnRmKCJOZXcgZW50cnkgcG9pbnQgZm9yIHRoZSBFTEY6IDB4JWxsWFxuIiwgZWhkci5l X2VudHJ5KTsKKworCisJLyogTG9hZCB0aGUgRUxGIGV4ZWN1dGFibGUgKi8KKwlyZXQgPSBlbGZf ZXhlY19sb2FkKCZlaGRyLCBpbmZvKTsKKwlpZiAocmV0IDwgMCkgeworCQlmcHJpbnRmKHN0ZGVy ciwgIkVMRiBleGVjIGxvYWQgZmFpbGVkXG4iKTsKKwkJcmV0dXJuIHJldDsKKwl9CisKKwlyZXQg PSBsb2FkX2V4dHJhX3NlZ21lbnRzKGluZm8sIG5ld19iYXNlX2FkZHIsCisJCQkJICBrZXJuZWxf c2l6ZSwgbWF4X2FkZHIpOworCXJldHVybiByZXQ7Cit9CisKKworLyoqKioqKipcCisqIFNUVUJT ICoKK1wqKioqKioqLworCitpbnQgbWFjaGluZV92ZXJpZnlfZWxmX3JlbChzdHJ1Y3QgbWVtX2Vo ZHIgKmVoZHIpCit7CisJaWYgKGVoZHItPmVpX2RhdGEgIT0gRUxGREFUQTJMU0IpCisJCXJldHVy biAwOworI2lmIF9fcmlzY3ZfeGxlbiA9PSA2NAorCWlmIChlaGRyLT5laV9jbGFzcyAhPSBFTEZD TEFTUzY0KQorI2Vsc2UKKwlpZiAoZWhkci0+ZWlfY2xhc3MgIT0gRUxGQ0xBU1MzMikKKyNlbmRp ZgorCQlyZXR1cm4gMDsKKwlpZiAoZWhkci0+ZV9tYWNoaW5lICE9IEVNX1JJU0NWKQorCQlyZXR1 cm4gMDsKKwlyZXR1cm4gMTsKK30KKwordm9pZCBtYWNoaW5lX2FwcGx5X2VsZl9yZWwoc3RydWN0 IG1lbV9laGRyICpVTlVTRUQoZWhkciksCisJCQkgICBzdHJ1Y3QgbWVtX3N5bSAqVU5VU0VEKHN5 bSksCisJCQkgICB1bnNpZ25lZCBsb25nIHJfdHlwZSwKKwkJCSAgIHZvaWQgKlVOVVNFRChsb2Nh dGlvbiksCisJCQkgICB1bnNpZ25lZCBsb25nIFVOVVNFRChhZGRyZXNzKSwKKwkJCSAgIHVuc2ln bmVkIGxvbmcgVU5VU0VEKHZhbHVlKSkKK3sKKwlzd2l0Y2ggKHJfdHlwZSkgeworCWRlZmF1bHQ6 CisJCWRpZSgiVW5rbm93biByZWxhIHJlbG9jYXRpb246ICVsdVxuIiwgcl90eXBlKTsKKwkJYnJl YWs7CisJfQorfQpkaWZmIC0tZ2l0IGEva2V4ZWMvYXJjaC9yaXNjdi9rZXhlYy1yaXNjdi5jIGIv a2V4ZWMvYXJjaC9yaXNjdi9rZXhlYy1yaXNjdi5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4 IDAwMDAwMDAwMDAwMC4uMzhkOWEzOTRhYWRkCi0tLSAvZGV2L251bGwKKysrIGIva2V4ZWMvYXJj aC9yaXNjdi9rZXhlYy1yaXNjdi5jCkBAIC0wLDAgKzEsNDMxIEBACisvKiBTUERYLUxpY2Vuc2Ut SWRlbnRpZmllcjogR1BMLTIuMCAqLworLyoKKyAqIENvcHlyaWdodCAoQykgMjAxOSBGT1JUSC1J Q1MvQ0FSVgorICogICAgICAgICAgICAgIE5pY2sgS29zc2lmaWRpcyA8bWlja0BpY3MuZm9ydGgu Z3I+CisgKi8KKworI2luY2x1ZGUgImtleGVjLXN5c2NhbGwuaCIJLyogRm9yIEtFWEVDX0FSQ0hf UklTQ1YgKi8KKyNpbmNsdWRlICJrZXhlYy5oIgkJLyogRm9yIE9QVF9NQVggYW5kIGNvbmNhdF9j bWRsaW5lKCkgKi8KKyNpbmNsdWRlICJtZW1fcmVnaW9ucy5oIgkvKiBGb3IgbWVtX3JlZ2lvbnNf c29ydCgpICovCisjaW5jbHVkZSAiZHQtb3BzLmgiCQkvKiBGb3IgZHRiX3NldF9ib290YXJncygp ICovCisjaW5jbHVkZSA8YXJjaC9vcHRpb25zLmg+CS8qIEZvciBLRVhFQ19BUkNIX09QVElPTlMg Ki8KKyNpbmNsdWRlIDxnZXRvcHQuaD4JCS8qIEZvciBzdHJ1Y3Qgb3B0aW9uICovCisjaW5jbHVk ZSA8c3lzL3N0YXQuaD4JCS8qIEZvciBzdGF0KCkgYW5kIHN0cnVjdCBzdGF0ICovCisjaW5jbHVk ZSA8c3RkbGliLmg+CQkvKiBGb3IgZnJlZSgpICovCisjaW5jbHVkZSA8ZXJybm8uaD4JCS8qIEZv ciBFSU5WQUwgKi8KKyNpbmNsdWRlIDxsaWJmZHQuaD4JCS8qIEZvciBEZXZpY2VUcmVlIGhhbmRs aW5nICovCisjaW5jbHVkZSAia2V4ZWMtcmlzY3YuaCIKKyNpbmNsdWRlICJpb21lbS5oIgorI2lu Y2x1ZGUgPHN0ZGJvb2wuaD4KKworY29uc3Qgc3RydWN0IGFyY2hfbWFwX2VudHJ5IGFyY2hlc1td ID0geworCXsgInJpc2N2MzIiLCBLRVhFQ19BUkNIX1JJU0NWIH0sCisJeyAicmlzY3Y2NCIsIEtF WEVDX0FSQ0hfUklTQ1YgfSwKKwl7IE5VTEwsIDAgfSwKK307CisKKworc3RydWN0IGZpbGVfdHlw ZSBmaWxlX3R5cGVbXSA9IHsKKwl7ImVsZi1yaXNjdiIsIGVsZl9yaXNjdl9wcm9iZSwgZWxmX3Jp c2N2X2xvYWQsIGVsZl9yaXNjdl91c2FnZX0sCit9OworaW50IGZpbGVfdHlwZXMgPSBzaXplb2Yo ZmlsZV90eXBlKSAvIHNpemVvZihmaWxlX3R5cGVbMF0pOworCitzdGF0aWMgY29uc3QgY2hhciBy aXNjdl9vcHRzX3VzYWdlW10gPQorIgktLWFwcGVuZD1TVFJJTkcJCUFwcGVuZCBTVFJJTkcgdG8g dGhlIGtlcm5lbCBjb21tYW5kIGxpbmUuXG4iCisiCS0tZHRiPUZJTEUJCVVzZSBGSUxFIGFzIHRo ZSBkZXZpY2UgdHJlZSBibG9iLlxuIgorIgktLWluaXRyZD1GSUxFCQlVc2UgRklMRSBhcyB0aGUg a2VybmVsIGluaXRpYWwgcmFtZGlzay5cbiIKKyIJLS1jb21tYW5kLWxpbmU9U1RSSU5HCVVzZSBT VFJJTkcgYXMgdGhlIGtlcm5lbCdzIGNvbW1hbmQgbGluZS5cbiIKKyIJLS1yZXVzZS1jbWRsaW5l CQlVc2Uga2VybmVsIGNvbW1hbmQgbGluZSBmcm9tIHJ1bm5pbmcgc3lzdGVtLlxuIjsKKworc3Rh dGljIHN0cnVjdCByaXNjdl9vcHRzIGFyY2hfb3B0aW9ucyA9IHswfTsKK3N0YXRpYyBzdHJ1Y3Qg ZmR0X2ltYWdlIHByb3ZpZGVkX2ZkdCA9IHswfTsKKworLyoqKioqKioqKioqKioqKipcCisqIENP TU1PTiBIRUxQRVJTICoKK1wqKioqKioqKioqKioqKioqLworCitpbnQgbG9hZF9leHRyYV9zZWdt ZW50cyhzdHJ1Y3Qga2V4ZWNfaW5mbyAqaW5mbywgdWludDY0X3Qga2VybmVsX2Jhc2UsCisJCQl1 aW50NjRfdCBrZXJuZWxfc2l6ZSwgdWludDY0X3QgbWF4X2FkZHIpCit7CisJc3RydWN0IGZkdF9p bWFnZSAqZmR0ID0gYXJjaF9vcHRpb25zLmZkdDsKKwljaGFyICppbml0cmRfYnVmID0gTlVMTDsK KwlvZmZfdCBpbml0cmRfc2l6ZSA9IDA7CisJdWludDY0X3QgaW5pdHJkX2Jhc2UgPSAwOworCXVp bnQ2NF90IHN0YXJ0ID0gMDsKKwl1aW50NjRfdCBlbmQgPSAwOworCXVpbnQ2NF90IG1pbl91c2Fi bGUgPSBrZXJuZWxfYmFzZSArIGtlcm5lbF9zaXplOworCXVpbnQ2NF90IG1heF91c2FibGUgPSBt YXhfYWRkcjsKKwlpbnQgcmV0ID0gMDsKKworCS8qIFByZXBhcmUgdGhlIGRldmljZSB0cmVlICov CisJaWYgKGluZm8tPmtleGVjX2ZsYWdzICYgS0VYRUNfT05fQ1JBU0gpIHsKKwkJcmV0ID0gbG9h ZF9lbGZjb3JlaGRyKGluZm8pOworCQlpZiAocmV0KSB7CisJCQlmcHJpbnRmKHN0ZGVyciwgIkNv dWxkbid0IGNyZWF0ZSBlbGZjb3JlaGRyXG4iKTsKKwkJCXJldHVybiByZXQ7CisJCX0KKworCQly ZXQgPSBkdGJfYWRkX3JhbmdlX3Byb3BlcnR5KCZmZHQtPmJ1ZiwgJmZkdC0+c2l6ZSwKKwkJCQkJ ICAgICBlbGZjb3JlaGRyX21lbS5zdGFydCwgZWxmY29yZWhkcl9tZW0uZW5kLAorCQkJCQkgICAg ICJjaG9zZW4iLCAibGludXgsZWxmY29yZWhkciIpOworCQlpZiAocmV0KSB7CisJCQlmcHJpbnRm KHN0ZGVyciwgIkNvdWxkbid0IGFkZCBlbGZjb3JlaGRyIHRvIGZkdFxuIik7CisJCQlyZXR1cm4g cmV0OworCQl9CisKKwkJcmV0ID0gZ2V0X2NyYXNoX2tlcm5lbF9sb2FkX3JhbmdlKCZzdGFydCwg JmVuZCk7CisJCWlmIChyZXQpIHsKKwkJCWZwcmludGYoc3RkZXJyLCAiQ291bGRuJ3QgZ2V0IGNy YXNoa2VuZWwgcmVnaW9uXG4iKTsKKwkJCXJldHVybiByZXQ7CisJCX0KKworCQlyZXQgPSBkdGJf YWRkX3JhbmdlX3Byb3BlcnR5KCZmZHQtPmJ1ZiwgJmZkdC0+c2l6ZSwgc3RhcnQsIGVuZCwKKwkJ CQkJICAgICAiY2hvc2VuIiwgImxpbnV4LHVzYWJsZS1tZW1vcnktcmFuZ2UiKTsKKwkJaWYgKHJl dCkgeworCQkJZnByaW50ZihzdGRlcnIsICJDb3VsZG4ndCBhZGQgdXNhYmxlLW1lbW9yeS1yYW5n ZSB0byBmZHRcbiIpOworCQkJcmV0dXJuIHJldDsKKwkJfQorCisJCW1heF91c2FibGUgPSBlbmQ7 CisJfSBlbHNlIHsKKwkJLyoKKwkJICogTWFrZSBzdXJlIHdlIHJlbW92ZSBlbGZjb3JlaGRyIGFu ZCB1c2FibGUtbWVtb3J5LXJhbmdlCisJCSAqIHdoZW4gc3dpdGNoaW5nIGZyb20gY3Jhc2gga2Vy bmVsIHRvIGEgbm9ybWFsIG9uZS4KKwkJICovCisJCWR0Yl9kZWxldGVfcHJvcGVydHkoZmR0LT5i dWYsICJjaG9zZW4iLCAibGludXgsZWxmY29yZWhkciIpOworCQlkdGJfZGVsZXRlX3Byb3BlcnR5 KGZkdC0+YnVmLCAiY2hvc2VuIiwgImxpbnV4LHVzYWJsZS1tZW1vcnktcmFuZ2UiKTsKKwl9CisK KwkvKiBEbyB3ZSBuZWVkIHRvIGluY2x1ZGUgYW4gaW5pdHJkIGltYWdlID8gKi8KKwlpZiAoIWFy Y2hfb3B0aW9ucy5pbml0cmRfcGF0aCAmJiAhYXJjaF9vcHRpb25zLmluaXRyZF9lbmQpCisJCWR0 Yl9jbGVhcl9pbml0cmQoJmZkdC0+YnVmLCAmZmR0LT5zaXplKTsKKwllbHNlIGlmIChhcmNoX29w dGlvbnMuaW5pdHJkX3BhdGgpIHsKKwkJaWYgKGFyY2hfb3B0aW9ucy5pbml0cmRfZW5kKQorCQkJ ZnByaW50ZihzdGRlcnIsICJXYXJuaW5nOiBBbiBpbml0cmQgaW1hZ2Ugd2FzIHByb3ZpZGVkIgor CQkJCQkiLCB3aWxsIGlnbm9yZSByZXVzZWluaXRyZFxuIik7CisKKwkJaW5pdHJkX2J1ZiA9IHNs dXJwX2ZpbGUoYXJjaF9vcHRpb25zLmluaXRyZF9wYXRoLAorCQkJCQkmaW5pdHJkX3NpemUpOwor CQlpZiAoIWluaXRyZF9idWYpIHsKKwkJCWZwcmludGYoc3RkZXJyLCAiQ291bGRuJ3QgcmVhZCBw cm92aWRlZCBpbml0cmRcbiIpOworCQkJcmV0dXJuIC1FSU5WQUw7CisJCX0KKworCQlpbml0cmRf YmFzZSA9IGFkZF9idWZmZXJfcGh5c192aXJ0KGluZm8sIGluaXRyZF9idWYsCisJCQkJCQkgICBp bml0cmRfc2l6ZSwKKwkJCQkJCSAgIGluaXRyZF9zaXplLCAwLAorCQkJCQkJICAgbWluX3VzYWJs ZSwKKwkJCQkJCSAgIG1heF91c2FibGUsIC0xLCAwKTsKKworCQlkdGJfc2V0X2luaXRyZCgmZmR0 LT5idWYsICZmZHQtPnNpemUsIGluaXRyZF9iYXNlLAorCQkJICAgICAgIGluaXRyZF9iYXNlICsg aW5pdHJkX3NpemUpOworCisJCWRiZ3ByaW50ZigiQmFzZSBhZGRyIGZvciBpbml0cmQgaW1hZ2U6 IDB4JWxYXG4iLCBpbml0cmRfYmFzZSk7CisJCW1heF91c2FibGUgPSBpbml0cmRfYmFzZTsKKwl9 CisKKwkvKiBBZGQgZGV2aWNlIHRyZWUgKi8KKwlhZGRfYnVmZmVyX3BoeXNfdmlydChpbmZvLCBm ZHQtPmJ1ZiwgZmR0LT5zaXplLCBmZHQtPnNpemUsIDAsCisJCQkgICAgIG1pbl91c2FibGUsIG1h eF91c2FibGUsIC0xLCAwKTsKKworCXJldHVybiAwOworfQorCisKKy8qKioqKioqKioqKioqKlwK KyogRU5UUlkgUE9JTlRTICoKK1wqKioqKioqKioqKioqKi8KKwordm9pZCBhcmNoX3VzYWdlKHZv aWQpCit7CisJcHJpbnRmKHJpc2N2X29wdHNfdXNhZ2UpOworfQorCitpbnQgYXJjaF9wcm9jZXNz X29wdGlvbnMoaW50IGFyZ2MsIGNoYXIgKiphcmd2KQoreworCXN0YXRpYyBjb25zdCBzdHJ1Y3Qg b3B0aW9uIG9wdGlvbnNbXSA9IHsKKwkJS0VYRUNfQVJDSF9PUFRJT05TCisJCXsgMCB9LAorCX07 CisJc3RhdGljIGNvbnN0IGNoYXIgc2hvcnRfb3B0aW9uc1tdID0gS0VYRUNfQVJDSF9PUFRfU1RS OworCXN0cnVjdCBzdGF0IHN0ID0gezB9OworCWNoYXIgKmFwcGVuZCA9IE5VTEw7CisJY2hhciAq Y21kbGluZSA9IE5VTEw7CisJdm9pZCAqdG1wID0gTlVMTDsKKwlvZmZfdCB0bXBfc2l6ZSA9IDA7 CisJaW50IG9wdCA9IDA7CisJaW50IHJldCA9IDA7CisKKwl3aGlsZSAoKG9wdCA9IGdldG9wdF9s b25nKGFyZ2MsIGFyZ3YsIHNob3J0X29wdGlvbnMsCisJCQkJICBvcHRpb25zLCAwKSkgIT0gLTEp IHsKKwkJc3dpdGNoIChvcHQpIHsKKwkJY2FzZSBPUFRfQVBQRU5EOgorCQkJYXBwZW5kID0gb3B0 YXJnOworCQkJYnJlYWs7CisJCWNhc2UgT1BUX0NNRExJTkU6CisJCQlpZiAoY21kbGluZSkKKwkJ CQlmcHJpbnRmKHN0ZGVyciwKKwkJCQkJIldhcm5pbmc6IEtlcm5lbCdzIGNtZGxpbmUgIgorCQkJ CQkic2V0IHR3aWNlICFcbiIpOworCQkJY21kbGluZSA9IG9wdGFyZzsKKwkJCWJyZWFrOworCQlj YXNlIE9QVF9SRVVTRV9DTURMSU5FOgorCQkJaWYgKGNtZGxpbmUpCisJCQkJZnByaW50ZihzdGRl cnIsCisJCQkJCSJXYXJuaW5nOiBLZXJuZWwncyBjbWRsaW5lICIKKwkJCQkJInNldCB0d2ljZSAh XG4iKTsKKwkJCWNtZGxpbmUgPSBnZXRfY29tbWFuZF9saW5lKCk7CisJCQlicmVhazsKKwkJY2Fz ZSBPUFRfRFRCOgorCQkJcmV0ID0gc3RhdChvcHRhcmcsICZzdCk7CisJCQlpZiAocmV0KSB7CisJ CQkJZnByaW50ZihzdGRlcnIsCisJCQkJCSJDb3VsZCBub3QgZmluZCB0aGUgcHJvdmlkZWQgZHRi ICFcbiIpOworCQkJCXJldHVybiAtRUlOVkFMOworCQkJfQorCQkJYXJjaF9vcHRpb25zLmZkdF9w YXRoID0gb3B0YXJnOworCQkJYnJlYWs7CisJCWNhc2UgT1BUX0lOSVRSRDoKKwkJCXJldCA9IHN0 YXQob3B0YXJnLCAmc3QpOworCQkJaWYgKHJldCkgeworCQkJCWZwcmludGYoc3RkZXJyLAorCQkJ CQkiQ291bGQgbm90IGZpbmQgdGhlIHByb3ZpZGVkICIKKwkJCQkJImluaXRyZCBpbWFnZSAhXG4i KTsKKwkJCQlyZXR1cm4gLUVJTlZBTDsKKwkJCX0KKwkJCWFyY2hfb3B0aW9ucy5pbml0cmRfcGF0 aCA9IG9wdGFyZzsKKwkJCWJyZWFrOworCQlkZWZhdWx0OgorCQkJYnJlYWs7CisJCX0KKwl9CisK KwkvKiBIYW5kbGUgS2VybmVsJ3MgY29tbWFuZCBsaW5lICovCisJaWYgKGFwcGVuZCAmJiAhY21k bGluZSkKKwkJZnByaW50ZihzdGRlcnIsICJXYXJuaW5nOiBObyBjbWRsaW5lIHByb3ZpZGVkLCAi CisJCQkJInVzaW5nIGFwcGVuZCBzdHJpbmcgYXMgY21kbGluZVxuIik7CisJaWYgKCFhcHBlbmQg JiYgIWNtZGxpbmUpCisJCWZwcmludGYoc3RkZXJyLCAiV2FybmluZzogTm8gY21kbGluZSBvciBh cHBlbmQgc3RyaW5nICIKKwkJCQkicHJvdmlkZWRcbiIpOworCisJaWYgKGFwcGVuZCB8fCBjbWRs aW5lKQorCQkvKgorCQkgKiBOb3RlIHRoYXQgdGhpcyBhbHNvIGhhbmRsZXMgdGhlIGNhc2Ugd2hl cmUgImNtZGxpbmUiCisJCSAqIG9yICJhcHBlbmQiIGlzIE5VTEwuCisJCSAqLworCQlhcmNoX29w dGlvbnMuY21kbGluZSA9IGNvbmNhdF9jbWRsaW5lKGNtZGxpbmUsIGFwcGVuZCk7CisKKwkvKiBI YW5kbGUgRkRUIGltYWdlICovCisJaWYgKCFhcmNoX29wdGlvbnMuZmR0X3BhdGgpIHsKKwkJcmV0 ID0gc3RhdCgiL3N5cy9maXJtd2FyZS9mZHQiLCAmc3QpOworCQlpZiAocmV0KSB7CisJCQlmcHJp bnRmKHN0ZGVyciwgIk5vIGR0YiBwcm92aWRlZCBhbmQgIgorCQkJCQkiL3N5cy9maXJtd2FyZS9m ZHQgaXMgbm90IHByZXNlbnRcbiIpOworCQkJcmV0dXJuIC1FSU5WQUw7CisJCX0KKwkJZnByaW50 ZihzdGRlcnIsICJXYXJuaW5nOiBObyBkdGIgcHJvdmlkZWQsICIKKwkJCQkidXNpbmcgL3N5cy9m aXJtd2FyZS9mZHRcbiIpOworCQlhcmNoX29wdGlvbnMuZmR0X3BhdGggPSAiL3N5cy9maXJtd2Fy ZS9mZHQiOworCX0KKworCXRtcCA9IHNsdXJwX2ZpbGUoYXJjaF9vcHRpb25zLmZkdF9wYXRoLCAm dG1wX3NpemUpOworCWlmICghdG1wKSB7CisJCWZwcmludGYoc3RkZXJyLCAiQ291bGRuJ3QgcmVh ZCBwcm92aWRlZCBmZHRcbiIpOworCQlyZXR1cm4gLUVJTlZBTDsKKwl9CisKKwlyZXQgPSBmZHRf Y2hlY2tfaGVhZGVyKHRtcCk7CisJaWYgKHJldCkgeworCQlmcHJpbnRmKHN0ZGVyciwgIkdvdCBh biBpdmFsaWQgZmR0IGltYWdlICFcbiIpOworCQlmcmVlKHRtcCk7CisJCXJldHVybiAtRUlOVkFM OworCX0KKwlwcm92aWRlZF9mZHQuYnVmID0gdG1wOworCXByb3ZpZGVkX2ZkdC5zaXplID0gdG1w X3NpemU7CisKKwlpZiAoYXJjaF9vcHRpb25zLmNtZGxpbmUpIHsKKwkJcmV0ID0gZHRiX3NldF9i b290YXJncygmcHJvdmlkZWRfZmR0LmJ1ZiwgJnByb3ZpZGVkX2ZkdC5zaXplLAorCQkJCSAgICAg ICBhcmNoX29wdGlvbnMuY21kbGluZSk7CisJCWlmIChyZXQgPCAwKSB7CisJCQlmcHJpbnRmKHN0 ZGVyciwgIkNvdWxkIG5vdCBzZXQgYm9vdGFyZ3Mgb24gIgorCQkJCQkidGhlIGZkdCBpbWFnZVxu Iik7CisJCQlyZXR1cm4gcmV0OworCQl9CisJfQorCisJYXJjaF9vcHRpb25zLmZkdCA9ICZwcm92 aWRlZF9mZHQ7CisKKwlyZXR1cm4gMDsKK30KKworLyoKKyAqIFRoaXMgb25lIGlzIGNhbGxlZCBh ZnRlciBhcmNoX3Byb2Nlc3Nfb3B0aW9ucyBzbyB3ZSBhbHJlYWR5CisgKiBoYXZlIGFuIGZkdCBp bWFnZSBpbiBwbGFjZS4KKyAqLwordm9pZCBhcmNoX3JldXNlX2luaXRyZCh2b2lkKQoreworCWNv bnN0IHVpbnQzMl90ICpwcm9wMzIgPSBOVUxMOworCXVpbnQzMl90IGFkZHJfY2VsbHMgPSAwOwor CWNvbnN0IHZvaWQgKnByb3AgPSAwOworCWludCBwcm9wX3NpemUgPSAwOworCXVpbnQ2NF90IGlu aXRyZF9zdGFydCA9IDA7CisJdWludDY0X3QgaW5pdHJkX2VuZCA9IDA7CisJaW50IGNob3Nlbl9v ZmZzZXQgPSAwOworCXN0cnVjdCBmZHRfaW1hZ2UgKmZkdCA9ICZwcm92aWRlZF9mZHQ7CisKKwlj aG9zZW5fb2Zmc2V0ID0gZmR0X3N1Ym5vZGVfb2Zmc2V0KGZkdC0+YnVmLCAwLCAiY2hvc2VuIik7 CisJaWYgKGNob3Nlbl9vZmZzZXQgPCAwKSB7CisJCWZwcmludGYoc3RkZXJyLCAiTm8gL2Nob3Nl biBub2RlIGZvdW5kIG9uIGZkdCBpbWFnZSAiCisJCQkJInVuYWJsZSB0byByZXVzZSBpbml0cmRc biIpOworCQlyZXR1cm47CisJfQorCisJcHJvcDMyID0gZmR0X2dldHByb3AoZmR0LT5idWYsIDAs ICIjYWRkcmVzcy1jZWxscyIsIE5VTEwpOworCWlmICghcHJvcDMyKSB7CisJCWZwcmludGYoc3Rk ZXJyLCAiTm8gI2FkZHJlc3MtY2VsbHMgcHJvcGVydHkgb24gcm9vdCBub2RlXG4iKTsKKwkJcmV0 dXJuOworCX0KKwlhZGRyX2NlbGxzID0gYmUzMl90b19jcHUoKnByb3AzMik7CisKKwlwcm9wID0g ZmR0X2dldHByb3AoZmR0LT5idWYsIGNob3Nlbl9vZmZzZXQsCisJCQkgICAibGludXgsaW5pdHJk LXN0YXJ0IiwgJnByb3Bfc2l6ZSk7CisJaWYgKCFwcm9wKSB7CisJCWZwcmludGYoc3RkZXJyLCAi Q291bGQgbm90IGdldCBsaW51eCxpbml0cmQtc3RhcnRcbiIpOworCQlyZXR1cm47CisJfQorCWR0 Yl9leHRyYWN0X2ludF9wcm9wZXJ0eSgmaW5pdHJkX3N0YXJ0LCBwcm9wLCBhZGRyX2NlbGxzKTsK KworCXByb3AgPSBmZHRfZ2V0cHJvcChmZHQtPmJ1ZiwgY2hvc2VuX29mZnNldCwKKwkJCSAgICJs aW51eCxpbml0cmQtZW5kIiwgJnByb3Bfc2l6ZSk7CisJaWYgKCFwcm9wKSB7CisJCWZwcmludGYo c3RkZXJyLCAiQ291bGQgbm90IGdldCBsaW51eCxpbml0cmQtZW5kXG4iKTsKKwkJcmV0dXJuOwor CX0KKwlkdGJfZXh0cmFjdF9pbnRfcHJvcGVydHkoJmluaXRyZF9lbmQsIHByb3AsIGFkZHJfY2Vs bHMpOworCisJYXJjaF9vcHRpb25zLmluaXRyZF9zdGFydCA9IGluaXRyZF9zdGFydDsKKwlhcmNo X29wdGlvbnMuaW5pdHJkX2VuZCA9IGluaXRyZF9lbmQ7CisJZGJncHJpbnRmKCJpbml0cmRfc3Rh cnQ6IDB4JWxYLCBpbml0cmRfZW5kOiAweCVsWFxuIiwKKwkJICBpbml0cmRfc3RhcnQsIGluaXRy ZF9lbmQpOworCit9CisKK3N0YXRpYyBib29sIHRvX2JlX2V4Y2x1ZGVkKGNoYXIgKnN0ciwgdW5z aWduZWQgbG9uZyBsb25nIHN0YXJ0LCB1bnNpZ25lZCBsb25nIGxvbmcgZW5kKQoreworCWlmICgh c3RybmNtcChzdHIsIENSQVNIX0tFUk5FTCwgc3RybGVuKENSQVNIX0tFUk5FTCkpKSB7CisJCXVp bnQ2NF90IGxvYWRfc3RhcnQsIGxvYWRfZW5kOworCisJCWlmICghZ2V0X2NyYXNoX2tlcm5lbF9s b2FkX3JhbmdlKCZsb2FkX3N0YXJ0LCAmbG9hZF9lbmQpICYmCisJCSAgICAobG9hZF9zdGFydCA9 PSBzdGFydCkgJiYgKGxvYWRfZW5kID09IGVuZCkpCisJCQlyZXR1cm4gZmFsc2U7CisKKwkJcmV0 dXJuIHRydWU7CisJfQorCisJaWYgKCFzdHJuY21wKHN0ciwgU1lTVEVNX1JBTSwgc3RybGVuKFNZ U1RFTV9SQU0pKSB8fAorCSAgICAhc3RybmNtcChzdHIsIEtFUk5FTF9DT0RFLCBzdHJsZW4oS0VS TkVMX0NPREUpKSB8fAorCSAgICAhc3RybmNtcChzdHIsIEtFUk5FTF9EQVRBLCBzdHJsZW4oS0VS TkVMX0RBVEEpKSkKKwkJcmV0dXJuIGZhbHNlOworCWVsc2UKKwkJcmV0dXJuIHRydWU7Cit9CisK K2ludCBnZXRfbWVtb3J5X3JhbmdlcyhzdHJ1Y3QgbWVtb3J5X3JhbmdlICoqcmFuZ2UsIGludCAq bnVtX3JhbmdlcywKKwkJICAgICAgdW5zaWduZWQgbG9uZyBrZXhlY19mbGFncykKK3sKKwlzdHJ1 Y3QgbWVtb3J5X3JhbmdlcyBzeXNtZW1fcmFuZ2VzID0gezB9OworCWNvbnN0IGNoYXIgKmlvbWVt ID0gcHJvY19pb21lbSgpOworCXN0cnVjdCBtZW1vcnlfcmFuZ2UgZXhjbF9yYW5nZTsKKwl1bnNp Z25lZCBsb25nIGxvbmcgc3RhcnQsIGVuZDsKKwlpbnQgY29uc3VtZWQsIGNvdW50LCByZXQgPSAw OworCUZJTEUgKmZwID0gTlVMTCwgKnNwID0gTlVMTDsKKwljaGFyIGxpbmVbTUFYX0xJTkVdLCAq c3RyOworCisJZnAgPSBmb3Blbihpb21lbSwgInIiKTsKKwlpZiAoIWZwKSB7CisJCWZwcmludGYo c3RkZXJyLCAiQ2Fubm90IG9wZW4gJXM6ICVzXG4iLCBpb21lbSwgc3RyZXJyb3IoZXJybm8pKTsK KwkJcmV0dXJuIC0xOworCX0KKworCXNwID0gZm9wZW4oaW9tZW0sICJyIik7CisJaWYgKCFzcCkg eworCQlmcHJpbnRmKHN0ZGVyciwgIkNhbm5vdCBvcGVuICVzOiAlc1xuIiwgaW9tZW0sIHN0cmVy cm9yKGVycm5vKSk7CisJCXJldCA9IC0xOworCQlnb3RvIGVycjsKKwl9CisKKwkvKgorCSAqIFBl cmZvcm0gdHdvIHBhc3NlczogRmlyc3QgYWRkIGFsbCBTeXN0ZW0gUkFNLCBhbmQgdGhlbgorCSAq IGV4Y2x1ZGUgdGhlICJSZXNlcnZlZCIgcmFuZ2VzIgorCSAqLworCXdoaWxlIChmZ2V0cyhsaW5l LCBzaXplb2YobGluZSksIGZwKSAhPSAwKSB7CisJCWNvdW50ID0gc3NjYW5mKGxpbmUsICIlbGx4 LSVsbHggOiAlbiIsICZzdGFydCwgJmVuZCwgJmNvbnN1bWVkKTsKKwkJaWYgKGNvdW50ICE9IDIp CisJCQljb250aW51ZTsKKwkJc3RyID0gbGluZSArIGNvbnN1bWVkOworCisJCWlmICghc3RybmNt cChzdHIsIFNZU1RFTV9SQU0sIHN0cmxlbihTWVNURU1fUkFNKSkpIHsKKwkJCXJldCA9IG1lbV9y ZWdpb25zX2FsbG9jX2FuZF9hZGQoJnN5c21lbV9yYW5nZXMsCisJCQkJCXN0YXJ0LCBlbmQgLSBz dGFydCArIDEsIFJBTkdFX1JBTSk7CisJCQlpZiAocmV0KSB7CisJCQkJZnByaW50ZihzdGRlcnIs CisJCQkJCSJDYW5ub3QgYWxsb2NhdGUgbWVtb3J5IGZvciByYW5nZXNcbiIpOworCQkJCXJldCA9 IC1FTk9NRU07CisJCQkJZ290byBlcnI7CisJCQl9CisKKwkJfQorCX0KKworCXdoaWxlIChmZ2V0 cyhsaW5lLCBzaXplb2YobGluZSksIHNwKSAhPSAwKSB7CisJCWNvdW50ID0gc3NjYW5mKGxpbmUs ICIlbGx4LSVsbHggOiAlbiIsICZzdGFydCwgJmVuZCwgJmNvbnN1bWVkKTsKKwkJaWYgKGNvdW50 ICE9IDIpCisJCQljb250aW51ZTsKKwkJc3RyID0gbGluZSArIGNvbnN1bWVkOworCisJCWlmICh0 b19iZV9leGNsdWRlZChzdHIsIHN0YXJ0LCBlbmQpKSB7CisJCQlleGNsX3JhbmdlLnN0YXJ0ID0g c3RhcnQ7CisJCQlleGNsX3JhbmdlLmVuZCA9IGVuZDsKKworCQkJcmV0ID0gbWVtX3JlZ2lvbnNf YWxsb2NfYW5kX2V4Y2x1ZGUoJnN5c21lbV9yYW5nZXMsICZleGNsX3JhbmdlKTsKKwkJCWlmIChy ZXQpIHsKKwkJCQlmcHJpbnRmKHN0ZGVyciwKKwkJCQkJIkNhbm5vdCBhbGxvY2F0ZSBtZW1vcnkg Zm9yIHJhbmdlcyAoZXhjbHVkZSlcbiIpOworCQkJCXJldCA9IC1FTk9NRU07CisJCQkJZ290byBl cnI7CisJCQl9CisJCX0KKwl9CisKKwkqcmFuZ2UgPSBzeXNtZW1fcmFuZ2VzLnJhbmdlczsKKwkq bnVtX3JhbmdlcyA9IHN5c21lbV9yYW5nZXMuc2l6ZTsKKworCWRiZ3ByaW50X21lbV9yYW5nZSgi U3lzdGVtIFJBTSByYW5nZXM7IiwKKwkJCQlzeXNtZW1fcmFuZ2VzLnJhbmdlcywgc3lzbWVtX3Jh bmdlcy5zaXplKTsKKworCXJldCA9IDA7CisgZXJyOgorCWlmIChmcCkKKwkJZmNsb3NlKGZwKTsK KwlpZiAoc3ApCisJCWZjbG9zZShzcCk7CisJcmV0dXJuIHJldDsKK30KKworLyoqKioqKipcCisq IFNUVUJTICoKK1wqKioqKioqLworCitpbnQgYXJjaF9jb21wYXRfdHJhbXBvbGluZShzdHJ1Y3Qg a2V4ZWNfaW5mbyAqVU5VU0VEKGluZm8pKQoreworCXJldHVybiAwOworfQorCit2b2lkIGFyY2hf dXBkYXRlX3B1cmdhdG9yeShzdHJ1Y3Qga2V4ZWNfaW5mbyAqVU5VU0VEKGluZm8pKQoreworfQor CitpbnQgYXJjaF9kb19leGNsdWRlX3NlZ21lbnQoc3RydWN0IGtleGVjX2luZm8gKlVOVVNFRChp bmZvKSwgc3RydWN0IGtleGVjX3NlZ21lbnQgKlVOVVNFRChzZWdtZW50KSkKK3sKKwlyZXR1cm4g MDsKK30KZGlmZiAtLWdpdCBhL2tleGVjL2FyY2gvcmlzY3Yva2V4ZWMtcmlzY3YuaCBiL2tleGVj L2FyY2gvcmlzY3Yva2V4ZWMtcmlzY3YuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAw MDAwMDAwMDAuLmM0MzIzYTY1ZGFjZgotLS0gL2Rldi9udWxsCisrKyBiL2tleGVjL2FyY2gvcmlz Y3Yva2V4ZWMtcmlzY3YuaApAQCAtMCwwICsxLDMyIEBACisvKiBTUERYLUxpY2Vuc2UtSWRlbnRp ZmllcjogR1BMLTIuMCAqLworLyoKKyAqIENvcHlyaWdodCAoQykgMjAxOSBGT1JUSC1JQ1MvQ0FS VgorICogICAgICAgICAgICAgIE5pY2sgS29zc2lmaWRpcyA8bWlja0BpY3MuZm9ydGguZ3I+Cisg Ki8KKworc3RydWN0IGZkdF9pbWFnZSB7CisJY2hhcgkqYnVmOworCW9mZl90CXNpemU7Cit9Owor CitzdHJ1Y3QgcmlzY3Zfb3B0cyB7CisJY2hhciAqY21kbGluZTsKKwljaGFyICpmZHRfcGF0aDsK KwljaGFyICppbml0cmRfcGF0aDsKKwl1aW50NjRfdCBpbml0cmRfc3RhcnQ7CisJdWludDY0X3Qg aW5pdHJkX2VuZDsKKwlzdHJ1Y3QgZmR0X2ltYWdlICpmZHQ7Cit9OworCisvKiBjcmFzaGR1bXAt cmlzY3YuYyAqLworZXh0ZXJuIHN0cnVjdCBtZW1vcnlfcmFuZ2UgZWxmY29yZWhkcl9tZW07Citp bnQgbG9hZF9lbGZjb3JlaGRyKHN0cnVjdCBrZXhlY19pbmZvICppbmZvKTsKKworLyoga2V4ZWMt cmlzY3YuYyAqLworaW50IGxvYWRfZXh0cmFfc2VnbWVudHMoc3RydWN0IGtleGVjX2luZm8gKmlu Zm8sIHVpbnQ2NF90IGtlcm5lbF9iYXNlLAorCQkJdWludDY0X3Qga2VybmVsX3NpemUsIHVpbnQ2 NF90IG1heF9hZGRyKTsKKworaW50IGVsZl9yaXNjdl9wcm9iZShjb25zdCBjaGFyICpidWYsIG9m Zl90IGxlbik7Cit2b2lkIGVsZl9yaXNjdl91c2FnZSh2b2lkKTsKK2ludCBlbGZfcmlzY3ZfbG9h ZChpbnQgYXJnYywgY2hhciAqKmFyZ3YsIGNvbnN0IGNoYXIgKmJ1Ziwgb2ZmX3QgbGVuLAorCQkg ICBzdHJ1Y3Qga2V4ZWNfaW5mbyAqaW5mbyk7CmRpZmYgLS1naXQgYS9rZXhlYy9kdC1vcHMuYyBi L2tleGVjL2R0LW9wcy5jCmluZGV4IDBhOTZiNzVmNjVhYS4uM2UyODVhYjIwNDNiIDEwMDY0NAot LS0gYS9rZXhlYy9kdC1vcHMuYworKysgYi9rZXhlYy9kdC1vcHMuYwpAQCAtNCw5ICs0LDExIEBA CiAjaW5jbHVkZSA8bGliZmR0Lmg+CiAjaW5jbHVkZSA8c3RkaW8uaD4KICNpbmNsdWRlIDxzdGRs aWIuaD4KKyNpbmNsdWRlIDxzdGRib29sLmg+CiAKICNpbmNsdWRlICJrZXhlYy5oIgogI2luY2x1 ZGUgImR0LW9wcy5oIgorI2luY2x1ZGUgIm1lbV9yZWdpb25zLmgiCiAKIHN0YXRpYyBjb25zdCBj aGFyIG5fY2hvc2VuW10gPSAiY2hvc2VuIjsKIApAQCAtOTUsNyArOTcsNyBAQCBpbnQgZHRiX3Nl dF9wcm9wZXJ0eShjaGFyICoqZHRiLCBvZmZfdCAqZHRiX3NpemUsIGNvbnN0IGNoYXIgKm5vZGUs CiAKIAlzdHJjcHkobmV3X25vZGUsICIvIik7CiAJc3RyY2F0KG5ld19ub2RlLCBub2RlKTsKLQkK KwogCW5vZGVvZmZzZXQgPSBmZHRfcGF0aF9vZmZzZXQobmV3X2R0YiwgbmV3X25vZGUpOwogCiAJ aWYgKG5vZGVvZmZzZXQgPT0gLUZEVF9FUlJfTk9URk9VTkQpIHsKQEAgLTE3NCwzICsxNzYsNDQx IEBAIGludCBkdGJfZGVsZXRlX3Byb3BlcnR5KGNoYXIgKmR0YiwgY29uc3QgY2hhciAqbm9kZSwg Y29uc3QgY2hhciAqcHJvcCkKIAlmcmVlKG5ld19ub2RlKTsKIAlyZXR1cm4gcmVzdWx0OwogfQor CitzdGF0aWMgaW50IGR0Yl9nZXRfbnVtX2NlbGxzKGNoYXIgKmR0YiwgaW50IG5vZGVvZmZzZXQs IHVpbnQzMl90ICphZGRyX2NlbGxzLAorCQkJICAgICB1aW50MzJfdCAqc2l6ZV9jZWxscywgYm9v bCByZWN1cnNpdmUpCit7CisJY29uc3QgdWludDMyX3QgKnByb3AzMiA9IE5VTEw7CisJaW50IGN1 cnJfb2Zmc2V0ID0gbm9kZW9mZnNldDsKKwlpbnQgcHJvcF9sZW4gPSAwOworCSphZGRyX2NlbGxz ID0gMDsKKwkqc2l6ZV9jZWxscyA9IDA7CisKKwlkbyB7CisJCXByb3AzMiA9IGZkdF9nZXRwcm9w KGR0YiwgY3Vycl9vZmZzZXQsICIjYWRkcmVzcy1jZWxscyIsICZwcm9wX2xlbik7CisJCWN1cnJf b2Zmc2V0ID0gZmR0X3BhcmVudF9vZmZzZXQoZHRiLCBjdXJyX29mZnNldCk7CisJfSB3aGlsZSAo IXByb3AzMiAmJiBwcm9wX2xlbiA9PSAtRkRUX0VSUl9OT1RGT1VORCAmJiByZWN1cnNpdmUpOwor CisJaWYgKCFwcm9wMzIpIHsKKwkJZGJncHJpbnRmKCJDb3VsZCBub3QgZ2V0ICNhZGRyZXNzLWNl bGxzIHByb3BlcnR5IGZvciAlcyAoJXMpXG4iLAorCQkJICBmZHRfZ2V0X25hbWUoZHRiLCBub2Rl b2Zmc2V0LCBOVUxMKSwgZmR0X3N0cmVycm9yKG5vZGVvZmZzZXQpKTsKKwkJcmV0dXJuIC1FSU5W QUw7CisJfQorCSphZGRyX2NlbGxzID0gZmR0MzJfdG9fY3B1KCpwcm9wMzIpOworCisJY3Vycl9v ZmZzZXQgPSBub2Rlb2Zmc2V0OworCWRvIHsKKwkJcHJvcDMyID0gZmR0X2dldHByb3AoZHRiLCBj dXJyX29mZnNldCwgIiNzaXplLWNlbGxzIiwgJnByb3BfbGVuKTsKKwkJY3Vycl9vZmZzZXQgPSBm ZHRfcGFyZW50X29mZnNldChkdGIsIGN1cnJfb2Zmc2V0KTsKKwl9IHdoaWxlICghcHJvcDMyICYm IHByb3BfbGVuID09IC1GRFRfRVJSX05PVEZPVU5EICYmIHJlY3Vyc2l2ZSk7CisKKwlpZiAoIXBy b3AzMikgeworCQlkYmdwcmludGYoIkNvdWxkIG5vdCBnZXQgI3NpemUtY2VsbHMgcHJvcGVydHkg Zm9yICVzICglcylcbiIsCisJCQkgIGZkdF9nZXRfbmFtZShkdGIsIG5vZGVvZmZzZXQsIE5VTEwp LCBmZHRfc3RyZXJyb3Iobm9kZW9mZnNldCkpOworCQlyZXR1cm4gLUVJTlZBTDsKKwl9CisJKnNp emVfY2VsbHMgPSBmZHQzMl90b19jcHUoKnByb3AzMik7CisKKwlkYmdwcmludGYoIiVzOiAjYWRk cmVzcy1jZWxsczolZCAjc2l6ZS1jZWxsczolZFxuIiwKKwkJIGZkdF9nZXRfbmFtZShkdGIsIG5v ZGVvZmZzZXQsIE5VTEwpLCAqYWRkcl9jZWxscywgKnNpemVfY2VsbHMpOworCisJcmV0dXJuIDA7 Cit9CisKK3ZvaWQgZHRiX2V4dHJhY3RfaW50X3Byb3BlcnR5KHVpbnQ2NF90ICp2YWwsIGNvbnN0 IHZvaWQgKmJ1ZiwgdWludDMyX3QgY2VsbHMpCit7CisJY29uc3QgdWludDMyX3QgKnByb3AzMiA9 IE5VTEw7CisJY29uc3QgdWludDY0X3QgKnByb3A2NCA9IE5VTEw7CisKKwlpZiAoY2VsbHMgPT0g MSkgeworCQlwcm9wMzIgPSAoY29uc3QgdWludDMyX3QgKikgYnVmOworCQkqdmFsID0gKHVpbnQ2 NF90KSBiZTMyX3RvX2NwdSgqcHJvcDMyKTsKKwl9IGVsc2UgeworCQkvKiBTa2lwIGFueSBsZWFk aW5nIGNlbGxzICovCisJCXByb3A2NCA9IChjb25zdCB1aW50NjRfdCAqKSAodWludDMyX3QgKili dWYgKyBjZWxscyAtIDI7CisJCSp2YWwgPSAodWludDY0X3QpIGJlNjRfdG9fY3B1KCpwcm9wNjQp OworCX0KK30KKwordm9pZCBkdGJfZmlsbF9pbnRfcHJvcGVydHkodm9pZCAqYnVmLCB1aW50NjRf dCB2YWwsIHVpbnQzMl90IGNlbGxzKQoreworCXVpbnQzMl90IHByb3AzMiA9IDA7CisJdWludDY0 X3QgcHJvcDY0ID0gMDsKKworCWlmIChjZWxscyA9PSAxKSB7CisJCXByb3AzMiA9IGNwdV90b19m ZHQzMigodWludDMyX3QpIHZhbCk7CisJCW1lbWNweShidWYsICZwcm9wMzIsIHNpemVvZih1aW50 MzJfdCkpOworCX0gZWxzZSB7CisJCXByb3A2NCA9IGNwdV90b19mZHQ2NCh2YWwpOworCQkvKiBT a2lwIGFueSBsZWFkaW5nIGNlbGxzICovCisJCW1lbWNweSgodWludDY0X3QgKikodWludDMyX3Qg KilidWYgKyBjZWxscyAtIDIsCisJCSAgICAgICAmcHJvcDY0LCBzaXplb2YodWludDY0X3QpKTsK Kwl9Cit9CisKK2ludCBkdGJfYWRkX3JhbmdlX3Byb3BlcnR5KGNoYXIgKipkdGIsIG9mZl90ICpk dGJfc2l6ZSwgdWludDY0X3Qgc3RhcnQsIHVpbnQ2NF90IGVuZCwKKwkJCSAgIGNvbnN0IGNoYXIg KnBhcmVudCwgY29uc3QgY2hhciAqbmFtZSkKK3sKKwl1aW50MzJfdCBhZGRyX2NlbGxzID0gMDsK Kwl1aW50MzJfdCBzaXplX2NlbGxzID0gMDsKKwljaGFyICpub2RlcGF0aCA9IE5VTEw7CisJdm9p ZCAqcHJvcCA9IE5VTEw7CisJaW50IG5vZGVvZmZzZXQgPSAwOworCWludCBwcm9wX3NpemUgPSAw OworCWludCByZXQgPSAwOworCisJbm9kZXBhdGggPSBtYWxsb2Moc3RybGVuKCIvIikgKyBzdHJs ZW4ocGFyZW50KSArIDEpOworCWlmICghbm9kZXBhdGgpIHsKKwkJZGJncHJpbnRmKCIlczogbWFs bG9jIGZhaWxlZFxuIiwgX19mdW5jX18pOworCQlyZXR1cm4gLUVOT01FTTsKKwl9CisKKwlzdHJj cHkobm9kZXBhdGgsICIvIik7CisJc3RyY2F0KG5vZGVwYXRoLCBwYXJlbnQpOworCisJbm9kZW9m ZnNldCA9IGZkdF9wYXRoX29mZnNldCgqZHRiLCBub2RlcGF0aCk7CisJaWYgKG5vZGVvZmZzZXQg PCAwKSB7CisJCWRiZ3ByaW50ZigiJXM6IGZkdF9wYXRoX29mZnNldCglcykgZmFpbGVkOiAlc1xu IiwgX19mdW5jX18sCisJCQkgIG5vZGVwYXRoLCBmZHRfc3RyZXJyb3Iobm9kZW9mZnNldCkpOwor CQlmcmVlKG5vZGVwYXRoKTsKKwkJcmV0dXJuIG5vZGVvZmZzZXQ7CisJfQorCWZyZWUobm9kZXBh dGgpOworCisJcmV0ID0gZHRiX2dldF9udW1fY2VsbHMoKmR0Yiwgbm9kZW9mZnNldCwgJmFkZHJf Y2VsbHMsICZzaXplX2NlbGxzLCB0cnVlKTsKKwlpZiAocmV0IDwgMCkKKwkJcmV0dXJuIHJldDsK KworCS8qIENhbiB0aGUgcmFuZ2UgZml0IHdpdGggdGhlIGdpdmVuIGFkZHJlc3Mvc2l6ZSBjZWxs cyA/ICovCisJaWYgKChhZGRyX2NlbGxzID09IDEpICYmIChzdGFydCA+PSAoMVVMTCA8PCAzMikp KQorCQlyZXR1cm4gLUVJTlZBTDsKKworCWlmICgoc2l6ZV9jZWxscyA9PSAxKSAmJiAoKGVuZCAt IHN0YXJ0ICsgMSkgPj0gKDFVTEwgPDwgMzIpKSkKKwkJcmV0dXJuIC1FSU5WQUw7CisKKwlwcm9w X3NpemUgPSBzaXplb2YodWludDMyX3QpICogKGFkZHJfY2VsbHMgKyBzaXplX2NlbGxzKTsKKwlw cm9wID0gbWFsbG9jKHByb3Bfc2l6ZSk7CisKKwlkdGJfZmlsbF9pbnRfcHJvcGVydHkocHJvcCwg c3RhcnQsIGFkZHJfY2VsbHMpOworCWR0Yl9maWxsX2ludF9wcm9wZXJ0eSgodm9pZCAqKSgodWlu dDMyX3QgKilwcm9wICsgYWRkcl9jZWxscyksCisJCQkgICAgICBlbmQgLSBzdGFydCArIDEsIHNp emVfY2VsbHMpOworCisJLyogQWRkIGJ5IG5vZGUgcGF0aCBuYW1lICovCisJcmV0dXJuIGR0Yl9z ZXRfcHJvcGVydHkoZHRiLCBkdGJfc2l6ZSwgcGFyZW50LCBuYW1lLCBwcm9wLCBwcm9wX3NpemUp OworfQorCisvKioqKioqKioqKioqKioqKioqKioqKioqXAorKiBNRU1PUlkgUkFOR0VTIEhBTkRM SU5HICoKK1wqKioqKioqKioqKioqKioqKioqKioqKiovCisKK3N0YXRpYyBpbnQgZHRiX2FkZF9t ZW1vcnlfcmFuZ2Uoc3RydWN0IG1lbW9yeV9yYW5nZXMgKm1lbV9yYW5nZXMsIHVpbnQ2NF90IHN0 YXJ0LAorCQkJCXVpbnQ2NF90IGVuZCwgdW5zaWduZWQgdHlwZSkKK3sKKwlzdHJ1Y3QgbWVtb3J5 X3JhbmdlIHRoaXNfcmVnaW9uID0gezB9OworCXN0cnVjdCBtZW1vcnlfcmFuZ2UgKnJhbmdlcyA9 IG1lbV9yYW5nZXMtPnJhbmdlczsKKwlpbnQgaSA9IDA7CisJaW50IHJldCA9IDA7CisKKwlpZiAo c3RhcnQgPT0gZW5kKSB7CisJCWRiZ3ByaW50ZigiSWdub3JpbmcgZW1wdHkgcmVnaW9uXG4iKTsK KwkJcmV0dXJuIC1FSU5WQUw7CisJfQorCisJLyogQ2hlY2sgaWYgd2UgYXJlIGFkZGluZyBhbiBl eGlzdGluZyByZWdpb24gKi8KKwlmb3IgKGkgPSAwOyBpIDwgbWVtX3Jhbmdlcy0+c2l6ZTsgaSsr KSB7CisJCWlmIChzdGFydCA9PSByYW5nZXNbaV0uc3RhcnQgJiYgZW5kID09IHJhbmdlc1tpXS5l bmQpIHsKKwkJCWRiZ3ByaW50ZigiRHVwbGljYXRlOiAweCVseCAtIDB4JWx4XG4iLCBzdGFydCwg ZW5kKTsKKworCQkJaWYgKHR5cGUgPT0gcmFuZ2VzW2ldLnR5cGUpCisJCQkJcmV0dXJuIDA7CisJ CQllbHNlIGlmICh0eXBlID09IFJBTkdFX1JFU0VSVkVEKSB7CisJCQkJcmFuZ2VzW2ldLnR5cGUg PSBSQU5HRV9SRVNFUlZFRDsKKwkJCQlyZXR1cm4gMDsKKwkJCX0KKworCQkJZGJncHJpbnRmKCJD b25mbGljdGluZyB0eXBlcyBmb3IgcmVnaW9uOiAweCVseCAtIDB4JWx4XG4iLAorCQkJCSAgc3Rh cnQsIGVuZCk7CisJCQlyZXR1cm4gLUVJTlZBTDsKKwkJfQorCX0KKworCS8qCisJICogUmVzZXJ2 ZWQgcmVnaW9ucyBtYXkgYmUgcGFydCBvZiBhbiBleGlzdGluZyAvbWVtb3J5CisJICogcmVnaW9u IGFuZCBzaG91bGRuJ3Qgb3ZlcmxhcCBhY2NvcmRpbmcgdG8gc3BlYywgc28KKwkgKiBzaW5jZSB3 ZSBhZGQgL21lbW9yeSByZWdpb25zIGZpcnN0LCB3ZSBjYW4gZXhjbHVkZQorCSAqIHJlc2VydmVk IHJlZ2lvbnMgaGVyZSBmcm9tIHRoZSBleGlzdGluZyAvbWVtb3J5IHJlZ2lvbnMKKwkgKiBpbmNs dWRlZCBpbiByYW5nZXNbXSwgc28gdGhhdCB3ZSBkb24ndCBoYXZlIHRoZSBzYW1lCisJICogcmVn aW9uIHR3aWNlLgorCSAqLworCWlmICh0eXBlID09IFJBTkdFX1JFU0VSVkVEKSB7CisJCXRoaXNf cmVnaW9uLnN0YXJ0ID0gc3RhcnQ7CisJCXRoaXNfcmVnaW9uLmVuZCA9IGVuZCAtIDE7CisJCXRo aXNfcmVnaW9uLnR5cGUgPSB0eXBlOworCQlyZXQgPSBtZW1fcmVnaW9uc19leGNsdWRlKG1lbV9y YW5nZXMsICZ0aGlzX3JlZ2lvbik7CisJCWlmIChyZXQpCisJCQlyZXR1cm4gcmV0OworCX0KKwor CXJldCA9IG1lbV9yZWdpb25zX2FsbG9jX2FuZF9hZGQobWVtX3Jhbmdlcywgc3RhcnQsCisJCQkJ CWVuZCAtIHN0YXJ0LCB0eXBlKTsKKworCXJldHVybiByZXQ7Cit9CisKK3N0YXRpYyBpbnQgZHRi X2FkZF9tZW1vcnlfcmVnaW9uKGNoYXIgKmR0YiwgaW50IG5vZGVvZmZzZXQsCisJCQkJIHN0cnVj dCBtZW1vcnlfcmFuZ2VzICptZW1fcmFuZ2VzLCBpbnQgdHlwZSkKK3sKKwl1aW50MzJfdCByb290 X2FkZHJfY2VsbHMgPSAwOworCXVpbnQzMl90IHJvb3Rfc2l6ZV9jZWxscyA9IDA7CisJdWludDY0 X3QgYWRkciA9IDA7CisJdWludDY0X3Qgc2l6ZSA9IDA7CisJY29uc3QgY2hhciAqcmVnID0gTlVM TDsKKwlpbnQgcHJvcF9zaXplID0gMDsKKwlpbnQgb2Zmc2V0ID0gMDsKKwlpbnQgZW50cnlfc2l6 ZSA9IDA7CisJaW50IG51bV9lbnRyaWVzID0gMDsKKwlpbnQgcmV0ID0gMDsKKworCS8qCisJICog R2V0IGFkZHJlc3MtY2VsbHMgYW5kIHNpemUtY2VsbHMgcHJvcGVydGllcyAoYWNjb3JkaW5nIHRv CisJICogYmluZGluZyBzcGVjIHRoZXNlIGFyZSB0aGUgc2FtZSBhcyBpbiB0aGUgcm9vdCBub2Rl KQorCSAqLworCXJldCA9IGR0Yl9nZXRfbnVtX2NlbGxzKGR0YiwgMCwgJnJvb3RfYWRkcl9jZWxs cywgJnJvb3Rfc2l6ZV9jZWxscywgZmFsc2UpOworCWlmIChyZXQgPCAwKSB7CisJCWRiZ3ByaW50 ZigiTm8gYWRkcmVzcy9zaXplIGNlbGxzIG9uIHJvb3Qgbm9kZSAhXG4iKTsKKwkJcmV0dXJuIHJl dDsKKwl9CisKKwkvKgorCSAqIFBhcnNlIHRoZSByZWcgYXJyYXksIGFjb3JkaW5nIHRvIGRldmlj ZSB0cmVlIHNwZWMgaXQgaW5jbHVkZXMKKwkgKiBhbiBhcmJpdGFyeSBudW1iZXIgb2YgPGFkZHJl c3M+PHNpemU+IHBhaXJzCisJICovCisJZW50cnlfc2l6ZSA9IChyb290X2FkZHJfY2VsbHMgKyBy b290X3NpemVfY2VsbHMpICogc2l6ZW9mKHVpbnQzMl90KTsKKwlyZWcgPSBmZHRfZ2V0cHJvcChk dGIsIG5vZGVvZmZzZXQsICJyZWciLCAmcHJvcF9zaXplKTsKKwlpZiAoIXJlZykgeworCQlkYmdw cmludGYoIldhcm5pbmc6IE1hbGZvcm1lZCBtZW1vcnkgcmVnaW9uIHdpdGggbm8gcmVnIHByb3Bl cnR5ICglcykgIVxuIiwKKwkJCSAgZmR0X2dldF9uYW1lKGR0Yiwgbm9kZW9mZnNldCwgTlVMTCkp OworCQlyZXR1cm4gLUVJTlZBTDsKKwl9CisKKwludW1fZW50cmllcyA9IHByb3Bfc2l6ZSAvIGVu dHJ5X3NpemU7CisJZGJncHJpbnRmKCJHb3QgcmVnaW9uIHdpdGggJWkgZW50cmllczogJXNcbiIs IG51bV9lbnRyaWVzLAorCQkgIGZkdF9nZXRfbmFtZShkdGIsIG5vZGVvZmZzZXQsIE5VTEwpKTsK KworCWZvciAobnVtX2VudHJpZXMtLTsgbnVtX2VudHJpZXMgPj0gMDsgbnVtX2VudHJpZXMtLSkg eworCQlvZmZzZXQgPSBudW1fZW50cmllcyAqIGVudHJ5X3NpemU7CisKKwkJZHRiX2V4dHJhY3Rf aW50X3Byb3BlcnR5KCZhZGRyLCByZWcgKyBvZmZzZXQsCisJCQkJCSByb290X2FkZHJfY2VsbHMp OworCQlvZmZzZXQgKz0gcm9vdF9hZGRyX2NlbGxzICogc2l6ZW9mKHVpbnQzMl90KTsKKworCQlk dGJfZXh0cmFjdF9pbnRfcHJvcGVydHkoJnNpemUsIHJlZyArIG9mZnNldCwKKwkJCQkJIHJvb3Rf c2l6ZV9jZWxscyk7CisKKwkJcmV0ID0gZHRiX2FkZF9tZW1vcnlfcmFuZ2UobWVtX3Jhbmdlcywg YWRkciwKKwkJCQkJICAgYWRkciArIHNpemUsIHR5cGUpOworCQlpZiAocmV0KQorCQkJcmV0dXJu IHJldDsKKwl9CisKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIGludCBkdGJfcGFyc2VfbWVtb3J5 X3Jlc2VydmF0aW9uc190YWJsZShjaGFyICpkdGIsIHN0cnVjdCBtZW1vcnlfcmFuZ2VzICptZW1f cmFuZ2VzKQoreworCWludCB0b3RhbF9tZW1yc3J2ID0gMDsKKwl1aW50NjRfdCBhZGRyID0gMDsK Kwl1aW50NjRfdCBzaXplID0gMDsKKwlpbnQgcmV0ID0gMDsKKwlpbnQgaSA9IDA7CisKKwl0b3Rh bF9tZW1yc3J2ID0gZmR0X251bV9tZW1fcnN2KGR0Yik7CisJZm9yIChpID0gMDsgaSA8IHRvdGFs X21lbXJzcnY7IGkrKykgeworCQlyZXQgPSBmZHRfZ2V0X21lbV9yc3YoZHRiLCBpLCAmYWRkciwg JnNpemUpOworCQlpZiAocmV0KQorCQkJY29udGludWU7CisJCXJldCA9IGR0Yl9hZGRfbWVtb3J5 X3JhbmdlKG1lbV9yYW5nZXMsIGFkZHIsIGFkZHIgKyBzaXplIC0gMSwKKwkJCQkJICAgUkFOR0Vf UkVTRVJWRUQpOworCQlpZiAocmV0KQorCQkJcmV0dXJuIHJldDsKKwl9CisKKwlyZXR1cm4gMDsK K30KKworc3RhdGljIGludCBkdGJfZ2V0X3Jlc2VydmVkX21lbW9yeV9ub2RlKGNoYXIgKmR0YikK K3sKKwl1aW50MzJfdCByb290X2FkZHJfY2VsbHMgPSAwOworCXVpbnQzMl90IHJvb3Rfc2l6ZV9j ZWxscyA9IDA7CisJdWludDMyX3QgYWRkcl9jZWxscyA9IDA7CisJdWludDMyX3Qgc2l6ZV9jZWxs cyA9IDA7CisJaW50IHByb3Bfc2l6ZSA9IDA7CisJaW50IG5vZGVvZmZzZXQgPSAwOworCWludCBy ZXQgPSAwOworCisJLyogR2V0IGFkZHJlc3MgLyBzaXplIGNlbGxzIGZyb20gcm9vdCBub2RlICov CisJcmV0ID0gZHRiX2dldF9udW1fY2VsbHMoZHRiLCAwLCAmcm9vdF9hZGRyX2NlbGxzLCAmcm9v dF9zaXplX2NlbGxzLCBmYWxzZSk7CisJaWYgKHJldCA8IDApIHsKKwkJZGJncHJpbnRmKCJObyBh ZGRyZXNzL3NpemUgY2VsbHMgb24gcm9vdCBub2RlICFcbiIpOworCQlyZXR1cm4gcmV0OworCX0K KworCS8qIFRoaXMgY2FsbHMgZmR0X25leHRfbm9kZSBpbnRlcm5hbHkgKi8KKwlub2Rlb2Zmc2V0 ID0gZmR0X3N1Ym5vZGVfb2Zmc2V0KGR0YiwgMCwgInJlc2VydmVkLW1lbW9yeSIpOworCWlmIChu b2Rlb2Zmc2V0ID09IC1GRFRfRVJSX05PVEZPVU5EKSB7CisJCXJldHVybiBub2Rlb2Zmc2V0Owor CX0gZWxzZSBpZiAobm9kZW9mZnNldCA8IDApIHsKKwkJZGJncHJpbnRmKCJFcnJvciB3aGlsZSBs b29raW5nIGZvciByZXNlcnZlZC1tZW1vcnk6ICVzXG4iLAorCQkJZmR0X3N0cmVycm9yKG5vZGVv ZmZzZXQpKTsKKwkJcmV0dXJuIG5vZGVvZmZzZXQ7CisJfQorCisJLyogTG9vayBmb3IgdGhlIHJh bmdlcyBwcm9wZXJ0eSAqLworCWZkdF9nZXRwcm9wKGR0Yiwgbm9kZW9mZnNldCwgInJhbmdlcyIs ICZwcm9wX3NpemUpOworCWlmIChwcm9wX3NpemUgPCAwKSB7CisJCWZwcmludGYoc3RkZXJyLCAi TWFsZm9ybWVkIHJlc2VydmVkLW1lbW9yeSBub2RlIChubyByYW5nZXMgcHJvcGVydHkpICFcbiIp OworCQlyZXR1cm4gLUVJTlZBTDsKKwl9CisKKwkvKiBWZXJpZnkgYWRkcmVzcy1jZWxscyAvIHNp emUtY2VsbHMgKi8KKwlyZXQgPSBkdGJfZ2V0X251bV9jZWxscyhkdGIsIG5vZGVvZmZzZXQsICZh ZGRyX2NlbGxzLCAmc2l6ZV9jZWxscywgZmFsc2UpOworCWlmIChyZXQgPCAwKSB7CisJCWRiZ3By aW50ZigiTm8gYWRkcmVzcy9zaXplIGNlbGxzIHByb3BlcnR5IG9uIHJlc2VydmVkLW1lbW9yeSBu b2RlXG4iKTsKKwkJcmV0dXJuIHJldDsKKwl9CisKKwlpZiAoYWRkcl9jZWxscyAhPSByb290X2Fk ZHJfY2VsbHMpIHsKKwkJZnByaW50ZihzdGRlcnIsICJJbnZhbGlkICNhZGRyZXNzLWNlbGxzIHBy b3BlcnR5IG9uIHJlc2VydmVkLW1lbW9yeSBub2RlXG4iKTsKKwkJcmV0dXJuIC1FSU5WQUw7CisJ fQorCisJaWYgKHNpemVfY2VsbHMgIT0gcm9vdF9zaXplX2NlbGxzKSB7CisJCWZwcmludGYoc3Rk ZXJyLCAiSW52YWxpZCAjc2l6ZS1jZWxscyBwcm9wZXJ0eSBvbiByZXNlcnZlZC1tZW1vcnkgbm9k ZVxuIik7CisJCXJldHVybiAtRUlOVkFMOworCisJfQorCisJcmV0dXJuIG5vZGVvZmZzZXQ7Cit9 CisKK3N0YXRpYyBpbnQgZHRiX3BhcnNlX3Jlc2VydmVkX21lbW9yeV9ub2RlKGNoYXIgKmR0Yiwg c3RydWN0IG1lbW9yeV9yYW5nZXMgKm1lbV9yYW5nZXMpCit7CisJaW50IG5vZGVvZmZzZXQgPSAw OworCWludCBub2RlX2RlcHRoID0gMDsKKwlpbnQgcGFyZW50X2RlcHRoID0gMDsKKwlpbnQgcmV0 ID0gMDsKKworCW5vZGVvZmZzZXQgPSBkdGJfZ2V0X3Jlc2VydmVkX21lbW9yeV9ub2RlKGR0Yik7 CisJaWYgKG5vZGVvZmZzZXQgPT0gLUZEVF9FUlJfTk9URk9VTkQpCisJCXJldHVybiAwOworCWVs c2UgaWYgKG5vZGVvZmZzZXQgPCAwKQorCQlyZXR1cm4gbm9kZW9mZnNldDsKKworCS8qIEdvdCB0 aGUgcGFyZW50IG5vZGUsIGNoZWNrIGZvciBzdWItbm9kZXMgKi8KKworCS8qIGZkdF9uZXh0X25v ZGUoKSBpbmNyZWFzZXMgb3IgZGVjcmVhc2VzIGRlcHRoICovCisJbm9kZV9kZXB0aCA9IHBhcmVu dF9kZXB0aDsKKwlub2Rlb2Zmc2V0ID0gZmR0X25leHRfbm9kZShkdGIsIG5vZGVvZmZzZXQsICZu b2RlX2RlcHRoKTsKKwlpZiAocmV0IDwgMCkgeworCQlkYmdwcmludGYoIlVuYWJsZSB0byBnZXQg bmV4dCBub2RlOiAlc1xuIiwKKwkJCSAgZmR0X3N0cmVycm9yKHJldCkpOworCQlyZXR1cm4gLUVJ TlZBTDsKKwl9CisKKwl3aGlsZSAobm9kZV9kZXB0aCAhPSBwYXJlbnRfZGVwdGgpIHsKKworCQly ZXQgPSBkdGJfYWRkX21lbW9yeV9yZWdpb24oZHRiLCBub2Rlb2Zmc2V0LAorCQkJCQkgICAgbWVt X3JhbmdlcywgUkFOR0VfUkVTRVJWRUQpOworCQlpZiAocmV0KQorCQkJcmV0dXJuIHJldDsKKwor CQlub2Rlb2Zmc2V0ID0gZmR0X25leHRfbm9kZShkdGIsIG5vZGVvZmZzZXQsICZub2RlX2RlcHRo KTsKKwkJaWYgKHJldCA8IDApIHsKKwkJCWRiZ3ByaW50ZigiVW5hYmxlIHRvIGdldCBuZXh0IG5v ZGU6ICVzXG4iLAorCQkJCSAgZmR0X3N0cmVycm9yKHJldCkpOworCQkJcmV0dXJuIC1FSU5WQUw7 CisJCX0KKwl9CisKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIGludCBkdGJfcGFyc2VfbWVtb3J5 X25vZGVzKGNoYXIgKmR0Yiwgc3RydWN0IG1lbW9yeV9yYW5nZXMgKm1lbV9yYW5nZXMpCit7CisJ aW50IG5vZGVvZmZzZXQgPSAwOworCWludCBudW1fcmVnaW9ucyA9IDA7CisJY29uc3QgY2hhciog ZGV2X3R5cGUgPSAwOworCWludCBwcm9wX3NpemUgPSAwOworCWludCByZXQgPSAwOworCisJZm9y ICg7IDsgbnVtX3JlZ2lvbnMrKykgeworCQlub2Rlb2Zmc2V0ID0gZmR0X3N1Ym5vZGVfb2Zmc2V0 KGR0Yiwgbm9kZW9mZnNldCwKKwkJCQkJCSAibWVtb3J5Iik7CisJCWlmIChub2Rlb2Zmc2V0IDwg MCkKKwkJCWJyZWFrOworCisJCWRiZ3ByaW50ZigiR290IG1lbW9yeSBub2RlIGF0IGRlcHRoOiAl aVxuIiwgZmR0X25vZGVfZGVwdGgoZHRiLCBub2Rlb2Zmc2V0KSk7CisKKwkJLyogTG9vayBmb3Ig dGhlIGRldmljZV90eXBlICBwcm9wZXJ0eSAqLworCQlkZXZfdHlwZSA9IGZkdF9nZXRwcm9wKGR0 Yiwgbm9kZW9mZnNldCwgImRldmljZV90eXBlIiwgJnByb3Bfc2l6ZSk7CisJCWlmIChwcm9wX3Np emUgPCAwKSB7CisJCQlmcHJpbnRmKHN0ZGVyciwgIk1hbGZvcm1lZCAvbWVtb3J5IG5vZGUgKG5v IGRldmljZS10eXBlIHByb3BlcnR5KSAhXG4iKTsKKwkJCXJldHVybiAtRUlOVkFMOworCQl9CisK KwkJaWYgKHN0cm5jbXAoZGV2X3R5cGUsICJtZW1vcnkiLCBwcm9wX3NpemUpKSB7CisJCQlkYmdw cmludGYoIkdvdCB1bmtub3duIGRldl90eXBlIHByb3BlcnR5OiAlc1xuIiwgZGV2X3R5cGUpOwor CQkJY29udGludWU7CisJCX0KKworCQlyZXQgPSBkdGJfYWRkX21lbW9yeV9yZWdpb24oZHRiLCBu b2Rlb2Zmc2V0LCBtZW1fcmFuZ2VzLCBSQU5HRV9SQU0pOworCQlpZiAocmV0KQorCQkJcmV0dXJu IHJldDsKKwl9CisKKwlpZiAoIW51bV9yZWdpb25zKSB7CisJCWRiZ3ByaW50ZigiTWFsZm9ybWVk IGR0Yiwgbm8gL21lbW9yeSBub2RlcyBwcmVzZW50ICFcbiIpOworCQlyZXR1cm4gLUVJTlZBTDsK Kwl9CisKKwlkYmdwcmludGYoIkdvdCAlaSAvbWVtb3J5IG5vZGVzXG4iLCBudW1fcmVnaW9ucyk7 CisKKwlyZXR1cm4gMDsKK30KKworaW50IGR0Yl9nZXRfbWVtb3J5X3JhbmdlcyhjaGFyICpkdGIs IHN0cnVjdCBtZW1vcnlfcmFuZ2VzICptZW1fcmFuZ2VzLCBzdHJ1Y3QgbWVtb3J5X3JhbmdlcyAq ZXh0cmFfcmFuZ2VzKQoreworCWludCBpID0gMDsKKwlpbnQgcmV0ID0gMDsKKworCS8qIEZpbGwg bWVtX3Jhbmdlc1tdIGJ5IHBhcnNpbmcgdGhlIGRldmljZSB0cmVlICovCisJcmV0ID0gZHRiX3Bh cnNlX21lbW9yeV9ub2RlcyhkdGIsIG1lbV9yYW5nZXMpOworCWlmIChyZXQpCisJCXJldHVybiBy ZXQ7CisKKwlyZXQgPSBkdGJfcGFyc2VfbWVtb3J5X3Jlc2VydmF0aW9uc190YWJsZShkdGIsIG1l bV9yYW5nZXMpOworCWlmIChyZXQpCisJCXJldHVybiByZXQ7CisKKwlyZXQgPSBkdGJfcGFyc2Vf cmVzZXJ2ZWRfbWVtb3J5X25vZGUoZHRiLCBtZW1fcmFuZ2VzKTsKKwlpZiAocmV0KQorCQlyZXR1 cm4gcmV0OworCisJLyogQXBwZW5kIGFueSBleHRyYSByYW5nZXMgcHJvdmlkZWQgYnkgdGhlIGNh bGxlciAoZS5nLiBpbml0cmQpICovCisJZm9yIChpID0gMDsgZXh0cmFfcmFuZ2VzICE9IE5VTEwg JiYgaSA8IGV4dHJhX3Jhbmdlcy0+c2l6ZTsgaSsrKSB7CisJCWRiZ3ByaW50ZigiQWRkaW5nIGV4 dHJhIHJhbmdlOiAweCVsbHggLSAweCVsbHggKCVzKVxuIiwKKwkJCSAgZXh0cmFfcmFuZ2VzLT5y YW5nZXNbaV0uc3RhcnQsCisJCQkgIGV4dHJhX3Jhbmdlcy0+cmFuZ2VzW2ldLmVuZCwKKwkJCSAg ZXh0cmFfcmFuZ2VzLT5yYW5nZXNbaV0udHlwZSA9PSBSQU5HRV9SRVNFUlZFRCA/CisgICAgICAg ICAgICAgICAgICAgICAgICAgICJSQU5HRV9SRVNFUlZFRCIgOiAiUkFOR0VfUkFNIik7CisKKwkJ cmV0ID0gZHRiX2FkZF9tZW1vcnlfcmFuZ2UobWVtX3JhbmdlcywgZXh0cmFfcmFuZ2VzLT5yYW5n ZXNbaV0uc3RhcnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dHJhX3Jhbmdl cy0+cmFuZ2VzW2ldLmVuZCwgZXh0cmFfcmFuZ2VzLT5yYW5nZXNbaV0udHlwZSk7CisJCWlmIChy ZXQpCisJCQlyZXR1cm4gcmV0OworCX0KKworCW1lbV9yZWdpb25zX3NvcnQobWVtX3Jhbmdlcyk7 CisKKwlyZXR1cm4gMDsKK30KZGlmZiAtLWdpdCBhL2tleGVjL2R0LW9wcy5oIGIva2V4ZWMvZHQt b3BzLmgKaW5kZXggMDM2NTljZTI4M2RiLi4zMDE0MjA1ZDhlOTggMTAwNjQ0Ci0tLSBhL2tleGVj L2R0LW9wcy5oCisrKyBiL2tleGVjL2R0LW9wcy5oCkBAIC0xMSw0ICsxMSwxMSBAQCBpbnQgZHRi X3NldF9wcm9wZXJ0eShjaGFyICoqZHRiLCBvZmZfdCAqZHRiX3NpemUsIGNvbnN0IGNoYXIgKm5v ZGUsCiAKIGludCBkdGJfZGVsZXRlX3Byb3BlcnR5KGNoYXIgKmR0YiwgY29uc3QgY2hhciAqbm9k ZSwgY29uc3QgY2hhciAqcHJvcCk7CiAKK3ZvaWQgZHRiX2V4dHJhY3RfaW50X3Byb3BlcnR5KHVp bnQ2NF90ICp2YWwsIGNvbnN0IHZvaWQgKmJ1ZiwgdWludDMyX3QgY2VsbHMpOwordm9pZCBkdGJf ZmlsbF9pbnRfcHJvcGVydHkodm9pZCAqYnVmLCB1aW50NjRfdCB2YWwsIHVpbnQzMl90IGNlbGxz KTsKK2ludCBkdGJfYWRkX3JhbmdlX3Byb3BlcnR5KGNoYXIgKipkdGIsIG9mZl90ICpkdGJfc2l6 ZSwgdWludDY0X3Qgc3RhcnQsIHVpbnQ2NF90IGVuZCwKKyAgICAgICAgICAgICAgICAgICAgICAg ICAgIGNvbnN0IGNoYXIgKm5vZGUsIGNvbnN0IGNoYXIqIHBhcmVudCk7CitpbnQgZHRiX2dldF9t ZW1vcnlfcmFuZ2VzKGNoYXIgKmR0Yiwgc3RydWN0IG1lbW9yeV9yYW5nZXMgKm1lbV9yYW5nZXMs CisJCQkgIHN0cnVjdCBtZW1vcnlfcmFuZ2VzICpleHRyYV9yYW5nZXMpOworCiAjZW5kaWYKZGlm ZiAtLWdpdCBhL2tleGVjL2tleGVjLXN5c2NhbGwuaCBiL2tleGVjL2tleGVjLXN5c2NhbGwuaApp bmRleCBjYzMyYzAxNjJhZWMuLjg5NTkxYWQxN2U3ZCAxMDA2NDQKLS0tIGEva2V4ZWMva2V4ZWMt c3lzY2FsbC5oCisrKyBiL2tleGVjL2tleGVjLXN5c2NhbGwuaApAQCAtMTQwLDYgKzE0MCw3IEBA IHN0YXRpYyBpbmxpbmUgbG9uZyBrZXhlY19maWxlX2xvYWQoaW50IGtlcm5lbF9mZCwgaW50IGlu aXRyZF9mZCwKICNkZWZpbmUgS0VYRUNfQVJDSF9NSVBTX0xFICgxMCA8PCAxNikKICNkZWZpbmUg S0VYRUNfQVJDSF9NSVBTICAgICggOCA8PCAxNikKICNkZWZpbmUgS0VYRUNfQVJDSF9DUklTICAg ICg3NiA8PCAxNikKKyNkZWZpbmUgS0VYRUNfQVJDSF9SSVNDViAgICgyNDMgPDwgMTYpCiAjZGVm aW5lIEtFWEVDX0FSQ0hfTE9PTkdBUkNICSgyNTggPDwgMTYpCiAKICNkZWZpbmUgS0VYRUNfTUFY X1NFR01FTlRTIDE2CkBAIC0xODcsNSArMTg4LDggQEAgc3RhdGljIGlubGluZSBsb25nIGtleGVj X2ZpbGVfbG9hZChpbnQga2VybmVsX2ZkLCBpbnQgaW5pdHJkX2ZkLAogI2lmIGRlZmluZWQoX19s b29uZ2FyY2hfXykKICNkZWZpbmUgS0VYRUNfQVJDSF9OQVRJVkUJS0VYRUNfQVJDSF9MT09OR0FS Q0gKICNlbmRpZgorI2lmIGRlZmluZWQoX19yaXNjdl9fKSB8fCBkZWZpbmVkKF9fcmlzY3YpCisj ZGVmaW5lIEtFWEVDX0FSQ0hfTkFUSVZFCUtFWEVDX0FSQ0hfUklTQ1YKKyNlbmRpZgogCiAjZW5k aWYgLyogS0VYRUNfU1lTQ0FMTF9IICovCmRpZmYgLS1naXQgYS9wdXJnYXRvcnkvTWFrZWZpbGUg Yi9wdXJnYXRvcnkvTWFrZWZpbGUKaW5kZXggNGQyZDA3MTM0YmQ1Li43ZDExNzVmMjQ0NWMgMTAw NjQ0Ci0tLSBhL3B1cmdhdG9yeS9NYWtlZmlsZQorKysgYi9wdXJnYXRvcnkvTWFrZWZpbGUKQEAg LTI1LDYgKzI1LDcgQEAgaW5jbHVkZSAkKHNyY2RpcikvcHVyZ2F0b3J5L2FyY2gvaWE2NC9NYWtl ZmlsZQogaW5jbHVkZSAkKHNyY2RpcikvcHVyZ2F0b3J5L2FyY2gvbWlwcy9NYWtlZmlsZQogaW5j bHVkZSAkKHNyY2RpcikvcHVyZ2F0b3J5L2FyY2gvcHBjL01ha2VmaWxlCiBpbmNsdWRlICQoc3Jj ZGlyKS9wdXJnYXRvcnkvYXJjaC9wcGM2NC9NYWtlZmlsZQoraW5jbHVkZSAkKHNyY2RpcikvcHVy Z2F0b3J5L2FyY2gvcmlzY3YvTWFrZWZpbGUKIGluY2x1ZGUgJChzcmNkaXIpL3B1cmdhdG9yeS9h cmNoL3MzOTAvTWFrZWZpbGUKIGluY2x1ZGUgJChzcmNkaXIpL3B1cmdhdG9yeS9hcmNoL3NoL01h a2VmaWxlCiBpbmNsdWRlICQoc3JjZGlyKS9wdXJnYXRvcnkvYXJjaC94ODZfNjQvTWFrZWZpbGUK ZGlmZiAtLWdpdCBhL3B1cmdhdG9yeS9hcmNoL3Jpc2N2L01ha2VmaWxlIGIvcHVyZ2F0b3J5L2Fy Y2gvcmlzY3YvTWFrZWZpbGUKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMDAwMDAw Li40OWE2ZmVmNGE5MDQKLS0tIC9kZXYvbnVsbAorKysgYi9wdXJnYXRvcnkvYXJjaC9yaXNjdi9N YWtlZmlsZQpAQCAtMCwwICsxLDcgQEAKKyMKKyMgUHVyZ2F0b3J5IHJpc2N2CisjCisKK3Jpc2N2 X1BVUkdBVE9SWV9TUkNTID0KKworZGlzdCArPSBwdXJnYXRvcnkvYXJjaC9yaXNjdi9NYWtlZmls ZSAkKHJpc2N2X1BVUkdBVE9SWV9TUkNTKQotLSAKMi40NS4yCgoKX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbGludXgtcmlzY3YgbWFpbGluZyBsaXN0Cmxp bnV4LXJpc2N2QGxpc3RzLmluZnJhZGVhZC5vcmcKaHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcv bWFpbG1hbi9saXN0aW5mby9saW51eC1yaXNjdgo=