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 X-Spam-Level: X-Spam-Status: No, score=-17.4 required=3.0 tests=DKIMWL_WL_MED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 65A68C33C9E for ; Mon, 3 Feb 2020 04:23:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 005BD20661 for ; Mon, 3 Feb 2020 04:23:00 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="JNorMbU7" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727409AbgBCEXA (ORCPT ); Sun, 2 Feb 2020 23:23:00 -0500 Received: from mail-qt1-f202.google.com ([209.85.160.202]:41642 "EHLO mail-qt1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727164AbgBCEW7 (ORCPT ); Sun, 2 Feb 2020 23:22:59 -0500 Received: by mail-qt1-f202.google.com with SMTP id a13so9166852qtp.8 for ; Sun, 02 Feb 2020 20:22:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:message-id:mime-version:subject:from:to:cc :content-transfer-encoding; bh=X6VO2mdbhKE5o6DYiR8xP596jvUpUwQpg4b1gjaIEUk=; b=JNorMbU7Vyou3YsqDQGhq1Ao+TscpvwaHeU9pmfxwsbwvHXweYHzWu2mIgPkmaDTs5 6pEtHjMKZli1sBJvBm27a7RW45OGdfjjPj6UC6Wc6C8NolA/KNp7HAuBZ4KTdR879hn9 tvcbILA6D5XHaLt7ydcgALDSSug4rGRrpN8wGVUB5/K2u1IAzPpCaRMOPeq2awMj6NUq 6pgFcxmA3y6QBqK75AKcWl3U1kUTbJ4t4NGeABogJmBicwd+1R2c0I+uV/ELh2AGC4as DQt8DGUEPY7VKwfRr7y3QVbXyAkW19JJT+F0khBY3n0jF+ucsPqfILuMkJnLOymXHLDq 0fog== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:message-id:mime-version:subject:from:to:cc :content-transfer-encoding; bh=X6VO2mdbhKE5o6DYiR8xP596jvUpUwQpg4b1gjaIEUk=; b=WzkMzuNq8rD10TyjlK+vN/HvL+nDCYRacqlu5aaOVcHL6U9PGLrk7YTy6soTkqOoVD 0Fc8Otip6dhx5AKQUePJ1XVGZUzQSoAB28VB5kgVLgc+OZ6rc8cuVXuCJdwrbO+9BgWz j5/I13+5msZmEh/Y5lA1LLWQaNA84ZH7f6cwpyZgCHLND+GqZNawlC8vJxlN9voeDwjv 2CtMVk6HEj/nfhlzhUGGEFa8zZ+v1m/3lpr8sPIjk8YklwNOzkoBEwLpXtvJ9GX4S9gc /Gh63iLkfg1VgA5pzgJGKSOeqGX0b87t33dRSqebryqYSjyQvftPLHe67BGn9a/reNY3 01tA== X-Gm-Message-State: APjAAAX7MTrmWVDWib4RxpniscXuNfW6ntFCaqUcvNf+GDpN1hS8F5UL y+IjU1A5UikghoYDdNgOkUSb8bui0ZtdTHagouS5e4E5e5OiFmrEZAkz98o98Fi2cISImq9VRc6 WttC0dKC9eMAxGY6cUepaqoij3rfrVfRdY8Pot7NsRR6ywz3b0rmUoUWKyhIS9lHCoaPzvQ== X-Google-Smtp-Source: APXvYqzc7SF8KOm+AnEfNqc549HVOwwRQ4ijZ4mu8EgJ2ec4bhG6TrWRpD7WizBUKA9cb4FJcXd1j0HBRHQ= X-Received: by 2002:a0c:db8c:: with SMTP id m12mr20507624qvk.154.1580703777266; Sun, 02 Feb 2020 20:22:57 -0800 (PST) Date: Sun, 2 Feb 2020 20:22:54 -0800 Message-Id: <20200203042254.80360-1-adelva@google.com> Mime-Version: 1.0 X-Mailer: git-send-email 2.25.0.341.g760bfbb309-goog Subject: [PATCH] staging: android: Delete the 'vsoc' driver From: Alistair Delva To: linux-kernel@vger.kernel.org, cloud-android-devs@google.com Cc: Greg Kroah-Hartman , Joel Fernandes , Greg Hartman , kernel-team@android.com, devel@driverdev.osuosl.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The 'vsoc' driver was required for an early iteration of the Android 'cuttlefish' virtual platform, but this platform has been wholly converted to use virtio drivers instead. Delete this old driver. Cc: Greg Kroah-Hartman Cc: Joel Fernandes Cc: Greg Hartman Cc: kernel-team@android.com Cc: devel@driverdev.osuosl.org Signed-off-by: Alistair Delva --- drivers/staging/android/Kconfig | 8 - drivers/staging/android/Makefile | 1 - drivers/staging/android/TODO | 9 - drivers/staging/android/uapi/vsoc_shm.h | 295 ------ drivers/staging/android/vsoc.c | 1149 ----------------------- 5 files changed, 1462 deletions(-) delete mode 100644 drivers/staging/android/uapi/vsoc_shm.h delete mode 100644 drivers/staging/android/vsoc.c diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kcon= fig index d6d605d5cbde..8d8fd5c29349 100644 --- a/drivers/staging/android/Kconfig +++ b/drivers/staging/android/Kconfig @@ -14,14 +14,6 @@ config ASHMEM It is, in theory, a good memory allocator for low-memory devices, because it can discard shared memory units when under memory pressure. =20 -config ANDROID_VSOC - tristate "Android Virtual SoC support" - depends on PCI_MSI - help - This option adds support for the Virtual SoC driver needed to boot - a 'cuttlefish' Android image inside QEmu. The driver interacts with - a QEmu ivshmem device. If built as a module, it will be called vsoc. - source "drivers/staging/android/ion/Kconfig" =20 endif # if ANDROID diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Mak= efile index 14bd9c6ce10d..3b66cd0b0ec5 100644 --- a/drivers/staging/android/Makefile +++ b/drivers/staging/android/Makefile @@ -4,4 +4,3 @@ ccflags-y +=3D -I$(src) # needed for trace events obj-y +=3D ion/ =20 obj-$(CONFIG_ASHMEM) +=3D ashmem.o -obj-$(CONFIG_ANDROID_VSOC) +=3D vsoc.o diff --git a/drivers/staging/android/TODO b/drivers/staging/android/TODO index 767dd98fd92d..80eccfaf6db5 100644 --- a/drivers/staging/android/TODO +++ b/drivers/staging/android/TODO @@ -9,14 +9,5 @@ ion/ - Split /dev/ion up into multiple nodes (e.g. /dev/ion/heap0) - Better test framework (integration with VGEM was suggested) =20 -vsoc.c, uapi/vsoc_shm.h - - The current driver uses the same wait queue for all of the futexes in a - region. This will cause false wakeups in regions with a large number of - waiting threads. We should eventually use multiple queues and select th= e - queue based on the region. - - Add debugfs support for examining the permissions of regions. - - Remove VSOC_WAIT_FOR_INCOMING_INTERRUPT ioctl. This functionality has b= een - superseded by the futex and is there for legacy reasons. - Please send patches to Greg Kroah-Hartman and Cc: Arve Hj=C3=B8nnev=C3=A5g and Riley Andrews diff --git a/drivers/staging/android/uapi/vsoc_shm.h b/drivers/staging/andr= oid/uapi/vsoc_shm.h deleted file mode 100644 index 6291fb24efb2..000000000000 --- a/drivers/staging/android/uapi/vsoc_shm.h +++ /dev/null @@ -1,295 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (C) 2017 Google, Inc. - * - */ - -#ifndef _UAPI_LINUX_VSOC_SHM_H -#define _UAPI_LINUX_VSOC_SHM_H - -#include - -/** - * A permission is a token that permits a receiver to read and/or write an= area - * of memory within a Vsoc region. - * - * An fd_scoped permission grants both read and write access, and can be - * attached to a file description (see open(2)). - * Ownership of the area can then be shared by passing a file descriptor - * among processes. - * - * begin_offset and end_offset define the area of memory that is controlle= d by - * the permission. owner_offset points to a word, also in shared memory, t= hat - * controls ownership of the area. - * - * ownership of the region expires when the associated file description is - * released. - * - * At most one permission can be attached to each file description. - * - * This is useful when implementing HALs like gralloc that scope and pass - * ownership of shared resources via file descriptors. - * - * The caller is responsibe for doing any fencing. - * - * The calling process will normally identify a currently free area of - * memory. It will construct a proposed fd_scoped_permission_arg structure= : - * - * begin_offset and end_offset describe the area being claimed - * - * owner_offset points to the location in shared memory that indicates t= he - * owner of the area. - * - * owned_value is the value that will be stored in owner_offset iff the - * permission can be granted. It must be different than VSOC_REGION_FREE= . - * - * Two fd_scoped_permission structures are compatible if they vary only by - * their owned_value fields. - * - * The driver ensures that, for any group of simultaneous callers proposin= g - * compatible fd_scoped_permissions, it will accept exactly one of the - * propopsals. The other callers will get a failure with errno of EAGAIN. - * - * A process receiving a file descriptor can identify the region being - * granted using the VSOC_GET_FD_SCOPED_PERMISSION ioctl. - */ -struct fd_scoped_permission { - __u32 begin_offset; - __u32 end_offset; - __u32 owner_offset; - __u32 owned_value; -}; - -/* - * This value represents a free area of memory. The driver expects to see = this - * value at owner_offset when creating a permission otherwise it will not = do it, - * and will write this value back once the permission is no longer needed. - */ -#define VSOC_REGION_FREE ((__u32)0) - -/** - * ioctl argument for VSOC_CREATE_FD_SCOPE_PERMISSION - */ -struct fd_scoped_permission_arg { - struct fd_scoped_permission perm; - __s32 managed_region_fd; -}; - -#define VSOC_NODE_FREE ((__u32)0) - -/* - * Describes a signal table in shared memory. Each non-zero entry in the - * table indicates that the receiver should signal the futex at the given - * offset. Offsets are relative to the region, not the shared memory windo= w. - * - * interrupt_signalled_offset is used to reliably signal interrupts across= the - * vmm boundary. There are two roles: transmitter and receiver. For exampl= e, - * in the host_to_guest_signal_table the host is the transmitter and the - * guest is the receiver. The protocol is as follows: - * - * 1. The transmitter should convert the offset of the futex to an offset - * in the signal table [0, (1 << num_nodes_lg2)) - * The transmitter can choose any appropriate hashing algorithm, includ= ing - * hash =3D futex_offset & ((1 << num_nodes_lg2) - 1) - * - * 3. The transmitter should atomically compare and swap futex_offset with= 0 - * at hash. There are 3 possible outcomes - * a. The swap fails because the futex_offset is already in the table= . - * The transmitter should stop. - * b. Some other offset is in the table. This is a hash collision. Th= e - * transmitter should move to another table slot and try again. On= e - * possible algorithm: - * hash =3D (hash + 1) & ((1 << num_nodes_lg2) - 1) - * c. The swap worked. Continue below. - * - * 3. The transmitter atomically swaps 1 with the value at the - * interrupt_signalled_offset. There are two outcomes: - * a. The prior value was 1. In this case an interrupt has already be= en - * posted. The transmitter is done. - * b. The prior value was 0, indicating that the receiver may be slee= ping. - * The transmitter will issue an interrupt. - * - * 4. On waking the receiver immediately exchanges a 0 with the - * interrupt_signalled_offset. If it receives a 0 then this a spurious - * interrupt. That may occasionally happen in the current protocol, but - * should be rare. - * - * 5. The receiver scans the signal table by atomicaly exchanging 0 at eac= h - * location. If a non-zero offset is returned from the exchange the - * receiver wakes all sleepers at the given offset: - * futex((int*)(region_base + old_value), FUTEX_WAKE, MAX_INT); - * - * 6. The receiver thread then does a conditional wait, waking immediately - * if the value at interrupt_signalled_offset is non-zero. This catches= cases - * here additional signals were posted while the table was being scann= ed. - * On the guest the wait is handled via the VSOC_WAIT_FOR_INCOMING_INTE= RRUPT - * ioctl. - */ -struct vsoc_signal_table_layout { - /* log_2(Number of signal table entries) */ - __u32 num_nodes_lg2; - /* - * Offset to the first signal table entry relative to the start of the - * region - */ - __u32 futex_uaddr_table_offset; - /* - * Offset to an atomic_t / atomic uint32_t. A non-zero value indicates - * that one or more offsets are currently posted in the table. - * semi-unique access to an entry in the table - */ - __u32 interrupt_signalled_offset; -}; - -#define VSOC_REGION_WHOLE ((__s32)0) -#define VSOC_DEVICE_NAME_SZ 16 - -/** - * Each HAL would (usually) talk to a single device region - * Mulitple entities care about these regions: - * - The ivshmem_server will populate the regions in shared memory - * - The guest kernel will read the region, create minor device nodes, and - * allow interested parties to register for FUTEX_WAKE events in the reg= ion - * - HALs will access via the minor device nodes published by the guest ke= rnel - * - Host side processes will access the region via the ivshmem_server: - * 1. Pass name to ivshmem_server at a UNIX socket - * 2. ivshmemserver will reply with 2 fds: - * - host->guest doorbell fd - * - guest->host doorbell fd - * - fd for the shared memory region - * - region offset - * 3. Start a futex receiver thread on the doorbell fd pointed at the - * signal_nodes - */ -struct vsoc_device_region { - __u16 current_version; - __u16 min_compatible_version; - __u32 region_begin_offset; - __u32 region_end_offset; - __u32 offset_of_region_data; - struct vsoc_signal_table_layout guest_to_host_signal_table; - struct vsoc_signal_table_layout host_to_guest_signal_table; - /* Name of the device. Must always be terminated with a '\0', so - * the longest supported device name is 15 characters. - */ - char device_name[VSOC_DEVICE_NAME_SZ]; - /* There are two ways that permissions to access regions are handled: - * - When subdivided_by is VSOC_REGION_WHOLE, any process that can - * open the device node for the region gains complete access to it. - * - When subdivided is set processes that open the region cannot - * access it. Access to a sub-region must be established by invoking - * the VSOC_CREATE_FD_SCOPE_PERMISSION ioctl on the region - * referenced in subdivided_by, providing a fileinstance - * (represented by a fd) opened on this region. - */ - __u32 managed_by; -}; - -/* - * The vsoc layout descriptor. - * The first 4K should be reserved for the shm header and region descripto= rs. - * The regions should be page aligned. - */ - -struct vsoc_shm_layout_descriptor { - __u16 major_version; - __u16 minor_version; - - /* size of the shm. This may be redundant but nice to have */ - __u32 size; - - /* number of shared memory regions */ - __u32 region_count; - - /* The offset to the start of region descriptors */ - __u32 vsoc_region_desc_offset; -}; - -/* - * This specifies the current version that should be stored in - * vsoc_shm_layout_descriptor.major_version and - * vsoc_shm_layout_descriptor.minor_version. - * It should be updated only if the vsoc_device_region and - * vsoc_shm_layout_descriptor structures have changed. - * Versioning within each region is transferred - * via the min_compatible_version and current_version fields in - * vsoc_device_region. The driver does not consult these fields: they are = left - * for the HALs and host processes and will change independently of the la= yout - * version. - */ -#define CURRENT_VSOC_LAYOUT_MAJOR_VERSION 2 -#define CURRENT_VSOC_LAYOUT_MINOR_VERSION 0 - -#define VSOC_CREATE_FD_SCOPED_PERMISSION \ - _IOW(0xF5, 0, struct fd_scoped_permission) -#define VSOC_GET_FD_SCOPED_PERMISSION _IOR(0xF5, 1, struct fd_scoped_permi= ssion) - -/* - * This is used to signal the host to scan the guest_to_host_signal_table - * for new futexes to wake. This sends an interrupt if one is not already - * in flight. - */ -#define VSOC_MAYBE_SEND_INTERRUPT_TO_HOST _IO(0xF5, 2) - -/* - * When this returns the guest will scan host_to_guest_signal_table to - * check for new futexes to wake. - */ -/* TODO(ghartman): Consider moving this to the bottom half */ -#define VSOC_WAIT_FOR_INCOMING_INTERRUPT _IO(0xF5, 3) - -/* - * Guest HALs will use this to retrieve the region description after - * opening their device node. - */ -#define VSOC_DESCRIBE_REGION _IOR(0xF5, 4, struct vsoc_device_region) - -/* - * Wake any threads that may be waiting for a host interrupt on this regio= n. - * This is mostly used during shutdown. - */ -#define VSOC_SELF_INTERRUPT _IO(0xF5, 5) - -/* - * This is used to signal the host to scan the guest_to_host_signal_table - * for new futexes to wake. This sends an interrupt unconditionally. - */ -#define VSOC_SEND_INTERRUPT_TO_HOST _IO(0xF5, 6) - -enum wait_types { - VSOC_WAIT_UNDEFINED =3D 0, - VSOC_WAIT_IF_EQUAL =3D 1, - VSOC_WAIT_IF_EQUAL_TIMEOUT =3D 2 -}; - -/* - * Wait for a condition to be true - * - * Note, this is sized and aligned so the 32 bit and 64 bit layouts are - * identical. - */ -struct vsoc_cond_wait { - /* Input: Offset of the 32 bit word to check */ - __u32 offset; - /* Input: Value that will be compared with the offset */ - __u32 value; - /* Monotonic time to wake at in seconds */ - __u64 wake_time_sec; - /* Input: Monotonic time to wait in nanoseconds */ - __u32 wake_time_nsec; - /* Input: Type of wait */ - __u32 wait_type; - /* Output: Number of times the thread woke before returning. */ - __u32 wakes; - /* Ensure that we're 8-byte aligned and 8 byte length for 32/64 bit - * compatibility. - */ - __u32 reserved_1; -}; - -#define VSOC_COND_WAIT _IOWR(0xF5, 7, struct vsoc_cond_wait) - -/* Wake any local threads waiting at the offset given in arg */ -#define VSOC_COND_WAKE _IO(0xF5, 8) - -#endif /* _UAPI_LINUX_VSOC_SHM_H */ diff --git a/drivers/staging/android/vsoc.c b/drivers/staging/android/vsoc.= c deleted file mode 100644 index 1240bb0317d9..000000000000 --- a/drivers/staging/android/vsoc.c +++ /dev/null @@ -1,1149 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * drivers/android/staging/vsoc.c - * - * Android Virtual System on a Chip (VSoC) driver - * - * Copyright (C) 2017 Google, Inc. - * - * Author: ghartman@google.com - * - * Based on drivers/char/kvm_ivshmem.c - driver for KVM Inter-VM shared me= mory - * Copyright 2009 Cam Macdonell - * - * Based on cirrusfb.c and 8139cp.c: - * Copyright 1999-2001 Jeff Garzik - * Copyright 2001-2004 Jeff Garzik - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "uapi/vsoc_shm.h" - -#define VSOC_DEV_NAME "vsoc" - -/* - * Description of the ivshmem-doorbell PCI device used by QEmu. These - * constants follow docs/specs/ivshmem-spec.txt, which can be found in - * the QEmu repository. This was last reconciled with the version that - * came out with 2.8 - */ - -/* - * These constants are determined KVM Inter-VM shared memory device - * register offsets - */ -enum { - INTR_MASK =3D 0x00, /* Interrupt Mask */ - INTR_STATUS =3D 0x04, /* Interrupt Status */ - IV_POSITION =3D 0x08, /* VM ID */ - DOORBELL =3D 0x0c, /* Doorbell */ -}; - -static const int REGISTER_BAR; /* Equal to 0 */ -static const int MAX_REGISTER_BAR_LEN =3D 0x100; -/* - * The MSI-x BAR is not used directly. - * - * static const int MSI_X_BAR =3D 1; - */ -static const int SHARED_MEMORY_BAR =3D 2; - -struct vsoc_region_data { - char name[VSOC_DEVICE_NAME_SZ + 1]; - wait_queue_head_t interrupt_wait_queue; - /* TODO(b/73664181): Use multiple futex wait queues */ - wait_queue_head_t futex_wait_queue; - /* Flag indicating that an interrupt has been signalled by the host. */ - atomic_t *incoming_signalled; - /* Flag indicating the guest has signalled the host. */ - atomic_t *outgoing_signalled; - bool irq_requested; - bool device_created; -}; - -struct vsoc_device { - /* Kernel virtual address of REGISTER_BAR. */ - void __iomem *regs; - /* Physical address of SHARED_MEMORY_BAR. */ - phys_addr_t shm_phys_start; - /* Kernel virtual address of SHARED_MEMORY_BAR. */ - void __iomem *kernel_mapped_shm; - /* Size of the entire shared memory window in bytes. */ - size_t shm_size; - /* - * Pointer to the virtual address of the shared memory layout structure. - * This is probably identical to kernel_mapped_shm, but saving this - * here saves a lot of annoying casts. - */ - struct vsoc_shm_layout_descriptor *layout; - /* - * Points to a table of region descriptors in the kernel's virtual - * address space. Calculated from - * vsoc_shm_layout_descriptor.vsoc_region_desc_offset - */ - struct vsoc_device_region *regions; - /* Head of a list of permissions that have been granted. */ - struct list_head permissions; - struct pci_dev *dev; - /* Per-region (and therefore per-interrupt) information. */ - struct vsoc_region_data *regions_data; - /* - * Table of msi-x entries. This has to be separated from struct - * vsoc_region_data because the kernel deals with them as an array. - */ - struct msix_entry *msix_entries; - /* Mutex that protectes the permission list */ - struct mutex mtx; - /* Major number assigned by the kernel */ - int major; - /* Character device assigned by the kernel */ - struct cdev cdev; - /* Device class assigned by the kernel */ - struct class *class; - /* - * Flags that indicate what we've initialized. These are used to do an - * orderly cleanup of the device. - */ - bool enabled_device; - bool requested_regions; - bool cdev_added; - bool class_added; - bool msix_enabled; -}; - -static struct vsoc_device vsoc_dev; - -/* - * TODO(ghartman): Add a /sys filesystem entry that summarizes the permiss= ions. - */ - -struct fd_scoped_permission_node { - struct fd_scoped_permission permission; - struct list_head list; -}; - -struct vsoc_private_data { - struct fd_scoped_permission_node *fd_scoped_permission_node; -}; - -static long vsoc_ioctl(struct file *, unsigned int, unsigned long); -static int vsoc_mmap(struct file *, struct vm_area_struct *); -static int vsoc_open(struct inode *, struct file *); -static int vsoc_release(struct inode *, struct file *); -static ssize_t vsoc_read(struct file *, char __user *, size_t, loff_t *); -static ssize_t vsoc_write(struct file *, const char __user *, size_t, loff= _t *); -static loff_t vsoc_lseek(struct file *filp, loff_t offset, int origin); -static int -do_create_fd_scoped_permission(struct vsoc_device_region *region_p, - struct fd_scoped_permission_node *np, - struct fd_scoped_permission_arg __user *arg); -static void -do_destroy_fd_scoped_permission(struct vsoc_device_region *owner_region_p, - struct fd_scoped_permission *perm); -static long do_vsoc_describe_region(struct file *, - struct vsoc_device_region __user *); -static ssize_t vsoc_get_area(struct file *filp, __u32 *perm_off); - -/** - * Validate arguments on entry points to the driver. - */ -inline int vsoc_validate_inode(struct inode *inode) -{ - if (iminor(inode) >=3D vsoc_dev.layout->region_count) { - dev_err(&vsoc_dev.dev->dev, - "describe_region: invalid region %d\n", iminor(inode)); - return -ENODEV; - } - return 0; -} - -inline int vsoc_validate_filep(struct file *filp) -{ - int ret =3D vsoc_validate_inode(file_inode(filp)); - - if (ret) - return ret; - if (!filp->private_data) { - dev_err(&vsoc_dev.dev->dev, - "No private data on fd, region %d\n", - iminor(file_inode(filp))); - return -EBADFD; - } - return 0; -} - -/* Converts from shared memory offset to virtual address */ -static inline void *shm_off_to_virtual_addr(__u32 offset) -{ - return (void __force *)vsoc_dev.kernel_mapped_shm + offset; -} - -/* Converts from shared memory offset to physical address */ -static inline phys_addr_t shm_off_to_phys_addr(__u32 offset) -{ - return vsoc_dev.shm_phys_start + offset; -} - -/** - * Convenience functions to obtain the region from the inode or file. - * Dangerous to call before validating the inode/file. - */ -static -inline struct vsoc_device_region *vsoc_region_from_inode(struct inode *ino= de) -{ - return &vsoc_dev.regions[iminor(inode)]; -} - -static -inline struct vsoc_device_region *vsoc_region_from_filep(struct file *inod= e) -{ - return vsoc_region_from_inode(file_inode(inode)); -} - -static inline uint32_t vsoc_device_region_size(struct vsoc_device_region *= r) -{ - return r->region_end_offset - r->region_begin_offset; -} - -static const struct file_operations vsoc_ops =3D { - .owner =3D THIS_MODULE, - .open =3D vsoc_open, - .mmap =3D vsoc_mmap, - .read =3D vsoc_read, - .unlocked_ioctl =3D vsoc_ioctl, - .compat_ioctl =3D vsoc_ioctl, - .write =3D vsoc_write, - .llseek =3D vsoc_lseek, - .release =3D vsoc_release, -}; - -static struct pci_device_id vsoc_id_table[] =3D { - {0x1af4, 0x1110, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {0}, -}; - -MODULE_DEVICE_TABLE(pci, vsoc_id_table); - -static void vsoc_remove_device(struct pci_dev *pdev); -static int vsoc_probe_device(struct pci_dev *pdev, - const struct pci_device_id *ent); - -static struct pci_driver vsoc_pci_driver =3D { - .name =3D "vsoc", - .id_table =3D vsoc_id_table, - .probe =3D vsoc_probe_device, - .remove =3D vsoc_remove_device, -}; - -static int -do_create_fd_scoped_permission(struct vsoc_device_region *region_p, - struct fd_scoped_permission_node *np, - struct fd_scoped_permission_arg __user *arg) -{ - struct file *managed_filp; - s32 managed_fd; - atomic_t *owner_ptr =3D NULL; - struct vsoc_device_region *managed_region_p; - - if (copy_from_user(&np->permission, - &arg->perm, sizeof(np->permission)) || - copy_from_user(&managed_fd, - &arg->managed_region_fd, sizeof(managed_fd))) { - return -EFAULT; - } - managed_filp =3D fdget(managed_fd).file; - /* Check that it's a valid fd, */ - if (!managed_filp || vsoc_validate_filep(managed_filp)) - return -EPERM; - /* EEXIST if the given fd already has a permission. */ - if (((struct vsoc_private_data *)managed_filp->private_data)-> - fd_scoped_permission_node) - return -EEXIST; - managed_region_p =3D vsoc_region_from_filep(managed_filp); - /* Check that the provided region is managed by this one */ - if (&vsoc_dev.regions[managed_region_p->managed_by] !=3D region_p) - return -EPERM; - /* The area must be well formed and have non-zero size */ - if (np->permission.begin_offset >=3D np->permission.end_offset) - return -EINVAL; - /* The area must fit in the memory window */ - if (np->permission.end_offset > - vsoc_device_region_size(managed_region_p)) - return -ERANGE; - /* The area must be in the region data section */ - if (np->permission.begin_offset < - managed_region_p->offset_of_region_data) - return -ERANGE; - /* The area must be page aligned */ - if (!PAGE_ALIGNED(np->permission.begin_offset) || - !PAGE_ALIGNED(np->permission.end_offset)) - return -EINVAL; - /* Owner offset must be naturally aligned in the window */ - if (np->permission.owner_offset & - (sizeof(np->permission.owner_offset) - 1)) - return -EINVAL; - /* The owner flag must reside in the owner memory */ - if (np->permission.owner_offset + sizeof(np->permission.owner_offset) > - vsoc_device_region_size(region_p)) - return -ERANGE; - /* The owner flag must reside in the data section */ - if (np->permission.owner_offset < region_p->offset_of_region_data) - return -EINVAL; - /* The owner value must change to claim the memory */ - if (np->permission.owned_value =3D=3D VSOC_REGION_FREE) - return -EINVAL; - owner_ptr =3D - (atomic_t *)shm_off_to_virtual_addr(region_p->region_begin_offset + - np->permission.owner_offset); - /* We've already verified that this is in the shared memory window, so - * it should be safe to write to this address. - */ - if (atomic_cmpxchg(owner_ptr, - VSOC_REGION_FREE, - np->permission.owned_value) !=3D VSOC_REGION_FREE) { - return -EBUSY; - } - ((struct vsoc_private_data *)managed_filp->private_data)-> - fd_scoped_permission_node =3D np; - /* The file offset needs to be adjusted if the calling - * process did any read/write operations on the fd - * before creating the permission. - */ - if (managed_filp->f_pos) { - if (managed_filp->f_pos > np->permission.end_offset) { - /* If the offset is beyond the permission end, set it - * to the end. - */ - managed_filp->f_pos =3D np->permission.end_offset; - } else { - /* If the offset is within the permission interval - * keep it there otherwise reset it to zero. - */ - if (managed_filp->f_pos < np->permission.begin_offset) { - managed_filp->f_pos =3D 0; - } else { - managed_filp->f_pos -=3D - np->permission.begin_offset; - } - } - } - return 0; -} - -static void -do_destroy_fd_scoped_permission_node(struct vsoc_device_region *owner_regi= on_p, - struct fd_scoped_permission_node *node) -{ - if (node) { - do_destroy_fd_scoped_permission(owner_region_p, - &node->permission); - mutex_lock(&vsoc_dev.mtx); - list_del(&node->list); - mutex_unlock(&vsoc_dev.mtx); - kfree(node); - } -} - -static void -do_destroy_fd_scoped_permission(struct vsoc_device_region *owner_region_p, - struct fd_scoped_permission *perm) -{ - atomic_t *owner_ptr =3D NULL; - int prev =3D 0; - - if (!perm) - return; - owner_ptr =3D (atomic_t *)shm_off_to_virtual_addr - (owner_region_p->region_begin_offset + perm->owner_offset); - prev =3D atomic_xchg(owner_ptr, VSOC_REGION_FREE); - if (prev !=3D perm->owned_value) - dev_err(&vsoc_dev.dev->dev, - "%x-%x: owner (%s) %x: expected to be %x was %x", - perm->begin_offset, perm->end_offset, - owner_region_p->device_name, perm->owner_offset, - perm->owned_value, prev); -} - -static long do_vsoc_describe_region(struct file *filp, - struct vsoc_device_region __user *dest) -{ - struct vsoc_device_region *region_p; - int retval =3D vsoc_validate_filep(filp); - - if (retval) - return retval; - region_p =3D vsoc_region_from_filep(filp); - if (copy_to_user(dest, region_p, sizeof(*region_p))) - return -EFAULT; - return 0; -} - -/** - * Implements the inner logic of cond_wait. Copies to and from userspace a= re - * done in the helper function below. - */ -static int handle_vsoc_cond_wait(struct file *filp, struct vsoc_cond_wait = *arg) -{ - DEFINE_WAIT(wait); - u32 region_number =3D iminor(file_inode(filp)); - struct vsoc_region_data *data =3D vsoc_dev.regions_data + region_number; - struct hrtimer_sleeper timeout, *to =3D NULL; - int ret =3D 0; - struct vsoc_device_region *region_p =3D vsoc_region_from_filep(filp); - atomic_t *address =3D NULL; - ktime_t wake_time; - - /* Ensure that the offset is aligned */ - if (arg->offset & (sizeof(uint32_t) - 1)) - return -EADDRNOTAVAIL; - /* Ensure that the offset is within shared memory */ - if (((uint64_t)arg->offset) + region_p->region_begin_offset + - sizeof(uint32_t) > region_p->region_end_offset) - return -E2BIG; - address =3D shm_off_to_virtual_addr(region_p->region_begin_offset + - arg->offset); - - /* Ensure that the type of wait is valid */ - switch (arg->wait_type) { - case VSOC_WAIT_IF_EQUAL: - break; - case VSOC_WAIT_IF_EQUAL_TIMEOUT: - to =3D &timeout; - break; - default: - return -EINVAL; - } - - if (to) { - /* Copy the user-supplied timesec into the kernel structure. - * We do things this way to flatten differences between 32 bit - * and 64 bit timespecs. - */ - if (arg->wake_time_nsec >=3D NSEC_PER_SEC) - return -EINVAL; - wake_time =3D ktime_set(arg->wake_time_sec, arg->wake_time_nsec); - - hrtimer_init_sleeper_on_stack(to, CLOCK_MONOTONIC, - HRTIMER_MODE_ABS); - hrtimer_set_expires_range_ns(&to->timer, wake_time, - current->timer_slack_ns); - } - - while (1) { - prepare_to_wait(&data->futex_wait_queue, &wait, - TASK_INTERRUPTIBLE); - /* - * Check the sentinel value after prepare_to_wait. If the value - * changes after this check the writer will call signal, - * changing the task state from INTERRUPTIBLE to RUNNING. That - * will ensure that schedule() will eventually schedule this - * task. - */ - if (atomic_read(address) !=3D arg->value) { - ret =3D 0; - break; - } - if (to) { - hrtimer_sleeper_start_expires(to, HRTIMER_MODE_ABS); - if (likely(to->task)) - freezable_schedule(); - hrtimer_cancel(&to->timer); - if (!to->task) { - ret =3D -ETIMEDOUT; - break; - } - } else { - freezable_schedule(); - } - /* Count the number of times that we woke up. This is useful - * for unit testing. - */ - ++arg->wakes; - if (signal_pending(current)) { - ret =3D -EINTR; - break; - } - } - finish_wait(&data->futex_wait_queue, &wait); - if (to) - destroy_hrtimer_on_stack(&to->timer); - return ret; -} - -/** - * Handles the details of copying from/to userspace to ensure that the cop= ies - * happen on all of the return paths of cond_wait. - */ -static int do_vsoc_cond_wait(struct file *filp, - struct vsoc_cond_wait __user *untrusted_in) -{ - struct vsoc_cond_wait arg; - int rval =3D 0; - - if (copy_from_user(&arg, untrusted_in, sizeof(arg))) - return -EFAULT; - /* wakes is an out parameter. Initialize it to something sensible. */ - arg.wakes =3D 0; - rval =3D handle_vsoc_cond_wait(filp, &arg); - if (copy_to_user(untrusted_in, &arg, sizeof(arg))) - return -EFAULT; - return rval; -} - -static int do_vsoc_cond_wake(struct file *filp, uint32_t offset) -{ - struct vsoc_device_region *region_p =3D vsoc_region_from_filep(filp); - u32 region_number =3D iminor(file_inode(filp)); - struct vsoc_region_data *data =3D vsoc_dev.regions_data + region_number; - /* Ensure that the offset is aligned */ - if (offset & (sizeof(uint32_t) - 1)) - return -EADDRNOTAVAIL; - /* Ensure that the offset is within shared memory */ - if (((uint64_t)offset) + region_p->region_begin_offset + - sizeof(uint32_t) > region_p->region_end_offset) - return -E2BIG; - /* - * TODO(b/73664181): Use multiple futex wait queues. - * We need to wake every sleeper when the condition changes. Typically - * only a single thread will be waiting on the condition, but there - * are exceptions. The worst case is about 10 threads. - */ - wake_up_interruptible_all(&data->futex_wait_queue); - return 0; -} - -static long vsoc_ioctl(struct file *filp, unsigned int cmd, unsigned long = arg) -{ - int rv =3D 0; - struct vsoc_device_region *region_p; - u32 reg_num; - struct vsoc_region_data *reg_data; - int retval =3D vsoc_validate_filep(filp); - - if (retval) - return retval; - region_p =3D vsoc_region_from_filep(filp); - reg_num =3D iminor(file_inode(filp)); - reg_data =3D vsoc_dev.regions_data + reg_num; - switch (cmd) { - case VSOC_CREATE_FD_SCOPED_PERMISSION: - { - struct fd_scoped_permission_node *node =3D NULL; - - node =3D kzalloc(sizeof(*node), GFP_KERNEL); - /* We can't allocate memory for the permission */ - if (!node) - return -ENOMEM; - INIT_LIST_HEAD(&node->list); - rv =3D do_create_fd_scoped_permission - (region_p, - node, - (struct fd_scoped_permission_arg __user *)arg); - if (!rv) { - mutex_lock(&vsoc_dev.mtx); - list_add(&node->list, &vsoc_dev.permissions); - mutex_unlock(&vsoc_dev.mtx); - } else { - kfree(node); - return rv; - } - } - break; - - case VSOC_GET_FD_SCOPED_PERMISSION: - { - struct fd_scoped_permission_node *node =3D - ((struct vsoc_private_data *)filp->private_data)-> - fd_scoped_permission_node; - if (!node) - return -ENOENT; - if (copy_to_user - ((struct fd_scoped_permission __user *)arg, - &node->permission, sizeof(node->permission))) - return -EFAULT; - } - break; - - case VSOC_MAYBE_SEND_INTERRUPT_TO_HOST: - if (!atomic_xchg(reg_data->outgoing_signalled, 1)) { - writel(reg_num, vsoc_dev.regs + DOORBELL); - return 0; - } else { - return -EBUSY; - } - break; - - case VSOC_SEND_INTERRUPT_TO_HOST: - writel(reg_num, vsoc_dev.regs + DOORBELL); - return 0; - case VSOC_WAIT_FOR_INCOMING_INTERRUPT: - wait_event_interruptible - (reg_data->interrupt_wait_queue, - (atomic_read(reg_data->incoming_signalled) !=3D 0)); - break; - - case VSOC_DESCRIBE_REGION: - return do_vsoc_describe_region - (filp, - (struct vsoc_device_region __user *)arg); - - case VSOC_SELF_INTERRUPT: - atomic_set(reg_data->incoming_signalled, 1); - wake_up_interruptible(®_data->interrupt_wait_queue); - break; - - case VSOC_COND_WAIT: - return do_vsoc_cond_wait(filp, - (struct vsoc_cond_wait __user *)arg); - case VSOC_COND_WAKE: - return do_vsoc_cond_wake(filp, arg); - - default: - return -EINVAL; - } - return 0; -} - -static ssize_t vsoc_read(struct file *filp, char __user *buffer, size_t le= n, - loff_t *poffset) -{ - __u32 area_off; - const void *area_p; - ssize_t area_len; - int retval =3D vsoc_validate_filep(filp); - - if (retval) - return retval; - area_len =3D vsoc_get_area(filp, &area_off); - area_p =3D shm_off_to_virtual_addr(area_off); - area_p +=3D *poffset; - area_len -=3D *poffset; - if (area_len <=3D 0) - return 0; - if (area_len < len) - len =3D area_len; - if (copy_to_user(buffer, area_p, len)) - return -EFAULT; - *poffset +=3D len; - return len; -} - -static loff_t vsoc_lseek(struct file *filp, loff_t offset, int origin) -{ - ssize_t area_len =3D 0; - int retval =3D vsoc_validate_filep(filp); - - if (retval) - return retval; - area_len =3D vsoc_get_area(filp, NULL); - switch (origin) { - case SEEK_SET: - break; - - case SEEK_CUR: - if (offset > 0 && offset + filp->f_pos < 0) - return -EOVERFLOW; - offset +=3D filp->f_pos; - break; - - case SEEK_END: - if (offset > 0 && offset + area_len < 0) - return -EOVERFLOW; - offset +=3D area_len; - break; - - case SEEK_DATA: - if (offset >=3D area_len) - return -EINVAL; - if (offset < 0) - offset =3D 0; - break; - - case SEEK_HOLE: - /* Next hole is always the end of the region, unless offset is - * beyond that - */ - if (offset < area_len) - offset =3D area_len; - break; - - default: - return -EINVAL; - } - - if (offset < 0 || offset > area_len) - return -EINVAL; - filp->f_pos =3D offset; - - return offset; -} - -static ssize_t vsoc_write(struct file *filp, const char __user *buffer, - size_t len, loff_t *poffset) -{ - __u32 area_off; - void *area_p; - ssize_t area_len; - int retval =3D vsoc_validate_filep(filp); - - if (retval) - return retval; - area_len =3D vsoc_get_area(filp, &area_off); - area_p =3D shm_off_to_virtual_addr(area_off); - area_p +=3D *poffset; - area_len -=3D *poffset; - if (area_len <=3D 0) - return 0; - if (area_len < len) - len =3D area_len; - if (copy_from_user(area_p, buffer, len)) - return -EFAULT; - *poffset +=3D len; - return len; -} - -static irqreturn_t vsoc_interrupt(int irq, void *region_data_v) -{ - struct vsoc_region_data *region_data =3D - (struct vsoc_region_data *)region_data_v; - int reg_num =3D region_data - vsoc_dev.regions_data; - - if (unlikely(!region_data)) - return IRQ_NONE; - - if (unlikely(reg_num < 0 || - reg_num >=3D vsoc_dev.layout->region_count)) { - dev_err(&vsoc_dev.dev->dev, - "invalid irq @%p reg_num=3D0x%04x\n", - region_data, reg_num); - return IRQ_NONE; - } - if (unlikely(vsoc_dev.regions_data + reg_num !=3D region_data)) { - dev_err(&vsoc_dev.dev->dev, - "irq not aligned @%p reg_num=3D0x%04x\n", - region_data, reg_num); - return IRQ_NONE; - } - wake_up_interruptible(®ion_data->interrupt_wait_queue); - return IRQ_HANDLED; -} - -static int vsoc_probe_device(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - int result; - int i; - resource_size_t reg_size; - dev_t devt; - - vsoc_dev.dev =3D pdev; - result =3D pci_enable_device(pdev); - if (result) { - dev_err(&pdev->dev, - "pci_enable_device failed %s: error %d\n", - pci_name(pdev), result); - return result; - } - vsoc_dev.enabled_device =3D true; - result =3D pci_request_regions(pdev, "vsoc"); - if (result < 0) { - dev_err(&pdev->dev, "pci_request_regions failed\n"); - vsoc_remove_device(pdev); - return -EBUSY; - } - vsoc_dev.requested_regions =3D true; - /* Set up the control registers in BAR 0 */ - reg_size =3D pci_resource_len(pdev, REGISTER_BAR); - if (reg_size > MAX_REGISTER_BAR_LEN) - vsoc_dev.regs =3D - pci_iomap(pdev, REGISTER_BAR, MAX_REGISTER_BAR_LEN); - else - vsoc_dev.regs =3D pci_iomap(pdev, REGISTER_BAR, reg_size); - - if (!vsoc_dev.regs) { - dev_err(&pdev->dev, - "cannot map registers of size %zu\n", - (size_t)reg_size); - vsoc_remove_device(pdev); - return -EBUSY; - } - - /* Map the shared memory in BAR 2 */ - vsoc_dev.shm_phys_start =3D pci_resource_start(pdev, SHARED_MEMORY_BAR); - vsoc_dev.shm_size =3D pci_resource_len(pdev, SHARED_MEMORY_BAR); - - dev_info(&pdev->dev, "shared memory @ DMA %pa size=3D0x%zx\n", - &vsoc_dev.shm_phys_start, vsoc_dev.shm_size); - vsoc_dev.kernel_mapped_shm =3D pci_iomap_wc(pdev, SHARED_MEMORY_BAR, 0); - if (!vsoc_dev.kernel_mapped_shm) { - dev_err(&vsoc_dev.dev->dev, "cannot iomap region\n"); - vsoc_remove_device(pdev); - return -EBUSY; - } - - vsoc_dev.layout =3D (struct vsoc_shm_layout_descriptor __force *) - vsoc_dev.kernel_mapped_shm; - dev_info(&pdev->dev, "major_version: %d\n", - vsoc_dev.layout->major_version); - dev_info(&pdev->dev, "minor_version: %d\n", - vsoc_dev.layout->minor_version); - dev_info(&pdev->dev, "size: 0x%x\n", vsoc_dev.layout->size); - dev_info(&pdev->dev, "regions: %d\n", vsoc_dev.layout->region_count); - if (vsoc_dev.layout->major_version !=3D - CURRENT_VSOC_LAYOUT_MAJOR_VERSION) { - dev_err(&vsoc_dev.dev->dev, - "driver supports only major_version %d\n", - CURRENT_VSOC_LAYOUT_MAJOR_VERSION); - vsoc_remove_device(pdev); - return -EBUSY; - } - result =3D alloc_chrdev_region(&devt, 0, vsoc_dev.layout->region_count, - VSOC_DEV_NAME); - if (result) { - dev_err(&vsoc_dev.dev->dev, "alloc_chrdev_region failed\n"); - vsoc_remove_device(pdev); - return -EBUSY; - } - vsoc_dev.major =3D MAJOR(devt); - cdev_init(&vsoc_dev.cdev, &vsoc_ops); - vsoc_dev.cdev.owner =3D THIS_MODULE; - result =3D cdev_add(&vsoc_dev.cdev, devt, vsoc_dev.layout->region_count); - if (result) { - dev_err(&vsoc_dev.dev->dev, "cdev_add error\n"); - vsoc_remove_device(pdev); - return -EBUSY; - } - vsoc_dev.cdev_added =3D true; - vsoc_dev.class =3D class_create(THIS_MODULE, VSOC_DEV_NAME); - if (IS_ERR(vsoc_dev.class)) { - dev_err(&vsoc_dev.dev->dev, "class_create failed\n"); - vsoc_remove_device(pdev); - return PTR_ERR(vsoc_dev.class); - } - vsoc_dev.class_added =3D true; - vsoc_dev.regions =3D (struct vsoc_device_region __force *) - ((void *)vsoc_dev.layout + - vsoc_dev.layout->vsoc_region_desc_offset); - vsoc_dev.msix_entries =3D - kcalloc(vsoc_dev.layout->region_count, - sizeof(vsoc_dev.msix_entries[0]), GFP_KERNEL); - if (!vsoc_dev.msix_entries) { - dev_err(&vsoc_dev.dev->dev, - "unable to allocate msix_entries\n"); - vsoc_remove_device(pdev); - return -ENOSPC; - } - vsoc_dev.regions_data =3D - kcalloc(vsoc_dev.layout->region_count, - sizeof(vsoc_dev.regions_data[0]), GFP_KERNEL); - if (!vsoc_dev.regions_data) { - dev_err(&vsoc_dev.dev->dev, - "unable to allocate regions' data\n"); - vsoc_remove_device(pdev); - return -ENOSPC; - } - for (i =3D 0; i < vsoc_dev.layout->region_count; ++i) - vsoc_dev.msix_entries[i].entry =3D i; - - result =3D pci_enable_msix_exact(vsoc_dev.dev, vsoc_dev.msix_entries, - vsoc_dev.layout->region_count); - if (result) { - dev_info(&pdev->dev, "pci_enable_msix failed: %d\n", result); - vsoc_remove_device(pdev); - return -ENOSPC; - } - /* Check that all regions are well formed */ - for (i =3D 0; i < vsoc_dev.layout->region_count; ++i) { - const struct vsoc_device_region *region =3D vsoc_dev.regions + i; - - if (!PAGE_ALIGNED(region->region_begin_offset) || - !PAGE_ALIGNED(region->region_end_offset)) { - dev_err(&vsoc_dev.dev->dev, - "region %d not aligned (%x:%x)", i, - region->region_begin_offset, - region->region_end_offset); - vsoc_remove_device(pdev); - return -EFAULT; - } - if (region->region_begin_offset >=3D region->region_end_offset || - region->region_end_offset > vsoc_dev.shm_size) { - dev_err(&vsoc_dev.dev->dev, - "region %d offsets are wrong: %x %x %zx", - i, region->region_begin_offset, - region->region_end_offset, vsoc_dev.shm_size); - vsoc_remove_device(pdev); - return -EFAULT; - } - if (region->managed_by >=3D vsoc_dev.layout->region_count) { - dev_err(&vsoc_dev.dev->dev, - "region %d has invalid owner: %u", - i, region->managed_by); - vsoc_remove_device(pdev); - return -EFAULT; - } - } - vsoc_dev.msix_enabled =3D true; - for (i =3D 0; i < vsoc_dev.layout->region_count; ++i) { - const struct vsoc_device_region *region =3D vsoc_dev.regions + i; - size_t name_sz =3D sizeof(vsoc_dev.regions_data[i].name) - 1; - const struct vsoc_signal_table_layout *h_to_g_signal_table =3D - ®ion->host_to_guest_signal_table; - const struct vsoc_signal_table_layout *g_to_h_signal_table =3D - ®ion->guest_to_host_signal_table; - - vsoc_dev.regions_data[i].name[name_sz] =3D '\0'; - memcpy(vsoc_dev.regions_data[i].name, region->device_name, - name_sz); - dev_info(&pdev->dev, "region %d name=3D%s\n", - i, vsoc_dev.regions_data[i].name); - init_waitqueue_head - (&vsoc_dev.regions_data[i].interrupt_wait_queue); - init_waitqueue_head(&vsoc_dev.regions_data[i].futex_wait_queue); - vsoc_dev.regions_data[i].incoming_signalled =3D - shm_off_to_virtual_addr(region->region_begin_offset) + - h_to_g_signal_table->interrupt_signalled_offset; - vsoc_dev.regions_data[i].outgoing_signalled =3D - shm_off_to_virtual_addr(region->region_begin_offset) + - g_to_h_signal_table->interrupt_signalled_offset; - result =3D request_irq(vsoc_dev.msix_entries[i].vector, - vsoc_interrupt, 0, - vsoc_dev.regions_data[i].name, - vsoc_dev.regions_data + i); - if (result) { - dev_info(&pdev->dev, - "request_irq failed irq=3D%d vector=3D%d\n", - i, vsoc_dev.msix_entries[i].vector); - vsoc_remove_device(pdev); - return -ENOSPC; - } - vsoc_dev.regions_data[i].irq_requested =3D true; - if (!device_create(vsoc_dev.class, NULL, - MKDEV(vsoc_dev.major, i), - NULL, vsoc_dev.regions_data[i].name)) { - dev_err(&vsoc_dev.dev->dev, "device_create failed\n"); - vsoc_remove_device(pdev); - return -EBUSY; - } - vsoc_dev.regions_data[i].device_created =3D true; - } - return 0; -} - -/* - * This should undo all of the allocations in the probe function in revers= e - * order. - * - * Notes: - * - * The device may have been partially initialized, so double check - * that the allocations happened. - * - * This function may be called multiple times, so mark resources as free= d - * as they are deallocated. - */ -static void vsoc_remove_device(struct pci_dev *pdev) -{ - int i; - /* - * pdev is the first thing to be set on probe and the last thing - * to be cleared here. If it's NULL then there is no cleanup. - */ - if (!pdev || !vsoc_dev.dev) - return; - dev_info(&pdev->dev, "remove_device\n"); - if (vsoc_dev.regions_data) { - for (i =3D 0; i < vsoc_dev.layout->region_count; ++i) { - if (vsoc_dev.regions_data[i].device_created) { - device_destroy(vsoc_dev.class, - MKDEV(vsoc_dev.major, i)); - vsoc_dev.regions_data[i].device_created =3D false; - } - if (vsoc_dev.regions_data[i].irq_requested) - free_irq(vsoc_dev.msix_entries[i].vector, NULL); - vsoc_dev.regions_data[i].irq_requested =3D false; - } - kfree(vsoc_dev.regions_data); - vsoc_dev.regions_data =3D NULL; - } - if (vsoc_dev.msix_enabled) { - pci_disable_msix(pdev); - vsoc_dev.msix_enabled =3D false; - } - kfree(vsoc_dev.msix_entries); - vsoc_dev.msix_entries =3D NULL; - vsoc_dev.regions =3D NULL; - if (vsoc_dev.class_added) { - class_destroy(vsoc_dev.class); - vsoc_dev.class_added =3D false; - } - if (vsoc_dev.cdev_added) { - cdev_del(&vsoc_dev.cdev); - vsoc_dev.cdev_added =3D false; - } - if (vsoc_dev.major && vsoc_dev.layout) { - unregister_chrdev_region(MKDEV(vsoc_dev.major, 0), - vsoc_dev.layout->region_count); - vsoc_dev.major =3D 0; - } - vsoc_dev.layout =3D NULL; - if (vsoc_dev.kernel_mapped_shm) { - pci_iounmap(pdev, vsoc_dev.kernel_mapped_shm); - vsoc_dev.kernel_mapped_shm =3D NULL; - } - if (vsoc_dev.regs) { - pci_iounmap(pdev, vsoc_dev.regs); - vsoc_dev.regs =3D NULL; - } - if (vsoc_dev.requested_regions) { - pci_release_regions(pdev); - vsoc_dev.requested_regions =3D false; - } - if (vsoc_dev.enabled_device) { - pci_disable_device(pdev); - vsoc_dev.enabled_device =3D false; - } - /* Do this last: it indicates that the device is not initialized. */ - vsoc_dev.dev =3D NULL; -} - -static void __exit vsoc_cleanup_module(void) -{ - vsoc_remove_device(vsoc_dev.dev); - pci_unregister_driver(&vsoc_pci_driver); -} - -static int __init vsoc_init_module(void) -{ - int err =3D -ENOMEM; - - INIT_LIST_HEAD(&vsoc_dev.permissions); - mutex_init(&vsoc_dev.mtx); - - err =3D pci_register_driver(&vsoc_pci_driver); - if (err < 0) - return err; - return 0; -} - -static int vsoc_open(struct inode *inode, struct file *filp) -{ - /* Can't use vsoc_validate_filep because filp is still incomplete */ - int ret =3D vsoc_validate_inode(inode); - - if (ret) - return ret; - filp->private_data =3D - kzalloc(sizeof(struct vsoc_private_data), GFP_KERNEL); - if (!filp->private_data) - return -ENOMEM; - return 0; -} - -static int vsoc_release(struct inode *inode, struct file *filp) -{ - struct vsoc_private_data *private_data =3D NULL; - struct fd_scoped_permission_node *node =3D NULL; - struct vsoc_device_region *owner_region_p =3D NULL; - int retval =3D vsoc_validate_filep(filp); - - if (retval) - return retval; - private_data =3D (struct vsoc_private_data *)filp->private_data; - if (!private_data) - return 0; - - node =3D private_data->fd_scoped_permission_node; - if (node) { - owner_region_p =3D vsoc_region_from_inode(inode); - if (owner_region_p->managed_by !=3D VSOC_REGION_WHOLE) { - owner_region_p =3D - &vsoc_dev.regions[owner_region_p->managed_by]; - } - do_destroy_fd_scoped_permission_node(owner_region_p, node); - private_data->fd_scoped_permission_node =3D NULL; - } - kfree(private_data); - filp->private_data =3D NULL; - - return 0; -} - -/* - * Returns the device relative offset and length of the area specified by = the - * fd scoped permission. If there is no fd scoped permission set, a defaul= t - * permission covering the entire region is assumed, unless the region is = owned - * by another one, in which case the default is a permission with zero siz= e. - */ -static ssize_t vsoc_get_area(struct file *filp, __u32 *area_offset) -{ - __u32 off =3D 0; - ssize_t length =3D 0; - struct vsoc_device_region *region_p; - struct fd_scoped_permission *perm; - - region_p =3D vsoc_region_from_filep(filp); - off =3D region_p->region_begin_offset; - perm =3D &((struct vsoc_private_data *)filp->private_data)-> - fd_scoped_permission_node->permission; - if (perm) { - off +=3D perm->begin_offset; - length =3D perm->end_offset - perm->begin_offset; - } else if (region_p->managed_by =3D=3D VSOC_REGION_WHOLE) { - /* No permission set and the regions is not owned by another, - * default to full region access. - */ - length =3D vsoc_device_region_size(region_p); - } else { - /* return zero length, access is denied. */ - length =3D 0; - } - if (area_offset) - *area_offset =3D off; - return length; -} - -static int vsoc_mmap(struct file *filp, struct vm_area_struct *vma) -{ - unsigned long len =3D vma->vm_end - vma->vm_start; - __u32 area_off; - phys_addr_t mem_off; - ssize_t area_len; - int retval =3D vsoc_validate_filep(filp); - - if (retval) - return retval; - area_len =3D vsoc_get_area(filp, &area_off); - /* Add the requested offset */ - area_off +=3D (vma->vm_pgoff << PAGE_SHIFT); - area_len -=3D (vma->vm_pgoff << PAGE_SHIFT); - if (area_len < len) - return -EINVAL; - vma->vm_page_prot =3D pgprot_noncached(vma->vm_page_prot); - mem_off =3D shm_off_to_phys_addr(area_off); - if (io_remap_pfn_range(vma, vma->vm_start, mem_off >> PAGE_SHIFT, - len, vma->vm_page_prot)) - return -EAGAIN; - return 0; -} - -module_init(vsoc_init_module); -module_exit(vsoc_cleanup_module); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Greg Hartman "); -MODULE_DESCRIPTION("VSoC interpretation of QEmu's ivshmem device"); -MODULE_VERSION("1.0"); --=20 2.25.0.341.g760bfbb309-goog 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 X-Spam-Level: X-Spam-Status: No, score=-9.5 required=3.0 tests=DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AE1CAC3524D for ; Mon, 3 Feb 2020 07:17:55 +0000 (UTC) Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 798D92070A for ; Mon, 3 Feb 2020 07:17:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="JNorMbU7" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 798D92070A Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=driverdev-devel-bounces@linuxdriverproject.org Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 59CC98778F; Mon, 3 Feb 2020 07:17:54 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id X5sxvMWkF9VF; Mon, 3 Feb 2020 07:17:49 +0000 (UTC) Received: from ash.osuosl.org (ash.osuosl.org [140.211.166.34]) by hemlock.osuosl.org (Postfix) with ESMTP id 5B6DA876F2; Mon, 3 Feb 2020 07:17:49 +0000 (UTC) Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by ash.osuosl.org (Postfix) with ESMTP id EF0241BF381 for ; Mon, 3 Feb 2020 07:17:47 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id DE65B85CE0 for ; Mon, 3 Feb 2020 07:17:47 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id rmZOgfmvebWd for ; Mon, 3 Feb 2020 07:17:44 +0000 (UTC) X-Greylist: delayed 01:06:48 by SQLgrey-1.7.6 Received: from mail-ua1-f73.google.com (mail-ua1-f73.google.com [209.85.222.73]) by whitealder.osuosl.org (Postfix) with ESMTPS id 53A1584FAE for ; Mon, 3 Feb 2020 07:17:44 +0000 (UTC) Received: by mail-ua1-f73.google.com with SMTP id o13so3344733uad.7 for ; Sun, 02 Feb 2020 23:17:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:message-id:mime-version:subject:from:to:cc :content-transfer-encoding; bh=X6VO2mdbhKE5o6DYiR8xP596jvUpUwQpg4b1gjaIEUk=; b=JNorMbU7Vyou3YsqDQGhq1Ao+TscpvwaHeU9pmfxwsbwvHXweYHzWu2mIgPkmaDTs5 6pEtHjMKZli1sBJvBm27a7RW45OGdfjjPj6UC6Wc6C8NolA/KNp7HAuBZ4KTdR879hn9 tvcbILA6D5XHaLt7ydcgALDSSug4rGRrpN8wGVUB5/K2u1IAzPpCaRMOPeq2awMj6NUq 6pgFcxmA3y6QBqK75AKcWl3U1kUTbJ4t4NGeABogJmBicwd+1R2c0I+uV/ELh2AGC4as DQt8DGUEPY7VKwfRr7y3QVbXyAkW19JJT+F0khBY3n0jF+ucsPqfILuMkJnLOymXHLDq 0fog== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:message-id:mime-version:subject:from:to:cc :content-transfer-encoding; bh=X6VO2mdbhKE5o6DYiR8xP596jvUpUwQpg4b1gjaIEUk=; b=lScbszD9hWp/EJVKGVENPG1HebqLf9oqPSAhEZrh9vRu1ZqcfbQfDGd/6HtEgENVBx NbX450A/FX7UD1QvHOVhWphE1IcFV8Wmg6GjJl5ndzOy+aMZPogEBlK3zd4RsBh+tg3r Tv4GgvSPVTn85m47Vgmqcx9el9eIKFvMwSENXFAWmABOfDXZVnuJXLE3lZvurW8FfT9P hGBHAEOIyEhd5B14zcazhojJr7p6QC4gQ9/MbivaK+pIMFYdK6274G56Z1dscg17bd71 nVT0enKI+Sy1gRN79TXd49ZWfPhe/+Wg5kk7vnOyQ7HlkxLBzoqFND7P3Unfe6Rd2iAm XowQ== X-Gm-Message-State: APjAAAVrbPHf1miWKQoeasWdLathorUQnT13Rhx9M0t9HqqhBMuihEqe K1d5/o/LjyzL9CMM/9Vgb3fuqW7MTms= X-Google-Smtp-Source: APXvYqzc7SF8KOm+AnEfNqc549HVOwwRQ4ijZ4mu8EgJ2ec4bhG6TrWRpD7WizBUKA9cb4FJcXd1j0HBRHQ= X-Received: by 2002:a0c:db8c:: with SMTP id m12mr20507624qvk.154.1580703777266; Sun, 02 Feb 2020 20:22:57 -0800 (PST) Date: Sun, 2 Feb 2020 20:22:54 -0800 Message-Id: <20200203042254.80360-1-adelva@google.com> Mime-Version: 1.0 X-Mailer: git-send-email 2.25.0.341.g760bfbb309-goog Subject: [PATCH] staging: android: Delete the 'vsoc' driver From: Alistair Delva To: linux-kernel@vger.kernel.org, cloud-android-devs@google.com X-BeenThere: driverdev-devel@linuxdriverproject.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux Driver Project Developer List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Joel Fernandes , Greg Kroah-Hartman , Greg Hartman , kernel-team@android.com, devel@driverdev.osuosl.org Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Errors-To: driverdev-devel-bounces@linuxdriverproject.org Sender: "devel" VGhlICd2c29jJyBkcml2ZXIgd2FzIHJlcXVpcmVkIGZvciBhbiBlYXJseSBpdGVyYXRpb24gb2Yg dGhlIEFuZHJvaWQKJ2N1dHRsZWZpc2gnIHZpcnR1YWwgcGxhdGZvcm0sIGJ1dCB0aGlzIHBsYXRm b3JtIGhhcyBiZWVuIHdob2xseQpjb252ZXJ0ZWQgdG8gdXNlIHZpcnRpbyBkcml2ZXJzIGluc3Rl YWQuIERlbGV0ZSB0aGlzIG9sZCBkcml2ZXIuCgpDYzogR3JlZyBLcm9haC1IYXJ0bWFuIDxncmVn a2hAbGludXhmb3VuZGF0aW9uLm9yZz4KQ2M6IEpvZWwgRmVybmFuZGVzIDxqb2VsQGpvZWxmZXJu YW5kZXMub3JnPgpDYzogR3JlZyBIYXJ0bWFuIDxnaGFydG1hbkBnb29nbGUuY29tPgpDYzoga2Vy bmVsLXRlYW1AYW5kcm9pZC5jb20KQ2M6IGRldmVsQGRyaXZlcmRldi5vc3Vvc2wub3JnClNpZ25l ZC1vZmYtYnk6IEFsaXN0YWlyIERlbHZhIDxhZGVsdmFAZ29vZ2xlLmNvbT4KLS0tCiBkcml2ZXJz L3N0YWdpbmcvYW5kcm9pZC9LY29uZmlnICAgICAgICAgfCAgICA4IC0KIGRyaXZlcnMvc3RhZ2lu Zy9hbmRyb2lkL01ha2VmaWxlICAgICAgICB8ICAgIDEgLQogZHJpdmVycy9zdGFnaW5nL2FuZHJv aWQvVE9ETyAgICAgICAgICAgIHwgICAgOSAtCiBkcml2ZXJzL3N0YWdpbmcvYW5kcm9pZC91YXBp L3Zzb2Nfc2htLmggfCAgMjk1IC0tLS0tLQogZHJpdmVycy9zdGFnaW5nL2FuZHJvaWQvdnNvYy5j ICAgICAgICAgIHwgMTE0OSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogNSBmaWxlcyBjaGFuZ2Vk LCAxNDYyIGRlbGV0aW9ucygtKQogZGVsZXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvc3RhZ2luZy9h bmRyb2lkL3VhcGkvdnNvY19zaG0uaAogZGVsZXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvc3RhZ2lu Zy9hbmRyb2lkL3Zzb2MuYwoKZGlmZiAtLWdpdCBhL2RyaXZlcnMvc3RhZ2luZy9hbmRyb2lkL0tj b25maWcgYi9kcml2ZXJzL3N0YWdpbmcvYW5kcm9pZC9LY29uZmlnCmluZGV4IGQ2ZDYwNWQ1Y2Jk ZS4uOGQ4ZmQ1YzI5MzQ5IDEwMDY0NAotLS0gYS9kcml2ZXJzL3N0YWdpbmcvYW5kcm9pZC9LY29u ZmlnCisrKyBiL2RyaXZlcnMvc3RhZ2luZy9hbmRyb2lkL0tjb25maWcKQEAgLTE0LDE0ICsxNCw2 IEBAIGNvbmZpZyBBU0hNRU0KIAkgIEl0IGlzLCBpbiB0aGVvcnksIGEgZ29vZCBtZW1vcnkgYWxs b2NhdG9yIGZvciBsb3ctbWVtb3J5IGRldmljZXMsCiAJICBiZWNhdXNlIGl0IGNhbiBkaXNjYXJk IHNoYXJlZCBtZW1vcnkgdW5pdHMgd2hlbiB1bmRlciBtZW1vcnkgcHJlc3N1cmUuCiAKLWNvbmZp ZyBBTkRST0lEX1ZTT0MKLQl0cmlzdGF0ZSAiQW5kcm9pZCBWaXJ0dWFsIFNvQyBzdXBwb3J0Igot CWRlcGVuZHMgb24gUENJX01TSQotCWhlbHAKLQkgIFRoaXMgb3B0aW9uIGFkZHMgc3VwcG9ydCBm b3IgdGhlIFZpcnR1YWwgU29DIGRyaXZlciBuZWVkZWQgdG8gYm9vdAotCSAgYSAnY3V0dGxlZmlz aCcgQW5kcm9pZCBpbWFnZSBpbnNpZGUgUUVtdS4gVGhlIGRyaXZlciBpbnRlcmFjdHMgd2l0aAot CSAgYSBRRW11IGl2c2htZW0gZGV2aWNlLiBJZiBidWlsdCBhcyBhIG1vZHVsZSwgaXQgd2lsbCBi ZSBjYWxsZWQgdnNvYy4KLQogc291cmNlICJkcml2ZXJzL3N0YWdpbmcvYW5kcm9pZC9pb24vS2Nv bmZpZyIKIAogZW5kaWYgIyBpZiBBTkRST0lECmRpZmYgLS1naXQgYS9kcml2ZXJzL3N0YWdpbmcv YW5kcm9pZC9NYWtlZmlsZSBiL2RyaXZlcnMvc3RhZ2luZy9hbmRyb2lkL01ha2VmaWxlCmluZGV4 IDE0YmQ5YzZjZTEwZC4uM2I2NmNkMGIwZWM1IDEwMDY0NAotLS0gYS9kcml2ZXJzL3N0YWdpbmcv YW5kcm9pZC9NYWtlZmlsZQorKysgYi9kcml2ZXJzL3N0YWdpbmcvYW5kcm9pZC9NYWtlZmlsZQpA QCAtNCw0ICs0LDMgQEAgY2NmbGFncy15ICs9IC1JJChzcmMpCQkJIyBuZWVkZWQgZm9yIHRyYWNl IGV2ZW50cwogb2JqLXkJCQkJCSs9IGlvbi8KIAogb2JqLSQoQ09ORklHX0FTSE1FTSkJCQkrPSBh c2htZW0ubwotb2JqLSQoQ09ORklHX0FORFJPSURfVlNPQykJCSs9IHZzb2MubwpkaWZmIC0tZ2l0 IGEvZHJpdmVycy9zdGFnaW5nL2FuZHJvaWQvVE9ETyBiL2RyaXZlcnMvc3RhZ2luZy9hbmRyb2lk L1RPRE8KaW5kZXggNzY3ZGQ5OGZkOTJkLi44MGVjY2ZhZjZkYjUgMTAwNjQ0Ci0tLSBhL2RyaXZl cnMvc3RhZ2luZy9hbmRyb2lkL1RPRE8KKysrIGIvZHJpdmVycy9zdGFnaW5nL2FuZHJvaWQvVE9E TwpAQCAtOSwxNCArOSw1IEBAIGlvbi8KICAtIFNwbGl0IC9kZXYvaW9uIHVwIGludG8gbXVsdGlw bGUgbm9kZXMgKGUuZy4gL2Rldi9pb24vaGVhcDApCiAgLSBCZXR0ZXIgdGVzdCBmcmFtZXdvcmsg KGludGVncmF0aW9uIHdpdGggVkdFTSB3YXMgc3VnZ2VzdGVkKQogCi12c29jLmMsIHVhcGkvdnNv Y19zaG0uaAotIC0gVGhlIGN1cnJlbnQgZHJpdmVyIHVzZXMgdGhlIHNhbWUgd2FpdCBxdWV1ZSBm b3IgYWxsIG9mIHRoZSBmdXRleGVzIGluIGEKLSAgIHJlZ2lvbi4gVGhpcyB3aWxsIGNhdXNlIGZh bHNlIHdha2V1cHMgaW4gcmVnaW9ucyB3aXRoIGEgbGFyZ2UgbnVtYmVyIG9mCi0gICB3YWl0aW5n IHRocmVhZHMuIFdlIHNob3VsZCBldmVudHVhbGx5IHVzZSBtdWx0aXBsZSBxdWV1ZXMgYW5kIHNl bGVjdCB0aGUKLSAgIHF1ZXVlIGJhc2VkIG9uIHRoZSByZWdpb24uCi0gLSBBZGQgZGVidWdmcyBz dXBwb3J0IGZvciBleGFtaW5pbmcgdGhlIHBlcm1pc3Npb25zIG9mIHJlZ2lvbnMuCi0gLSBSZW1v dmUgVlNPQ19XQUlUX0ZPUl9JTkNPTUlOR19JTlRFUlJVUFQgaW9jdGwuIFRoaXMgZnVuY3Rpb25h bGl0eSBoYXMgYmVlbgotICAgc3VwZXJzZWRlZCBieSB0aGUgZnV0ZXggYW5kIGlzIHRoZXJlIGZv ciBsZWdhY3kgcmVhc29ucy4KLQogUGxlYXNlIHNlbmQgcGF0Y2hlcyB0byBHcmVnIEtyb2FoLUhh cnRtYW4gPGdyZWdAa3JvYWguY29tPiBhbmQgQ2M6CiBBcnZlIEhqw7hubmV2w6VnIDxhcnZlQGFu ZHJvaWQuY29tPiBhbmQgUmlsZXkgQW5kcmV3cyA8cmlhbmRyZXdzQGFuZHJvaWQuY29tPgpkaWZm IC0tZ2l0IGEvZHJpdmVycy9zdGFnaW5nL2FuZHJvaWQvdWFwaS92c29jX3NobS5oIGIvZHJpdmVy cy9zdGFnaW5nL2FuZHJvaWQvdWFwaS92c29jX3NobS5oCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0 NAppbmRleCA2MjkxZmIyNGVmYjIuLjAwMDAwMDAwMDAwMAotLS0gYS9kcml2ZXJzL3N0YWdpbmcv YW5kcm9pZC91YXBpL3Zzb2Nfc2htLmgKKysrIC9kZXYvbnVsbApAQCAtMSwyOTUgKzAsMCBAQAot LyogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAgKi8KLS8qCi0gKiBDb3B5cmlnaHQg KEMpIDIwMTcgR29vZ2xlLCBJbmMuCi0gKgotICovCi0KLSNpZm5kZWYgX1VBUElfTElOVVhfVlNP Q19TSE1fSAotI2RlZmluZSBfVUFQSV9MSU5VWF9WU09DX1NITV9ICi0KLSNpbmNsdWRlIDxsaW51 eC90eXBlcy5oPgotCi0vKioKLSAqIEEgcGVybWlzc2lvbiBpcyBhIHRva2VuIHRoYXQgcGVybWl0 cyBhIHJlY2VpdmVyIHRvIHJlYWQgYW5kL29yIHdyaXRlIGFuIGFyZWEKLSAqIG9mIG1lbW9yeSB3 aXRoaW4gYSBWc29jIHJlZ2lvbi4KLSAqCi0gKiBBbiBmZF9zY29wZWQgcGVybWlzc2lvbiBncmFu dHMgYm90aCByZWFkIGFuZCB3cml0ZSBhY2Nlc3MsIGFuZCBjYW4gYmUKLSAqIGF0dGFjaGVkIHRv IGEgZmlsZSBkZXNjcmlwdGlvbiAoc2VlIG9wZW4oMikpLgotICogT3duZXJzaGlwIG9mIHRoZSBh cmVhIGNhbiB0aGVuIGJlIHNoYXJlZCBieSBwYXNzaW5nIGEgZmlsZSBkZXNjcmlwdG9yCi0gKiBh bW9uZyBwcm9jZXNzZXMuCi0gKgotICogYmVnaW5fb2Zmc2V0IGFuZCBlbmRfb2Zmc2V0IGRlZmlu ZSB0aGUgYXJlYSBvZiBtZW1vcnkgdGhhdCBpcyBjb250cm9sbGVkIGJ5Ci0gKiB0aGUgcGVybWlz c2lvbi4gb3duZXJfb2Zmc2V0IHBvaW50cyB0byBhIHdvcmQsIGFsc28gaW4gc2hhcmVkIG1lbW9y eSwgdGhhdAotICogY29udHJvbHMgb3duZXJzaGlwIG9mIHRoZSBhcmVhLgotICoKLSAqIG93bmVy c2hpcCBvZiB0aGUgcmVnaW9uIGV4cGlyZXMgd2hlbiB0aGUgYXNzb2NpYXRlZCBmaWxlIGRlc2Ny aXB0aW9uIGlzCi0gKiByZWxlYXNlZC4KLSAqCi0gKiBBdCBtb3N0IG9uZSBwZXJtaXNzaW9uIGNh biBiZSBhdHRhY2hlZCB0byBlYWNoIGZpbGUgZGVzY3JpcHRpb24uCi0gKgotICogVGhpcyBpcyB1 c2VmdWwgd2hlbiBpbXBsZW1lbnRpbmcgSEFMcyBsaWtlIGdyYWxsb2MgdGhhdCBzY29wZSBhbmQg cGFzcwotICogb3duZXJzaGlwIG9mIHNoYXJlZCByZXNvdXJjZXMgdmlhIGZpbGUgZGVzY3JpcHRv cnMuCi0gKgotICogVGhlIGNhbGxlciBpcyByZXNwb25zaWJlIGZvciBkb2luZyBhbnkgZmVuY2lu Zy4KLSAqCi0gKiBUaGUgY2FsbGluZyBwcm9jZXNzIHdpbGwgbm9ybWFsbHkgaWRlbnRpZnkgYSBj dXJyZW50bHkgZnJlZSBhcmVhIG9mCi0gKiBtZW1vcnkuIEl0IHdpbGwgY29uc3RydWN0IGEgcHJv cG9zZWQgZmRfc2NvcGVkX3Blcm1pc3Npb25fYXJnIHN0cnVjdHVyZToKLSAqCi0gKiAgIGJlZ2lu X29mZnNldCBhbmQgZW5kX29mZnNldCBkZXNjcmliZSB0aGUgYXJlYSBiZWluZyBjbGFpbWVkCi0g KgotICogICBvd25lcl9vZmZzZXQgcG9pbnRzIHRvIHRoZSBsb2NhdGlvbiBpbiBzaGFyZWQgbWVt b3J5IHRoYXQgaW5kaWNhdGVzIHRoZQotICogICBvd25lciBvZiB0aGUgYXJlYS4KLSAqCi0gKiAg IG93bmVkX3ZhbHVlIGlzIHRoZSB2YWx1ZSB0aGF0IHdpbGwgYmUgc3RvcmVkIGluIG93bmVyX29m ZnNldCBpZmYgdGhlCi0gKiAgIHBlcm1pc3Npb24gY2FuIGJlIGdyYW50ZWQuIEl0IG11c3QgYmUg ZGlmZmVyZW50IHRoYW4gVlNPQ19SRUdJT05fRlJFRS4KLSAqCi0gKiBUd28gZmRfc2NvcGVkX3Bl cm1pc3Npb24gc3RydWN0dXJlcyBhcmUgY29tcGF0aWJsZSBpZiB0aGV5IHZhcnkgb25seSBieQot ICogdGhlaXIgb3duZWRfdmFsdWUgZmllbGRzLgotICoKLSAqIFRoZSBkcml2ZXIgZW5zdXJlcyB0 aGF0LCBmb3IgYW55IGdyb3VwIG9mIHNpbXVsdGFuZW91cyBjYWxsZXJzIHByb3Bvc2luZwotICog Y29tcGF0aWJsZSBmZF9zY29wZWRfcGVybWlzc2lvbnMsIGl0IHdpbGwgYWNjZXB0IGV4YWN0bHkg b25lIG9mIHRoZQotICogcHJvcG9wc2Fscy4gVGhlIG90aGVyIGNhbGxlcnMgd2lsbCBnZXQgYSBm YWlsdXJlIHdpdGggZXJybm8gb2YgRUFHQUlOLgotICoKLSAqIEEgcHJvY2VzcyByZWNlaXZpbmcg YSBmaWxlIGRlc2NyaXB0b3IgY2FuIGlkZW50aWZ5IHRoZSByZWdpb24gYmVpbmcKLSAqIGdyYW50 ZWQgdXNpbmcgdGhlIFZTT0NfR0VUX0ZEX1NDT1BFRF9QRVJNSVNTSU9OIGlvY3RsLgotICovCi1z dHJ1Y3QgZmRfc2NvcGVkX3Blcm1pc3Npb24gewotCV9fdTMyIGJlZ2luX29mZnNldDsKLQlfX3Uz MiBlbmRfb2Zmc2V0OwotCV9fdTMyIG93bmVyX29mZnNldDsKLQlfX3UzMiBvd25lZF92YWx1ZTsK LX07Ci0KLS8qCi0gKiBUaGlzIHZhbHVlIHJlcHJlc2VudHMgYSBmcmVlIGFyZWEgb2YgbWVtb3J5 LiBUaGUgZHJpdmVyIGV4cGVjdHMgdG8gc2VlIHRoaXMKLSAqIHZhbHVlIGF0IG93bmVyX29mZnNl dCB3aGVuIGNyZWF0aW5nIGEgcGVybWlzc2lvbiBvdGhlcndpc2UgaXQgd2lsbCBub3QgZG8gaXQs Ci0gKiBhbmQgd2lsbCB3cml0ZSB0aGlzIHZhbHVlIGJhY2sgb25jZSB0aGUgcGVybWlzc2lvbiBp cyBubyBsb25nZXIgbmVlZGVkLgotICovCi0jZGVmaW5lIFZTT0NfUkVHSU9OX0ZSRUUgKChfX3Uz MikwKQotCi0vKioKLSAqIGlvY3RsIGFyZ3VtZW50IGZvciBWU09DX0NSRUFURV9GRF9TQ09QRV9Q RVJNSVNTSU9OCi0gKi8KLXN0cnVjdCBmZF9zY29wZWRfcGVybWlzc2lvbl9hcmcgewotCXN0cnVj dCBmZF9zY29wZWRfcGVybWlzc2lvbiBwZXJtOwotCV9fczMyIG1hbmFnZWRfcmVnaW9uX2ZkOwot fTsKLQotI2RlZmluZSBWU09DX05PREVfRlJFRSAoKF9fdTMyKTApCi0KLS8qCi0gKiBEZXNjcmli ZXMgYSBzaWduYWwgdGFibGUgaW4gc2hhcmVkIG1lbW9yeS4gRWFjaCBub24temVybyBlbnRyeSBp biB0aGUKLSAqIHRhYmxlIGluZGljYXRlcyB0aGF0IHRoZSByZWNlaXZlciBzaG91bGQgc2lnbmFs IHRoZSBmdXRleCBhdCB0aGUgZ2l2ZW4KLSAqIG9mZnNldC4gT2Zmc2V0cyBhcmUgcmVsYXRpdmUg dG8gdGhlIHJlZ2lvbiwgbm90IHRoZSBzaGFyZWQgbWVtb3J5IHdpbmRvdy4KLSAqCi0gKiBpbnRl cnJ1cHRfc2lnbmFsbGVkX29mZnNldCBpcyB1c2VkIHRvIHJlbGlhYmx5IHNpZ25hbCBpbnRlcnJ1 cHRzIGFjcm9zcyB0aGUKLSAqIHZtbSBib3VuZGFyeS4gVGhlcmUgYXJlIHR3byByb2xlczogdHJh bnNtaXR0ZXIgYW5kIHJlY2VpdmVyLiBGb3IgZXhhbXBsZSwKLSAqIGluIHRoZSBob3N0X3RvX2d1 ZXN0X3NpZ25hbF90YWJsZSB0aGUgaG9zdCBpcyB0aGUgdHJhbnNtaXR0ZXIgYW5kIHRoZQotICog Z3Vlc3QgaXMgdGhlIHJlY2VpdmVyLiBUaGUgcHJvdG9jb2wgaXMgYXMgZm9sbG93czoKLSAqCi0g KiAxLiBUaGUgdHJhbnNtaXR0ZXIgc2hvdWxkIGNvbnZlcnQgdGhlIG9mZnNldCBvZiB0aGUgZnV0 ZXggdG8gYW4gb2Zmc2V0Ci0gKiAgICBpbiB0aGUgc2lnbmFsIHRhYmxlIFswLCAoMSA8PCBudW1f bm9kZXNfbGcyKSkKLSAqICAgIFRoZSB0cmFuc21pdHRlciBjYW4gY2hvb3NlIGFueSBhcHByb3By aWF0ZSBoYXNoaW5nIGFsZ29yaXRobSwgaW5jbHVkaW5nCi0gKiAgICBoYXNoID0gZnV0ZXhfb2Zm c2V0ICYgKCgxIDw8IG51bV9ub2Rlc19sZzIpIC0gMSkKLSAqCi0gKiAzLiBUaGUgdHJhbnNtaXR0 ZXIgc2hvdWxkIGF0b21pY2FsbHkgY29tcGFyZSBhbmQgc3dhcCBmdXRleF9vZmZzZXQgd2l0aCAw Ci0gKiAgICBhdCBoYXNoLiBUaGVyZSBhcmUgMyBwb3NzaWJsZSBvdXRjb21lcwotICogICAgICBh LiBUaGUgc3dhcCBmYWlscyBiZWNhdXNlIHRoZSBmdXRleF9vZmZzZXQgaXMgYWxyZWFkeSBpbiB0 aGUgdGFibGUuCi0gKiAgICAgICAgIFRoZSB0cmFuc21pdHRlciBzaG91bGQgc3RvcC4KLSAqICAg ICAgYi4gU29tZSBvdGhlciBvZmZzZXQgaXMgaW4gdGhlIHRhYmxlLiBUaGlzIGlzIGEgaGFzaCBj b2xsaXNpb24uIFRoZQotICogICAgICAgICB0cmFuc21pdHRlciBzaG91bGQgbW92ZSB0byBhbm90 aGVyIHRhYmxlIHNsb3QgYW5kIHRyeSBhZ2Fpbi4gT25lCi0gKiAgICAgICAgIHBvc3NpYmxlIGFs Z29yaXRobToKLSAqICAgICAgICAgaGFzaCA9IChoYXNoICsgMSkgJiAoKDEgPDwgbnVtX25vZGVz X2xnMikgLSAxKQotICogICAgICBjLiBUaGUgc3dhcCB3b3JrZWQuIENvbnRpbnVlIGJlbG93Lgot ICoKLSAqIDMuIFRoZSB0cmFuc21pdHRlciBhdG9taWNhbGx5IHN3YXBzIDEgd2l0aCB0aGUgdmFs dWUgYXQgdGhlCi0gKiAgICBpbnRlcnJ1cHRfc2lnbmFsbGVkX29mZnNldC4gVGhlcmUgYXJlIHR3 byBvdXRjb21lczoKLSAqICAgICAgYS4gVGhlIHByaW9yIHZhbHVlIHdhcyAxLiBJbiB0aGlzIGNh c2UgYW4gaW50ZXJydXB0IGhhcyBhbHJlYWR5IGJlZW4KLSAqICAgICAgICAgcG9zdGVkLiBUaGUg dHJhbnNtaXR0ZXIgaXMgZG9uZS4KLSAqICAgICAgYi4gVGhlIHByaW9yIHZhbHVlIHdhcyAwLCBp bmRpY2F0aW5nIHRoYXQgdGhlIHJlY2VpdmVyIG1heSBiZSBzbGVlcGluZy4KLSAqICAgICAgICAg VGhlIHRyYW5zbWl0dGVyIHdpbGwgaXNzdWUgYW4gaW50ZXJydXB0LgotICoKLSAqIDQuIE9uIHdh a2luZyB0aGUgcmVjZWl2ZXIgaW1tZWRpYXRlbHkgZXhjaGFuZ2VzIGEgMCB3aXRoIHRoZQotICog ICAgaW50ZXJydXB0X3NpZ25hbGxlZF9vZmZzZXQuIElmIGl0IHJlY2VpdmVzIGEgMCB0aGVuIHRo aXMgYSBzcHVyaW91cwotICogICAgaW50ZXJydXB0LiBUaGF0IG1heSBvY2Nhc2lvbmFsbHkgaGFw cGVuIGluIHRoZSBjdXJyZW50IHByb3RvY29sLCBidXQKLSAqICAgIHNob3VsZCBiZSByYXJlLgot ICoKLSAqIDUuIFRoZSByZWNlaXZlciBzY2FucyB0aGUgc2lnbmFsIHRhYmxlIGJ5IGF0b21pY2Fs eSBleGNoYW5naW5nIDAgYXQgZWFjaAotICogICAgbG9jYXRpb24uIElmIGEgbm9uLXplcm8gb2Zm c2V0IGlzIHJldHVybmVkIGZyb20gdGhlIGV4Y2hhbmdlIHRoZQotICogICAgcmVjZWl2ZXIgd2Fr ZXMgYWxsIHNsZWVwZXJzIGF0IHRoZSBnaXZlbiBvZmZzZXQ6Ci0gKiAgICAgIGZ1dGV4KChpbnQq KShyZWdpb25fYmFzZSArIG9sZF92YWx1ZSksIEZVVEVYX1dBS0UsIE1BWF9JTlQpOwotICoKLSAq IDYuIFRoZSByZWNlaXZlciB0aHJlYWQgdGhlbiBkb2VzIGEgY29uZGl0aW9uYWwgd2FpdCwgd2Fr aW5nIGltbWVkaWF0ZWx5Ci0gKiAgICBpZiB0aGUgdmFsdWUgYXQgaW50ZXJydXB0X3NpZ25hbGxl ZF9vZmZzZXQgaXMgbm9uLXplcm8uIFRoaXMgY2F0Y2hlcyBjYXNlcwotICogICAgaGVyZSBhZGRp dGlvbmFsICBzaWduYWxzIHdlcmUgcG9zdGVkIHdoaWxlIHRoZSB0YWJsZSB3YXMgYmVpbmcgc2Nh bm5lZC4KLSAqICAgIE9uIHRoZSBndWVzdCB0aGUgd2FpdCBpcyBoYW5kbGVkIHZpYSB0aGUgVlNP Q19XQUlUX0ZPUl9JTkNPTUlOR19JTlRFUlJVUFQKLSAqICAgIGlvY3RsLgotICovCi1zdHJ1Y3Qg dnNvY19zaWduYWxfdGFibGVfbGF5b3V0IHsKLQkvKiBsb2dfMihOdW1iZXIgb2Ygc2lnbmFsIHRh YmxlIGVudHJpZXMpICovCi0JX191MzIgbnVtX25vZGVzX2xnMjsKLQkvKgotCSAqIE9mZnNldCB0 byB0aGUgZmlyc3Qgc2lnbmFsIHRhYmxlIGVudHJ5IHJlbGF0aXZlIHRvIHRoZSBzdGFydCBvZiB0 aGUKLQkgKiByZWdpb24KLQkgKi8KLQlfX3UzMiBmdXRleF91YWRkcl90YWJsZV9vZmZzZXQ7Ci0J LyoKLQkgKiBPZmZzZXQgdG8gYW4gYXRvbWljX3QgLyBhdG9taWMgdWludDMyX3QuIEEgbm9uLXpl cm8gdmFsdWUgaW5kaWNhdGVzCi0JICogdGhhdCBvbmUgb3IgbW9yZSBvZmZzZXRzIGFyZSBjdXJy ZW50bHkgcG9zdGVkIGluIHRoZSB0YWJsZS4KLQkgKiBzZW1pLXVuaXF1ZSBhY2Nlc3MgdG8gYW4g ZW50cnkgaW4gdGhlIHRhYmxlCi0JICovCi0JX191MzIgaW50ZXJydXB0X3NpZ25hbGxlZF9vZmZz ZXQ7Ci19OwotCi0jZGVmaW5lIFZTT0NfUkVHSU9OX1dIT0xFICgoX19zMzIpMCkKLSNkZWZpbmUg VlNPQ19ERVZJQ0VfTkFNRV9TWiAxNgotCi0vKioKLSAqIEVhY2ggSEFMIHdvdWxkICh1c3VhbGx5 KSB0YWxrIHRvIGEgc2luZ2xlIGRldmljZSByZWdpb24KLSAqIE11bGl0cGxlIGVudGl0aWVzIGNh cmUgYWJvdXQgdGhlc2UgcmVnaW9uczoKLSAqIC0gVGhlIGl2c2htZW1fc2VydmVyIHdpbGwgcG9w dWxhdGUgdGhlIHJlZ2lvbnMgaW4gc2hhcmVkIG1lbW9yeQotICogLSBUaGUgZ3Vlc3Qga2VybmVs IHdpbGwgcmVhZCB0aGUgcmVnaW9uLCBjcmVhdGUgbWlub3IgZGV2aWNlIG5vZGVzLCBhbmQKLSAq ICAgYWxsb3cgaW50ZXJlc3RlZCBwYXJ0aWVzIHRvIHJlZ2lzdGVyIGZvciBGVVRFWF9XQUtFIGV2 ZW50cyBpbiB0aGUgcmVnaW9uCi0gKiAtIEhBTHMgd2lsbCBhY2Nlc3MgdmlhIHRoZSBtaW5vciBk ZXZpY2Ugbm9kZXMgcHVibGlzaGVkIGJ5IHRoZSBndWVzdCBrZXJuZWwKLSAqIC0gSG9zdCBzaWRl IHByb2Nlc3NlcyB3aWxsIGFjY2VzcyB0aGUgcmVnaW9uIHZpYSB0aGUgaXZzaG1lbV9zZXJ2ZXI6 Ci0gKiAgIDEuIFBhc3MgbmFtZSB0byBpdnNobWVtX3NlcnZlciBhdCBhIFVOSVggc29ja2V0Ci0g KiAgIDIuIGl2c2htZW1zZXJ2ZXIgd2lsbCByZXBseSB3aXRoIDIgZmRzOgotICogICAgIC0gaG9z dC0+Z3Vlc3QgZG9vcmJlbGwgZmQKLSAqICAgICAtIGd1ZXN0LT5ob3N0IGRvb3JiZWxsIGZkCi0g KiAgICAgLSBmZCBmb3IgdGhlIHNoYXJlZCBtZW1vcnkgcmVnaW9uCi0gKiAgICAgLSByZWdpb24g b2Zmc2V0Ci0gKiAgIDMuIFN0YXJ0IGEgZnV0ZXggcmVjZWl2ZXIgdGhyZWFkIG9uIHRoZSBkb29y YmVsbCBmZCBwb2ludGVkIGF0IHRoZQotICogICAgICBzaWduYWxfbm9kZXMKLSAqLwotc3RydWN0 IHZzb2NfZGV2aWNlX3JlZ2lvbiB7Ci0JX191MTYgY3VycmVudF92ZXJzaW9uOwotCV9fdTE2IG1p bl9jb21wYXRpYmxlX3ZlcnNpb247Ci0JX191MzIgcmVnaW9uX2JlZ2luX29mZnNldDsKLQlfX3Uz MiByZWdpb25fZW5kX29mZnNldDsKLQlfX3UzMiBvZmZzZXRfb2ZfcmVnaW9uX2RhdGE7Ci0Jc3Ry dWN0IHZzb2Nfc2lnbmFsX3RhYmxlX2xheW91dCBndWVzdF90b19ob3N0X3NpZ25hbF90YWJsZTsK LQlzdHJ1Y3QgdnNvY19zaWduYWxfdGFibGVfbGF5b3V0IGhvc3RfdG9fZ3Vlc3Rfc2lnbmFsX3Rh YmxlOwotCS8qIE5hbWUgb2YgdGhlIGRldmljZS4gTXVzdCBhbHdheXMgYmUgdGVybWluYXRlZCB3 aXRoIGEgJ1wwJywgc28KLQkgKiB0aGUgbG9uZ2VzdCBzdXBwb3J0ZWQgZGV2aWNlIG5hbWUgaXMg MTUgY2hhcmFjdGVycy4KLQkgKi8KLQljaGFyIGRldmljZV9uYW1lW1ZTT0NfREVWSUNFX05BTUVf U1pdOwotCS8qIFRoZXJlIGFyZSB0d28gd2F5cyB0aGF0IHBlcm1pc3Npb25zIHRvIGFjY2VzcyBy ZWdpb25zIGFyZSBoYW5kbGVkOgotCSAqICAgLSBXaGVuIHN1YmRpdmlkZWRfYnkgaXMgVlNPQ19S RUdJT05fV0hPTEUsIGFueSBwcm9jZXNzIHRoYXQgY2FuCi0JICogICAgIG9wZW4gdGhlIGRldmlj ZSBub2RlIGZvciB0aGUgcmVnaW9uIGdhaW5zIGNvbXBsZXRlIGFjY2VzcyB0byBpdC4KLQkgKiAg IC0gV2hlbiBzdWJkaXZpZGVkIGlzIHNldCBwcm9jZXNzZXMgdGhhdCBvcGVuIHRoZSByZWdpb24g Y2Fubm90Ci0JICogICAgIGFjY2VzcyBpdC4gQWNjZXNzIHRvIGEgc3ViLXJlZ2lvbiBtdXN0IGJl IGVzdGFibGlzaGVkIGJ5IGludm9raW5nCi0JICogICAgIHRoZSBWU09DX0NSRUFURV9GRF9TQ09Q RV9QRVJNSVNTSU9OIGlvY3RsIG9uIHRoZSByZWdpb24KLQkgKiAgICAgcmVmZXJlbmNlZCBpbiBz dWJkaXZpZGVkX2J5LCBwcm92aWRpbmcgYSBmaWxlaW5zdGFuY2UKLQkgKiAgICAgKHJlcHJlc2Vu dGVkIGJ5IGEgZmQpIG9wZW5lZCBvbiB0aGlzIHJlZ2lvbi4KLQkgKi8KLQlfX3UzMiBtYW5hZ2Vk X2J5OwotfTsKLQotLyoKLSAqIFRoZSB2c29jIGxheW91dCBkZXNjcmlwdG9yLgotICogVGhlIGZp cnN0IDRLIHNob3VsZCBiZSByZXNlcnZlZCBmb3IgdGhlIHNobSBoZWFkZXIgYW5kIHJlZ2lvbiBk ZXNjcmlwdG9ycy4KLSAqIFRoZSByZWdpb25zIHNob3VsZCBiZSBwYWdlIGFsaWduZWQuCi0gKi8K LQotc3RydWN0IHZzb2Nfc2htX2xheW91dF9kZXNjcmlwdG9yIHsKLQlfX3UxNiBtYWpvcl92ZXJz aW9uOwotCV9fdTE2IG1pbm9yX3ZlcnNpb247Ci0KLQkvKiBzaXplIG9mIHRoZSBzaG0uIFRoaXMg bWF5IGJlIHJlZHVuZGFudCBidXQgbmljZSB0byBoYXZlICovCi0JX191MzIgc2l6ZTsKLQotCS8q IG51bWJlciBvZiBzaGFyZWQgbWVtb3J5IHJlZ2lvbnMgKi8KLQlfX3UzMiByZWdpb25fY291bnQ7 Ci0KLQkvKiBUaGUgb2Zmc2V0IHRvIHRoZSBzdGFydCBvZiByZWdpb24gZGVzY3JpcHRvcnMgKi8K LQlfX3UzMiB2c29jX3JlZ2lvbl9kZXNjX29mZnNldDsKLX07Ci0KLS8qCi0gKiBUaGlzIHNwZWNp ZmllcyB0aGUgY3VycmVudCB2ZXJzaW9uIHRoYXQgc2hvdWxkIGJlIHN0b3JlZCBpbgotICogdnNv Y19zaG1fbGF5b3V0X2Rlc2NyaXB0b3IubWFqb3JfdmVyc2lvbiBhbmQKLSAqIHZzb2Nfc2htX2xh eW91dF9kZXNjcmlwdG9yLm1pbm9yX3ZlcnNpb24uCi0gKiBJdCBzaG91bGQgYmUgdXBkYXRlZCBv bmx5IGlmIHRoZSB2c29jX2RldmljZV9yZWdpb24gYW5kCi0gKiB2c29jX3NobV9sYXlvdXRfZGVz Y3JpcHRvciBzdHJ1Y3R1cmVzIGhhdmUgY2hhbmdlZC4KLSAqIFZlcnNpb25pbmcgd2l0aGluIGVh Y2ggcmVnaW9uIGlzIHRyYW5zZmVycmVkCi0gKiB2aWEgdGhlIG1pbl9jb21wYXRpYmxlX3ZlcnNp b24gYW5kIGN1cnJlbnRfdmVyc2lvbiBmaWVsZHMgaW4KLSAqIHZzb2NfZGV2aWNlX3JlZ2lvbi4g VGhlIGRyaXZlciBkb2VzIG5vdCBjb25zdWx0IHRoZXNlIGZpZWxkczogdGhleSBhcmUgbGVmdAot ICogZm9yIHRoZSBIQUxzIGFuZCBob3N0IHByb2Nlc3NlcyBhbmQgd2lsbCBjaGFuZ2UgaW5kZXBl bmRlbnRseSBvZiB0aGUgbGF5b3V0Ci0gKiB2ZXJzaW9uLgotICovCi0jZGVmaW5lIENVUlJFTlRf VlNPQ19MQVlPVVRfTUFKT1JfVkVSU0lPTiAyCi0jZGVmaW5lIENVUlJFTlRfVlNPQ19MQVlPVVRf TUlOT1JfVkVSU0lPTiAwCi0KLSNkZWZpbmUgVlNPQ19DUkVBVEVfRkRfU0NPUEVEX1BFUk1JU1NJ T04gXAotCV9JT1coMHhGNSwgMCwgc3RydWN0IGZkX3Njb3BlZF9wZXJtaXNzaW9uKQotI2RlZmlu ZSBWU09DX0dFVF9GRF9TQ09QRURfUEVSTUlTU0lPTiBfSU9SKDB4RjUsIDEsIHN0cnVjdCBmZF9z Y29wZWRfcGVybWlzc2lvbikKLQotLyoKLSAqIFRoaXMgaXMgdXNlZCB0byBzaWduYWwgdGhlIGhv c3QgdG8gc2NhbiB0aGUgZ3Vlc3RfdG9faG9zdF9zaWduYWxfdGFibGUKLSAqIGZvciBuZXcgZnV0 ZXhlcyB0byB3YWtlLiBUaGlzIHNlbmRzIGFuIGludGVycnVwdCBpZiBvbmUgaXMgbm90IGFscmVh ZHkKLSAqIGluIGZsaWdodC4KLSAqLwotI2RlZmluZSBWU09DX01BWUJFX1NFTkRfSU5URVJSVVBU X1RPX0hPU1QgX0lPKDB4RjUsIDIpCi0KLS8qCi0gKiBXaGVuIHRoaXMgcmV0dXJucyB0aGUgZ3Vl c3Qgd2lsbCBzY2FuIGhvc3RfdG9fZ3Vlc3Rfc2lnbmFsX3RhYmxlIHRvCi0gKiBjaGVjayBmb3Ig bmV3IGZ1dGV4ZXMgdG8gd2FrZS4KLSAqLwotLyogVE9ETyhnaGFydG1hbik6IENvbnNpZGVyIG1v dmluZyB0aGlzIHRvIHRoZSBib3R0b20gaGFsZiAqLwotI2RlZmluZSBWU09DX1dBSVRfRk9SX0lO Q09NSU5HX0lOVEVSUlVQVCBfSU8oMHhGNSwgMykKLQotLyoKLSAqIEd1ZXN0IEhBTHMgd2lsbCB1 c2UgdGhpcyB0byByZXRyaWV2ZSB0aGUgcmVnaW9uIGRlc2NyaXB0aW9uIGFmdGVyCi0gKiBvcGVu aW5nIHRoZWlyIGRldmljZSBub2RlLgotICovCi0jZGVmaW5lIFZTT0NfREVTQ1JJQkVfUkVHSU9O IF9JT1IoMHhGNSwgNCwgc3RydWN0IHZzb2NfZGV2aWNlX3JlZ2lvbikKLQotLyoKLSAqIFdha2Ug YW55IHRocmVhZHMgdGhhdCBtYXkgYmUgd2FpdGluZyBmb3IgYSBob3N0IGludGVycnVwdCBvbiB0 aGlzIHJlZ2lvbi4KLSAqIFRoaXMgaXMgbW9zdGx5IHVzZWQgZHVyaW5nIHNodXRkb3duLgotICov Ci0jZGVmaW5lIFZTT0NfU0VMRl9JTlRFUlJVUFQgX0lPKDB4RjUsIDUpCi0KLS8qCi0gKiBUaGlz IGlzIHVzZWQgdG8gc2lnbmFsIHRoZSBob3N0IHRvIHNjYW4gdGhlIGd1ZXN0X3RvX2hvc3Rfc2ln bmFsX3RhYmxlCi0gKiBmb3IgbmV3IGZ1dGV4ZXMgdG8gd2FrZS4gVGhpcyBzZW5kcyBhbiBpbnRl cnJ1cHQgdW5jb25kaXRpb25hbGx5LgotICovCi0jZGVmaW5lIFZTT0NfU0VORF9JTlRFUlJVUFRf VE9fSE9TVCBfSU8oMHhGNSwgNikKLQotZW51bSB3YWl0X3R5cGVzIHsKLQlWU09DX1dBSVRfVU5E RUZJTkVEID0gMCwKLQlWU09DX1dBSVRfSUZfRVFVQUwgPSAxLAotCVZTT0NfV0FJVF9JRl9FUVVB TF9USU1FT1VUID0gMgotfTsKLQotLyoKLSAqIFdhaXQgZm9yIGEgY29uZGl0aW9uIHRvIGJlIHRy dWUKLSAqCi0gKiBOb3RlLCB0aGlzIGlzIHNpemVkIGFuZCBhbGlnbmVkIHNvIHRoZSAzMiBiaXQg YW5kIDY0IGJpdCBsYXlvdXRzIGFyZQotICogaWRlbnRpY2FsLgotICovCi1zdHJ1Y3QgdnNvY19j b25kX3dhaXQgewotCS8qIElucHV0OiBPZmZzZXQgb2YgdGhlIDMyIGJpdCB3b3JkIHRvIGNoZWNr ICovCi0JX191MzIgb2Zmc2V0OwotCS8qIElucHV0OiBWYWx1ZSB0aGF0IHdpbGwgYmUgY29tcGFy ZWQgd2l0aCB0aGUgb2Zmc2V0ICovCi0JX191MzIgdmFsdWU7Ci0JLyogTW9ub3RvbmljIHRpbWUg dG8gd2FrZSBhdCBpbiBzZWNvbmRzICovCi0JX191NjQgd2FrZV90aW1lX3NlYzsKLQkvKiBJbnB1 dDogTW9ub3RvbmljIHRpbWUgdG8gd2FpdCBpbiBuYW5vc2Vjb25kcyAqLwotCV9fdTMyIHdha2Vf dGltZV9uc2VjOwotCS8qIElucHV0OiBUeXBlIG9mIHdhaXQgKi8KLQlfX3UzMiB3YWl0X3R5cGU7 Ci0JLyogT3V0cHV0OiBOdW1iZXIgb2YgdGltZXMgdGhlIHRocmVhZCB3b2tlIGJlZm9yZSByZXR1 cm5pbmcuICovCi0JX191MzIgd2FrZXM7Ci0JLyogRW5zdXJlIHRoYXQgd2UncmUgOC1ieXRlIGFs aWduZWQgYW5kIDggYnl0ZSBsZW5ndGggZm9yIDMyLzY0IGJpdAotCSAqIGNvbXBhdGliaWxpdHku Ci0JICovCi0JX191MzIgcmVzZXJ2ZWRfMTsKLX07Ci0KLSNkZWZpbmUgVlNPQ19DT05EX1dBSVQg X0lPV1IoMHhGNSwgNywgc3RydWN0IHZzb2NfY29uZF93YWl0KQotCi0vKiBXYWtlIGFueSBsb2Nh bCB0aHJlYWRzIHdhaXRpbmcgYXQgdGhlIG9mZnNldCBnaXZlbiBpbiBhcmcgKi8KLSNkZWZpbmUg VlNPQ19DT05EX1dBS0UgX0lPKDB4RjUsIDgpCi0KLSNlbmRpZiAvKiBfVUFQSV9MSU5VWF9WU09D X1NITV9IICovCmRpZmYgLS1naXQgYS9kcml2ZXJzL3N0YWdpbmcvYW5kcm9pZC92c29jLmMgYi9k cml2ZXJzL3N0YWdpbmcvYW5kcm9pZC92c29jLmMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0Cmlu ZGV4IDEyNDBiYjAzMTdkOS4uMDAwMDAwMDAwMDAwCi0tLSBhL2RyaXZlcnMvc3RhZ2luZy9hbmRy b2lkL3Zzb2MuYworKysgL2Rldi9udWxsCkBAIC0xLDExNDkgKzAsMCBAQAotLy8gU1BEWC1MaWNl bnNlLUlkZW50aWZpZXI6IEdQTC0yLjAKLS8qCi0gKiBkcml2ZXJzL2FuZHJvaWQvc3RhZ2luZy92 c29jLmMKLSAqCi0gKiBBbmRyb2lkIFZpcnR1YWwgU3lzdGVtIG9uIGEgQ2hpcCAoVlNvQykgZHJp dmVyCi0gKgotICogQ29weXJpZ2h0IChDKSAyMDE3IEdvb2dsZSwgSW5jLgotICoKLSAqIEF1dGhv cjogZ2hhcnRtYW5AZ29vZ2xlLmNvbQotICoKLSAqIEJhc2VkIG9uIGRyaXZlcnMvY2hhci9rdm1f aXZzaG1lbS5jIC0gZHJpdmVyIGZvciBLVk0gSW50ZXItVk0gc2hhcmVkIG1lbW9yeQotICogICAg ICAgICBDb3B5cmlnaHQgMjAwOSBDYW0gTWFjZG9uZWxsIDxjYW1AY3MudWFsYmVydGEuY2E+Ci0g KgotICogQmFzZWQgb24gY2lycnVzZmIuYyBhbmQgODEzOWNwLmM6Ci0gKiAgIENvcHlyaWdodCAx OTk5LTIwMDEgSmVmZiBHYXJ6aWsKLSAqICAgQ29weXJpZ2h0IDIwMDEtMjAwNCBKZWZmIEdhcnpp awotICovCi0KLSNpbmNsdWRlIDxsaW51eC9kbWEtbWFwcGluZy5oPgotI2luY2x1ZGUgPGxpbnV4 L2ZyZWV6ZXIuaD4KLSNpbmNsdWRlIDxsaW51eC9mdXRleC5oPgotI2luY2x1ZGUgPGxpbnV4L2lu aXQuaD4KLSNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4KLSNpbmNsdWRlIDxsaW51eC9tb2R1bGUu aD4KLSNpbmNsdWRlIDxsaW51eC9tdXRleC5oPgotI2luY2x1ZGUgPGxpbnV4L3BjaS5oPgotI2lu Y2x1ZGUgPGxpbnV4L3Byb2NfZnMuaD4KLSNpbmNsdWRlIDxsaW51eC9zY2hlZC5oPgotI2luY2x1 ZGUgPGxpbnV4L3N5c2NhbGxzLmg+Ci0jaW5jbHVkZSA8bGludXgvdWFjY2Vzcy5oPgotI2luY2x1 ZGUgPGxpbnV4L2ludGVycnVwdC5oPgotI2luY2x1ZGUgPGxpbnV4L2NkZXYuaD4KLSNpbmNsdWRl IDxsaW51eC9maWxlLmg+Ci0jaW5jbHVkZSAidWFwaS92c29jX3NobS5oIgotCi0jZGVmaW5lIFZT T0NfREVWX05BTUUgInZzb2MiCi0KLS8qCi0gKiBEZXNjcmlwdGlvbiBvZiB0aGUgaXZzaG1lbS1k b29yYmVsbCBQQ0kgZGV2aWNlIHVzZWQgYnkgUUVtdS4gVGhlc2UKLSAqIGNvbnN0YW50cyBmb2xs b3cgZG9jcy9zcGVjcy9pdnNobWVtLXNwZWMudHh0LCB3aGljaCBjYW4gYmUgZm91bmQgaW4KLSAq IHRoZSBRRW11IHJlcG9zaXRvcnkuIFRoaXMgd2FzIGxhc3QgcmVjb25jaWxlZCB3aXRoIHRoZSB2 ZXJzaW9uIHRoYXQKLSAqIGNhbWUgb3V0IHdpdGggMi44Ci0gKi8KLQotLyoKLSAqIFRoZXNlIGNv bnN0YW50cyBhcmUgZGV0ZXJtaW5lZCBLVk0gSW50ZXItVk0gc2hhcmVkIG1lbW9yeSBkZXZpY2UK LSAqIHJlZ2lzdGVyIG9mZnNldHMKLSAqLwotZW51bSB7Ci0JSU5UUl9NQVNLID0gMHgwMCwJLyog SW50ZXJydXB0IE1hc2sgKi8KLQlJTlRSX1NUQVRVUyA9IDB4MDQsCS8qIEludGVycnVwdCBTdGF0 dXMgKi8KLQlJVl9QT1NJVElPTiA9IDB4MDgsCS8qIFZNIElEICovCi0JRE9PUkJFTEwgPSAweDBj LAkvKiBEb29yYmVsbCAqLwotfTsKLQotc3RhdGljIGNvbnN0IGludCBSRUdJU1RFUl9CQVI7ICAv KiBFcXVhbCB0byAwICovCi1zdGF0aWMgY29uc3QgaW50IE1BWF9SRUdJU1RFUl9CQVJfTEVOID0g MHgxMDA7Ci0vKgotICogVGhlIE1TSS14IEJBUiBpcyBub3QgdXNlZCBkaXJlY3RseS4KLSAqCi0g KiBzdGF0aWMgY29uc3QgaW50IE1TSV9YX0JBUiA9IDE7Ci0gKi8KLXN0YXRpYyBjb25zdCBpbnQg U0hBUkVEX01FTU9SWV9CQVIgPSAyOwotCi1zdHJ1Y3QgdnNvY19yZWdpb25fZGF0YSB7Ci0JY2hh ciBuYW1lW1ZTT0NfREVWSUNFX05BTUVfU1ogKyAxXTsKLQl3YWl0X3F1ZXVlX2hlYWRfdCBpbnRl cnJ1cHRfd2FpdF9xdWV1ZTsKLQkvKiBUT0RPKGIvNzM2NjQxODEpOiBVc2UgbXVsdGlwbGUgZnV0 ZXggd2FpdCBxdWV1ZXMgKi8KLQl3YWl0X3F1ZXVlX2hlYWRfdCBmdXRleF93YWl0X3F1ZXVlOwot CS8qIEZsYWcgaW5kaWNhdGluZyB0aGF0IGFuIGludGVycnVwdCBoYXMgYmVlbiBzaWduYWxsZWQg YnkgdGhlIGhvc3QuICovCi0JYXRvbWljX3QgKmluY29taW5nX3NpZ25hbGxlZDsKLQkvKiBGbGFn IGluZGljYXRpbmcgdGhlIGd1ZXN0IGhhcyBzaWduYWxsZWQgdGhlIGhvc3QuICovCi0JYXRvbWlj X3QgKm91dGdvaW5nX3NpZ25hbGxlZDsKLQlib29sIGlycV9yZXF1ZXN0ZWQ7Ci0JYm9vbCBkZXZp Y2VfY3JlYXRlZDsKLX07Ci0KLXN0cnVjdCB2c29jX2RldmljZSB7Ci0JLyogS2VybmVsIHZpcnR1 YWwgYWRkcmVzcyBvZiBSRUdJU1RFUl9CQVIuICovCi0Jdm9pZCBfX2lvbWVtICpyZWdzOwotCS8q IFBoeXNpY2FsIGFkZHJlc3Mgb2YgU0hBUkVEX01FTU9SWV9CQVIuICovCi0JcGh5c19hZGRyX3Qg c2htX3BoeXNfc3RhcnQ7Ci0JLyogS2VybmVsIHZpcnR1YWwgYWRkcmVzcyBvZiBTSEFSRURfTUVN T1JZX0JBUi4gKi8KLQl2b2lkIF9faW9tZW0gKmtlcm5lbF9tYXBwZWRfc2htOwotCS8qIFNpemUg b2YgdGhlIGVudGlyZSBzaGFyZWQgbWVtb3J5IHdpbmRvdyBpbiBieXRlcy4gKi8KLQlzaXplX3Qg c2htX3NpemU7Ci0JLyoKLQkgKiBQb2ludGVyIHRvIHRoZSB2aXJ0dWFsIGFkZHJlc3Mgb2YgdGhl IHNoYXJlZCBtZW1vcnkgbGF5b3V0IHN0cnVjdHVyZS4KLQkgKiBUaGlzIGlzIHByb2JhYmx5IGlk ZW50aWNhbCB0byBrZXJuZWxfbWFwcGVkX3NobSwgYnV0IHNhdmluZyB0aGlzCi0JICogaGVyZSBz YXZlcyBhIGxvdCBvZiBhbm5veWluZyBjYXN0cy4KLQkgKi8KLQlzdHJ1Y3QgdnNvY19zaG1fbGF5 b3V0X2Rlc2NyaXB0b3IgKmxheW91dDsKLQkvKgotCSAqIFBvaW50cyB0byBhIHRhYmxlIG9mIHJl Z2lvbiBkZXNjcmlwdG9ycyBpbiB0aGUga2VybmVsJ3MgdmlydHVhbAotCSAqIGFkZHJlc3Mgc3Bh Y2UuIENhbGN1bGF0ZWQgZnJvbQotCSAqIHZzb2Nfc2htX2xheW91dF9kZXNjcmlwdG9yLnZzb2Nf cmVnaW9uX2Rlc2Nfb2Zmc2V0Ci0JICovCi0Jc3RydWN0IHZzb2NfZGV2aWNlX3JlZ2lvbiAqcmVn aW9uczsKLQkvKiBIZWFkIG9mIGEgbGlzdCBvZiBwZXJtaXNzaW9ucyB0aGF0IGhhdmUgYmVlbiBn cmFudGVkLiAqLwotCXN0cnVjdCBsaXN0X2hlYWQgcGVybWlzc2lvbnM7Ci0Jc3RydWN0IHBjaV9k ZXYgKmRldjsKLQkvKiBQZXItcmVnaW9uIChhbmQgdGhlcmVmb3JlIHBlci1pbnRlcnJ1cHQpIGlu Zm9ybWF0aW9uLiAqLwotCXN0cnVjdCB2c29jX3JlZ2lvbl9kYXRhICpyZWdpb25zX2RhdGE7Ci0J LyoKLQkgKiBUYWJsZSBvZiBtc2kteCBlbnRyaWVzLiBUaGlzIGhhcyB0byBiZSBzZXBhcmF0ZWQg ZnJvbSBzdHJ1Y3QKLQkgKiB2c29jX3JlZ2lvbl9kYXRhIGJlY2F1c2UgdGhlIGtlcm5lbCBkZWFs cyB3aXRoIHRoZW0gYXMgYW4gYXJyYXkuCi0JICovCi0Jc3RydWN0IG1zaXhfZW50cnkgKm1zaXhf ZW50cmllczsKLQkvKiBNdXRleCB0aGF0IHByb3RlY3RlcyB0aGUgcGVybWlzc2lvbiBsaXN0ICov Ci0Jc3RydWN0IG11dGV4IG10eDsKLQkvKiBNYWpvciBudW1iZXIgYXNzaWduZWQgYnkgdGhlIGtl cm5lbCAqLwotCWludCBtYWpvcjsKLQkvKiBDaGFyYWN0ZXIgZGV2aWNlIGFzc2lnbmVkIGJ5IHRo ZSBrZXJuZWwgKi8KLQlzdHJ1Y3QgY2RldiBjZGV2OwotCS8qIERldmljZSBjbGFzcyBhc3NpZ25l ZCBieSB0aGUga2VybmVsICovCi0Jc3RydWN0IGNsYXNzICpjbGFzczsKLQkvKgotCSAqIEZsYWdz IHRoYXQgaW5kaWNhdGUgd2hhdCB3ZSd2ZSBpbml0aWFsaXplZC4gVGhlc2UgYXJlIHVzZWQgdG8g ZG8gYW4KLQkgKiBvcmRlcmx5IGNsZWFudXAgb2YgdGhlIGRldmljZS4KLQkgKi8KLQlib29sIGVu YWJsZWRfZGV2aWNlOwotCWJvb2wgcmVxdWVzdGVkX3JlZ2lvbnM7Ci0JYm9vbCBjZGV2X2FkZGVk OwotCWJvb2wgY2xhc3NfYWRkZWQ7Ci0JYm9vbCBtc2l4X2VuYWJsZWQ7Ci19OwotCi1zdGF0aWMg c3RydWN0IHZzb2NfZGV2aWNlIHZzb2NfZGV2OwotCi0vKgotICogVE9ETyhnaGFydG1hbik6IEFk ZCBhIC9zeXMgZmlsZXN5c3RlbSBlbnRyeSB0aGF0IHN1bW1hcml6ZXMgdGhlIHBlcm1pc3Npb25z LgotICovCi0KLXN0cnVjdCBmZF9zY29wZWRfcGVybWlzc2lvbl9ub2RlIHsKLQlzdHJ1Y3QgZmRf c2NvcGVkX3Blcm1pc3Npb24gcGVybWlzc2lvbjsKLQlzdHJ1Y3QgbGlzdF9oZWFkIGxpc3Q7Ci19 OwotCi1zdHJ1Y3QgdnNvY19wcml2YXRlX2RhdGEgewotCXN0cnVjdCBmZF9zY29wZWRfcGVybWlz c2lvbl9ub2RlICpmZF9zY29wZWRfcGVybWlzc2lvbl9ub2RlOwotfTsKLQotc3RhdGljIGxvbmcg dnNvY19pb2N0bChzdHJ1Y3QgZmlsZSAqLCB1bnNpZ25lZCBpbnQsIHVuc2lnbmVkIGxvbmcpOwot c3RhdGljIGludCB2c29jX21tYXAoc3RydWN0IGZpbGUgKiwgc3RydWN0IHZtX2FyZWFfc3RydWN0 ICopOwotc3RhdGljIGludCB2c29jX29wZW4oc3RydWN0IGlub2RlICosIHN0cnVjdCBmaWxlICop Owotc3RhdGljIGludCB2c29jX3JlbGVhc2Uoc3RydWN0IGlub2RlICosIHN0cnVjdCBmaWxlICop Owotc3RhdGljIHNzaXplX3QgdnNvY19yZWFkKHN0cnVjdCBmaWxlICosIGNoYXIgX191c2VyICos IHNpemVfdCwgbG9mZl90ICopOwotc3RhdGljIHNzaXplX3QgdnNvY193cml0ZShzdHJ1Y3QgZmls ZSAqLCBjb25zdCBjaGFyIF9fdXNlciAqLCBzaXplX3QsIGxvZmZfdCAqKTsKLXN0YXRpYyBsb2Zm X3QgdnNvY19sc2VlayhzdHJ1Y3QgZmlsZSAqZmlscCwgbG9mZl90IG9mZnNldCwgaW50IG9yaWdp bik7Ci1zdGF0aWMgaW50Ci1kb19jcmVhdGVfZmRfc2NvcGVkX3Blcm1pc3Npb24oc3RydWN0IHZz b2NfZGV2aWNlX3JlZ2lvbiAqcmVnaW9uX3AsCi0JCQkgICAgICAgc3RydWN0IGZkX3Njb3BlZF9w ZXJtaXNzaW9uX25vZGUgKm5wLAotCQkJICAgICAgIHN0cnVjdCBmZF9zY29wZWRfcGVybWlzc2lv bl9hcmcgX191c2VyICphcmcpOwotc3RhdGljIHZvaWQKLWRvX2Rlc3Ryb3lfZmRfc2NvcGVkX3Bl cm1pc3Npb24oc3RydWN0IHZzb2NfZGV2aWNlX3JlZ2lvbiAqb3duZXJfcmVnaW9uX3AsCi0JCQkJ c3RydWN0IGZkX3Njb3BlZF9wZXJtaXNzaW9uICpwZXJtKTsKLXN0YXRpYyBsb25nIGRvX3Zzb2Nf ZGVzY3JpYmVfcmVnaW9uKHN0cnVjdCBmaWxlICosCi0JCQkJICAgIHN0cnVjdCB2c29jX2Rldmlj ZV9yZWdpb24gX191c2VyICopOwotc3RhdGljIHNzaXplX3QgdnNvY19nZXRfYXJlYShzdHJ1Y3Qg ZmlsZSAqZmlscCwgX191MzIgKnBlcm1fb2ZmKTsKLQotLyoqCi0gKiBWYWxpZGF0ZSBhcmd1bWVu dHMgb24gZW50cnkgcG9pbnRzIHRvIHRoZSBkcml2ZXIuCi0gKi8KLWlubGluZSBpbnQgdnNvY192 YWxpZGF0ZV9pbm9kZShzdHJ1Y3QgaW5vZGUgKmlub2RlKQotewotCWlmIChpbWlub3IoaW5vZGUp ID49IHZzb2NfZGV2LmxheW91dC0+cmVnaW9uX2NvdW50KSB7Ci0JCWRldl9lcnIoJnZzb2NfZGV2 LmRldi0+ZGV2LAotCQkJImRlc2NyaWJlX3JlZ2lvbjogaW52YWxpZCByZWdpb24gJWRcbiIsIGlt aW5vcihpbm9kZSkpOwotCQlyZXR1cm4gLUVOT0RFVjsKLQl9Ci0JcmV0dXJuIDA7Ci19Ci0KLWlu bGluZSBpbnQgdnNvY192YWxpZGF0ZV9maWxlcChzdHJ1Y3QgZmlsZSAqZmlscCkKLXsKLQlpbnQg cmV0ID0gdnNvY192YWxpZGF0ZV9pbm9kZShmaWxlX2lub2RlKGZpbHApKTsKLQotCWlmIChyZXQp Ci0JCXJldHVybiByZXQ7Ci0JaWYgKCFmaWxwLT5wcml2YXRlX2RhdGEpIHsKLQkJZGV2X2Vycigm dnNvY19kZXYuZGV2LT5kZXYsCi0JCQkiTm8gcHJpdmF0ZSBkYXRhIG9uIGZkLCByZWdpb24gJWRc biIsCi0JCQlpbWlub3IoZmlsZV9pbm9kZShmaWxwKSkpOwotCQlyZXR1cm4gLUVCQURGRDsKLQl9 Ci0JcmV0dXJuIDA7Ci19Ci0KLS8qIENvbnZlcnRzIGZyb20gc2hhcmVkIG1lbW9yeSBvZmZzZXQg dG8gdmlydHVhbCBhZGRyZXNzICovCi1zdGF0aWMgaW5saW5lIHZvaWQgKnNobV9vZmZfdG9fdmly dHVhbF9hZGRyKF9fdTMyIG9mZnNldCkKLXsKLQlyZXR1cm4gKHZvaWQgX19mb3JjZSAqKXZzb2Nf ZGV2Lmtlcm5lbF9tYXBwZWRfc2htICsgb2Zmc2V0OwotfQotCi0vKiBDb252ZXJ0cyBmcm9tIHNo YXJlZCBtZW1vcnkgb2Zmc2V0IHRvIHBoeXNpY2FsIGFkZHJlc3MgKi8KLXN0YXRpYyBpbmxpbmUg cGh5c19hZGRyX3Qgc2htX29mZl90b19waHlzX2FkZHIoX191MzIgb2Zmc2V0KQotewotCXJldHVy biB2c29jX2Rldi5zaG1fcGh5c19zdGFydCArIG9mZnNldDsKLX0KLQotLyoqCi0gKiBDb252ZW5p ZW5jZSBmdW5jdGlvbnMgdG8gb2J0YWluIHRoZSByZWdpb24gZnJvbSB0aGUgaW5vZGUgb3IgZmls ZS4KLSAqIERhbmdlcm91cyB0byBjYWxsIGJlZm9yZSB2YWxpZGF0aW5nIHRoZSBpbm9kZS9maWxl LgotICovCi1zdGF0aWMKLWlubGluZSBzdHJ1Y3QgdnNvY19kZXZpY2VfcmVnaW9uICp2c29jX3Jl Z2lvbl9mcm9tX2lub2RlKHN0cnVjdCBpbm9kZSAqaW5vZGUpCi17Ci0JcmV0dXJuICZ2c29jX2Rl di5yZWdpb25zW2ltaW5vcihpbm9kZSldOwotfQotCi1zdGF0aWMKLWlubGluZSBzdHJ1Y3QgdnNv Y19kZXZpY2VfcmVnaW9uICp2c29jX3JlZ2lvbl9mcm9tX2ZpbGVwKHN0cnVjdCBmaWxlICppbm9k ZSkKLXsKLQlyZXR1cm4gdnNvY19yZWdpb25fZnJvbV9pbm9kZShmaWxlX2lub2RlKGlub2RlKSk7 Ci19Ci0KLXN0YXRpYyBpbmxpbmUgdWludDMyX3QgdnNvY19kZXZpY2VfcmVnaW9uX3NpemUoc3Ry dWN0IHZzb2NfZGV2aWNlX3JlZ2lvbiAqcikKLXsKLQlyZXR1cm4gci0+cmVnaW9uX2VuZF9vZmZz ZXQgLSByLT5yZWdpb25fYmVnaW5fb2Zmc2V0OwotfQotCi1zdGF0aWMgY29uc3Qgc3RydWN0IGZp bGVfb3BlcmF0aW9ucyB2c29jX29wcyA9IHsKLQkub3duZXIgPSBUSElTX01PRFVMRSwKLQkub3Bl biA9IHZzb2Nfb3BlbiwKLQkubW1hcCA9IHZzb2NfbW1hcCwKLQkucmVhZCA9IHZzb2NfcmVhZCwK LQkudW5sb2NrZWRfaW9jdGwgPSB2c29jX2lvY3RsLAotCS5jb21wYXRfaW9jdGwgPSB2c29jX2lv Y3RsLAotCS53cml0ZSA9IHZzb2Nfd3JpdGUsCi0JLmxsc2VlayA9IHZzb2NfbHNlZWssCi0JLnJl bGVhc2UgPSB2c29jX3JlbGVhc2UsCi19OwotCi1zdGF0aWMgc3RydWN0IHBjaV9kZXZpY2VfaWQg dnNvY19pZF90YWJsZVtdID0gewotCXsweDFhZjQsIDB4MTExMCwgUENJX0FOWV9JRCwgUENJX0FO WV9JRCwgMCwgMCwgMH0sCi0JezB9LAotfTsKLQotTU9EVUxFX0RFVklDRV9UQUJMRShwY2ksIHZz b2NfaWRfdGFibGUpOwotCi1zdGF0aWMgdm9pZCB2c29jX3JlbW92ZV9kZXZpY2Uoc3RydWN0IHBj aV9kZXYgKnBkZXYpOwotc3RhdGljIGludCB2c29jX3Byb2JlX2RldmljZShzdHJ1Y3QgcGNpX2Rl diAqcGRldiwKLQkJCSAgICAgY29uc3Qgc3RydWN0IHBjaV9kZXZpY2VfaWQgKmVudCk7Ci0KLXN0 YXRpYyBzdHJ1Y3QgcGNpX2RyaXZlciB2c29jX3BjaV9kcml2ZXIgPSB7Ci0JLm5hbWUgPSAidnNv YyIsCi0JLmlkX3RhYmxlID0gdnNvY19pZF90YWJsZSwKLQkucHJvYmUgPSB2c29jX3Byb2JlX2Rl dmljZSwKLQkucmVtb3ZlID0gdnNvY19yZW1vdmVfZGV2aWNlLAotfTsKLQotc3RhdGljIGludAot ZG9fY3JlYXRlX2ZkX3Njb3BlZF9wZXJtaXNzaW9uKHN0cnVjdCB2c29jX2RldmljZV9yZWdpb24g KnJlZ2lvbl9wLAotCQkJICAgICAgIHN0cnVjdCBmZF9zY29wZWRfcGVybWlzc2lvbl9ub2RlICpu cCwKLQkJCSAgICAgICBzdHJ1Y3QgZmRfc2NvcGVkX3Blcm1pc3Npb25fYXJnIF9fdXNlciAqYXJn KQotewotCXN0cnVjdCBmaWxlICptYW5hZ2VkX2ZpbHA7Ci0JczMyIG1hbmFnZWRfZmQ7Ci0JYXRv bWljX3QgKm93bmVyX3B0ciA9IE5VTEw7Ci0Jc3RydWN0IHZzb2NfZGV2aWNlX3JlZ2lvbiAqbWFu YWdlZF9yZWdpb25fcDsKLQotCWlmIChjb3B5X2Zyb21fdXNlcigmbnAtPnBlcm1pc3Npb24sCi0J CQkgICAmYXJnLT5wZXJtLCBzaXplb2YobnAtPnBlcm1pc3Npb24pKSB8fAotCSAgICBjb3B5X2Zy b21fdXNlcigmbWFuYWdlZF9mZCwKLQkJCSAgICZhcmctPm1hbmFnZWRfcmVnaW9uX2ZkLCBzaXpl b2YobWFuYWdlZF9mZCkpKSB7Ci0JCXJldHVybiAtRUZBVUxUOwotCX0KLQltYW5hZ2VkX2ZpbHAg PSBmZGdldChtYW5hZ2VkX2ZkKS5maWxlOwotCS8qIENoZWNrIHRoYXQgaXQncyBhIHZhbGlkIGZk LCAqLwotCWlmICghbWFuYWdlZF9maWxwIHx8IHZzb2NfdmFsaWRhdGVfZmlsZXAobWFuYWdlZF9m aWxwKSkKLQkJcmV0dXJuIC1FUEVSTTsKLQkvKiBFRVhJU1QgaWYgdGhlIGdpdmVuIGZkIGFscmVh ZHkgaGFzIGEgcGVybWlzc2lvbi4gKi8KLQlpZiAoKChzdHJ1Y3QgdnNvY19wcml2YXRlX2RhdGEg KiltYW5hZ2VkX2ZpbHAtPnByaXZhdGVfZGF0YSktPgotCSAgICBmZF9zY29wZWRfcGVybWlzc2lv bl9ub2RlKQotCQlyZXR1cm4gLUVFWElTVDsKLQltYW5hZ2VkX3JlZ2lvbl9wID0gdnNvY19yZWdp b25fZnJvbV9maWxlcChtYW5hZ2VkX2ZpbHApOwotCS8qIENoZWNrIHRoYXQgdGhlIHByb3ZpZGVk IHJlZ2lvbiBpcyBtYW5hZ2VkIGJ5IHRoaXMgb25lICovCi0JaWYgKCZ2c29jX2Rldi5yZWdpb25z W21hbmFnZWRfcmVnaW9uX3AtPm1hbmFnZWRfYnldICE9IHJlZ2lvbl9wKQotCQlyZXR1cm4gLUVQ RVJNOwotCS8qIFRoZSBhcmVhIG11c3QgYmUgd2VsbCBmb3JtZWQgYW5kIGhhdmUgbm9uLXplcm8g c2l6ZSAqLwotCWlmIChucC0+cGVybWlzc2lvbi5iZWdpbl9vZmZzZXQgPj0gbnAtPnBlcm1pc3Np b24uZW5kX29mZnNldCkKLQkJcmV0dXJuIC1FSU5WQUw7Ci0JLyogVGhlIGFyZWEgbXVzdCBmaXQg aW4gdGhlIG1lbW9yeSB3aW5kb3cgKi8KLQlpZiAobnAtPnBlcm1pc3Npb24uZW5kX29mZnNldCA+ Ci0JICAgIHZzb2NfZGV2aWNlX3JlZ2lvbl9zaXplKG1hbmFnZWRfcmVnaW9uX3ApKQotCQlyZXR1 cm4gLUVSQU5HRTsKLQkvKiBUaGUgYXJlYSBtdXN0IGJlIGluIHRoZSByZWdpb24gZGF0YSBzZWN0 aW9uICovCi0JaWYgKG5wLT5wZXJtaXNzaW9uLmJlZ2luX29mZnNldCA8Ci0JICAgIG1hbmFnZWRf cmVnaW9uX3AtPm9mZnNldF9vZl9yZWdpb25fZGF0YSkKLQkJcmV0dXJuIC1FUkFOR0U7Ci0JLyog VGhlIGFyZWEgbXVzdCBiZSBwYWdlIGFsaWduZWQgKi8KLQlpZiAoIVBBR0VfQUxJR05FRChucC0+ cGVybWlzc2lvbi5iZWdpbl9vZmZzZXQpIHx8Ci0JICAgICFQQUdFX0FMSUdORUQobnAtPnBlcm1p c3Npb24uZW5kX29mZnNldCkpCi0JCXJldHVybiAtRUlOVkFMOwotCS8qIE93bmVyIG9mZnNldCBt dXN0IGJlIG5hdHVyYWxseSBhbGlnbmVkIGluIHRoZSB3aW5kb3cgKi8KLQlpZiAobnAtPnBlcm1p c3Npb24ub3duZXJfb2Zmc2V0ICYKLQkgICAgKHNpemVvZihucC0+cGVybWlzc2lvbi5vd25lcl9v ZmZzZXQpIC0gMSkpCi0JCXJldHVybiAtRUlOVkFMOwotCS8qIFRoZSBvd25lciBmbGFnIG11c3Qg cmVzaWRlIGluIHRoZSBvd25lciBtZW1vcnkgKi8KLQlpZiAobnAtPnBlcm1pc3Npb24ub3duZXJf b2Zmc2V0ICsgc2l6ZW9mKG5wLT5wZXJtaXNzaW9uLm93bmVyX29mZnNldCkgPgotCSAgICB2c29j X2RldmljZV9yZWdpb25fc2l6ZShyZWdpb25fcCkpCi0JCXJldHVybiAtRVJBTkdFOwotCS8qIFRo ZSBvd25lciBmbGFnIG11c3QgcmVzaWRlIGluIHRoZSBkYXRhIHNlY3Rpb24gKi8KLQlpZiAobnAt PnBlcm1pc3Npb24ub3duZXJfb2Zmc2V0IDwgcmVnaW9uX3AtPm9mZnNldF9vZl9yZWdpb25fZGF0 YSkKLQkJcmV0dXJuIC1FSU5WQUw7Ci0JLyogVGhlIG93bmVyIHZhbHVlIG11c3QgY2hhbmdlIHRv IGNsYWltIHRoZSBtZW1vcnkgKi8KLQlpZiAobnAtPnBlcm1pc3Npb24ub3duZWRfdmFsdWUgPT0g VlNPQ19SRUdJT05fRlJFRSkKLQkJcmV0dXJuIC1FSU5WQUw7Ci0Jb3duZXJfcHRyID0KLQkgICAg KGF0b21pY190ICopc2htX29mZl90b192aXJ0dWFsX2FkZHIocmVnaW9uX3AtPnJlZ2lvbl9iZWdp bl9vZmZzZXQgKwotCQkJCQkJbnAtPnBlcm1pc3Npb24ub3duZXJfb2Zmc2V0KTsKLQkvKiBXZSd2 ZSBhbHJlYWR5IHZlcmlmaWVkIHRoYXQgdGhpcyBpcyBpbiB0aGUgc2hhcmVkIG1lbW9yeSB3aW5k b3csIHNvCi0JICogaXQgc2hvdWxkIGJlIHNhZmUgdG8gd3JpdGUgdG8gdGhpcyBhZGRyZXNzLgot CSAqLwotCWlmIChhdG9taWNfY21weGNoZyhvd25lcl9wdHIsCi0JCQkgICBWU09DX1JFR0lPTl9G UkVFLAotCQkJICAgbnAtPnBlcm1pc3Npb24ub3duZWRfdmFsdWUpICE9IFZTT0NfUkVHSU9OX0ZS RUUpIHsKLQkJcmV0dXJuIC1FQlVTWTsKLQl9Ci0JKChzdHJ1Y3QgdnNvY19wcml2YXRlX2RhdGEg KiltYW5hZ2VkX2ZpbHAtPnByaXZhdGVfZGF0YSktPgotCSAgICBmZF9zY29wZWRfcGVybWlzc2lv bl9ub2RlID0gbnA7Ci0JLyogVGhlIGZpbGUgb2Zmc2V0IG5lZWRzIHRvIGJlIGFkanVzdGVkIGlm IHRoZSBjYWxsaW5nCi0JICogcHJvY2VzcyBkaWQgYW55IHJlYWQvd3JpdGUgb3BlcmF0aW9ucyBv biB0aGUgZmQKLQkgKiBiZWZvcmUgY3JlYXRpbmcgdGhlIHBlcm1pc3Npb24uCi0JICovCi0JaWYg KG1hbmFnZWRfZmlscC0+Zl9wb3MpIHsKLQkJaWYgKG1hbmFnZWRfZmlscC0+Zl9wb3MgPiBucC0+ cGVybWlzc2lvbi5lbmRfb2Zmc2V0KSB7Ci0JCQkvKiBJZiB0aGUgb2Zmc2V0IGlzIGJleW9uZCB0 aGUgcGVybWlzc2lvbiBlbmQsIHNldCBpdAotCQkJICogdG8gdGhlIGVuZC4KLQkJCSAqLwotCQkJ bWFuYWdlZF9maWxwLT5mX3BvcyA9IG5wLT5wZXJtaXNzaW9uLmVuZF9vZmZzZXQ7Ci0JCX0gZWxz ZSB7Ci0JCQkvKiBJZiB0aGUgb2Zmc2V0IGlzIHdpdGhpbiB0aGUgcGVybWlzc2lvbiBpbnRlcnZh bAotCQkJICoga2VlcCBpdCB0aGVyZSBvdGhlcndpc2UgcmVzZXQgaXQgdG8gemVyby4KLQkJCSAq LwotCQkJaWYgKG1hbmFnZWRfZmlscC0+Zl9wb3MgPCBucC0+cGVybWlzc2lvbi5iZWdpbl9vZmZz ZXQpIHsKLQkJCQltYW5hZ2VkX2ZpbHAtPmZfcG9zID0gMDsKLQkJCX0gZWxzZSB7Ci0JCQkJbWFu YWdlZF9maWxwLT5mX3BvcyAtPQotCQkJCSAgICBucC0+cGVybWlzc2lvbi5iZWdpbl9vZmZzZXQ7 Ci0JCQl9Ci0JCX0KLQl9Ci0JcmV0dXJuIDA7Ci19Ci0KLXN0YXRpYyB2b2lkCi1kb19kZXN0cm95 X2ZkX3Njb3BlZF9wZXJtaXNzaW9uX25vZGUoc3RydWN0IHZzb2NfZGV2aWNlX3JlZ2lvbiAqb3du ZXJfcmVnaW9uX3AsCi0JCQkJICAgICBzdHJ1Y3QgZmRfc2NvcGVkX3Blcm1pc3Npb25fbm9kZSAq bm9kZSkKLXsKLQlpZiAobm9kZSkgewotCQlkb19kZXN0cm95X2ZkX3Njb3BlZF9wZXJtaXNzaW9u KG93bmVyX3JlZ2lvbl9wLAotCQkJCQkJJm5vZGUtPnBlcm1pc3Npb24pOwotCQltdXRleF9sb2Nr KCZ2c29jX2Rldi5tdHgpOwotCQlsaXN0X2RlbCgmbm9kZS0+bGlzdCk7Ci0JCW11dGV4X3VubG9j aygmdnNvY19kZXYubXR4KTsKLQkJa2ZyZWUobm9kZSk7Ci0JfQotfQotCi1zdGF0aWMgdm9pZAot ZG9fZGVzdHJveV9mZF9zY29wZWRfcGVybWlzc2lvbihzdHJ1Y3QgdnNvY19kZXZpY2VfcmVnaW9u ICpvd25lcl9yZWdpb25fcCwKLQkJCQlzdHJ1Y3QgZmRfc2NvcGVkX3Blcm1pc3Npb24gKnBlcm0p Ci17Ci0JYXRvbWljX3QgKm93bmVyX3B0ciA9IE5VTEw7Ci0JaW50IHByZXYgPSAwOwotCi0JaWYg KCFwZXJtKQotCQlyZXR1cm47Ci0Jb3duZXJfcHRyID0gKGF0b21pY190ICopc2htX29mZl90b192 aXJ0dWFsX2FkZHIKLQkJKG93bmVyX3JlZ2lvbl9wLT5yZWdpb25fYmVnaW5fb2Zmc2V0ICsgcGVy bS0+b3duZXJfb2Zmc2V0KTsKLQlwcmV2ID0gYXRvbWljX3hjaGcob3duZXJfcHRyLCBWU09DX1JF R0lPTl9GUkVFKTsKLQlpZiAocHJldiAhPSBwZXJtLT5vd25lZF92YWx1ZSkKLQkJZGV2X2Vycigm dnNvY19kZXYuZGV2LT5kZXYsCi0JCQkiJXgtJXg6IG93bmVyICglcykgJXg6IGV4cGVjdGVkIHRv IGJlICV4IHdhcyAleCIsCi0JCQlwZXJtLT5iZWdpbl9vZmZzZXQsIHBlcm0tPmVuZF9vZmZzZXQs Ci0JCQlvd25lcl9yZWdpb25fcC0+ZGV2aWNlX25hbWUsIHBlcm0tPm93bmVyX29mZnNldCwKLQkJ CXBlcm0tPm93bmVkX3ZhbHVlLCBwcmV2KTsKLX0KLQotc3RhdGljIGxvbmcgZG9fdnNvY19kZXNj cmliZV9yZWdpb24oc3RydWN0IGZpbGUgKmZpbHAsCi0JCQkJICAgIHN0cnVjdCB2c29jX2Rldmlj ZV9yZWdpb24gX191c2VyICpkZXN0KQotewotCXN0cnVjdCB2c29jX2RldmljZV9yZWdpb24gKnJl Z2lvbl9wOwotCWludCByZXR2YWwgPSB2c29jX3ZhbGlkYXRlX2ZpbGVwKGZpbHApOwotCi0JaWYg KHJldHZhbCkKLQkJcmV0dXJuIHJldHZhbDsKLQlyZWdpb25fcCA9IHZzb2NfcmVnaW9uX2Zyb21f ZmlsZXAoZmlscCk7Ci0JaWYgKGNvcHlfdG9fdXNlcihkZXN0LCByZWdpb25fcCwgc2l6ZW9mKCpy ZWdpb25fcCkpKQotCQlyZXR1cm4gLUVGQVVMVDsKLQlyZXR1cm4gMDsKLX0KLQotLyoqCi0gKiBJ bXBsZW1lbnRzIHRoZSBpbm5lciBsb2dpYyBvZiBjb25kX3dhaXQuIENvcGllcyB0byBhbmQgZnJv bSB1c2Vyc3BhY2UgYXJlCi0gKiBkb25lIGluIHRoZSBoZWxwZXIgZnVuY3Rpb24gYmVsb3cuCi0g Ki8KLXN0YXRpYyBpbnQgaGFuZGxlX3Zzb2NfY29uZF93YWl0KHN0cnVjdCBmaWxlICpmaWxwLCBz dHJ1Y3QgdnNvY19jb25kX3dhaXQgKmFyZykKLXsKLQlERUZJTkVfV0FJVCh3YWl0KTsKLQl1MzIg cmVnaW9uX251bWJlciA9IGltaW5vcihmaWxlX2lub2RlKGZpbHApKTsKLQlzdHJ1Y3QgdnNvY19y ZWdpb25fZGF0YSAqZGF0YSA9IHZzb2NfZGV2LnJlZ2lvbnNfZGF0YSArIHJlZ2lvbl9udW1iZXI7 Ci0Jc3RydWN0IGhydGltZXJfc2xlZXBlciB0aW1lb3V0LCAqdG8gPSBOVUxMOwotCWludCByZXQg PSAwOwotCXN0cnVjdCB2c29jX2RldmljZV9yZWdpb24gKnJlZ2lvbl9wID0gdnNvY19yZWdpb25f ZnJvbV9maWxlcChmaWxwKTsKLQlhdG9taWNfdCAqYWRkcmVzcyA9IE5VTEw7Ci0Ja3RpbWVfdCB3 YWtlX3RpbWU7Ci0KLQkvKiBFbnN1cmUgdGhhdCB0aGUgb2Zmc2V0IGlzIGFsaWduZWQgKi8KLQlp ZiAoYXJnLT5vZmZzZXQgJiAoc2l6ZW9mKHVpbnQzMl90KSAtIDEpKQotCQlyZXR1cm4gLUVBRERS Tk9UQVZBSUw7Ci0JLyogRW5zdXJlIHRoYXQgdGhlIG9mZnNldCBpcyB3aXRoaW4gc2hhcmVkIG1l bW9yeSAqLwotCWlmICgoKHVpbnQ2NF90KWFyZy0+b2Zmc2V0KSArIHJlZ2lvbl9wLT5yZWdpb25f YmVnaW5fb2Zmc2V0ICsKLQkgICAgc2l6ZW9mKHVpbnQzMl90KSA+IHJlZ2lvbl9wLT5yZWdpb25f ZW5kX29mZnNldCkKLQkJcmV0dXJuIC1FMkJJRzsKLQlhZGRyZXNzID0gc2htX29mZl90b192aXJ0 dWFsX2FkZHIocmVnaW9uX3AtPnJlZ2lvbl9iZWdpbl9vZmZzZXQgKwotCQkJCQkgIGFyZy0+b2Zm c2V0KTsKLQotCS8qIEVuc3VyZSB0aGF0IHRoZSB0eXBlIG9mIHdhaXQgaXMgdmFsaWQgKi8KLQlz d2l0Y2ggKGFyZy0+d2FpdF90eXBlKSB7Ci0JY2FzZSBWU09DX1dBSVRfSUZfRVFVQUw6Ci0JCWJy ZWFrOwotCWNhc2UgVlNPQ19XQUlUX0lGX0VRVUFMX1RJTUVPVVQ6Ci0JCXRvID0gJnRpbWVvdXQ7 Ci0JCWJyZWFrOwotCWRlZmF1bHQ6Ci0JCXJldHVybiAtRUlOVkFMOwotCX0KLQotCWlmICh0bykg ewotCQkvKiBDb3B5IHRoZSB1c2VyLXN1cHBsaWVkIHRpbWVzZWMgaW50byB0aGUga2VybmVsIHN0 cnVjdHVyZS4KLQkJICogV2UgZG8gdGhpbmdzIHRoaXMgd2F5IHRvIGZsYXR0ZW4gZGlmZmVyZW5j ZXMgYmV0d2VlbiAzMiBiaXQKLQkJICogYW5kIDY0IGJpdCB0aW1lc3BlY3MuCi0JCSAqLwotCQlp ZiAoYXJnLT53YWtlX3RpbWVfbnNlYyA+PSBOU0VDX1BFUl9TRUMpCi0JCQlyZXR1cm4gLUVJTlZB TDsKLQkJd2FrZV90aW1lID0ga3RpbWVfc2V0KGFyZy0+d2FrZV90aW1lX3NlYywgYXJnLT53YWtl X3RpbWVfbnNlYyk7Ci0KLQkJaHJ0aW1lcl9pbml0X3NsZWVwZXJfb25fc3RhY2sodG8sIENMT0NL X01PTk9UT05JQywKLQkJCQkJICAgICAgSFJUSU1FUl9NT0RFX0FCUyk7Ci0JCWhydGltZXJfc2V0 X2V4cGlyZXNfcmFuZ2VfbnMoJnRvLT50aW1lciwgd2FrZV90aW1lLAotCQkJCQkgICAgIGN1cnJl bnQtPnRpbWVyX3NsYWNrX25zKTsKLQl9Ci0KLQl3aGlsZSAoMSkgewotCQlwcmVwYXJlX3RvX3dh aXQoJmRhdGEtPmZ1dGV4X3dhaXRfcXVldWUsICZ3YWl0LAotCQkJCVRBU0tfSU5URVJSVVBUSUJM RSk7Ci0JCS8qCi0JCSAqIENoZWNrIHRoZSBzZW50aW5lbCB2YWx1ZSBhZnRlciBwcmVwYXJlX3Rv X3dhaXQuIElmIHRoZSB2YWx1ZQotCQkgKiBjaGFuZ2VzIGFmdGVyIHRoaXMgY2hlY2sgdGhlIHdy aXRlciB3aWxsIGNhbGwgc2lnbmFsLAotCQkgKiBjaGFuZ2luZyB0aGUgdGFzayBzdGF0ZSBmcm9t IElOVEVSUlVQVElCTEUgdG8gUlVOTklORy4gVGhhdAotCQkgKiB3aWxsIGVuc3VyZSB0aGF0IHNj aGVkdWxlKCkgd2lsbCBldmVudHVhbGx5IHNjaGVkdWxlIHRoaXMKLQkJICogdGFzay4KLQkJICov Ci0JCWlmIChhdG9taWNfcmVhZChhZGRyZXNzKSAhPSBhcmctPnZhbHVlKSB7Ci0JCQlyZXQgPSAw OwotCQkJYnJlYWs7Ci0JCX0KLQkJaWYgKHRvKSB7Ci0JCQlocnRpbWVyX3NsZWVwZXJfc3RhcnRf ZXhwaXJlcyh0bywgSFJUSU1FUl9NT0RFX0FCUyk7Ci0JCQlpZiAobGlrZWx5KHRvLT50YXNrKSkK LQkJCQlmcmVlemFibGVfc2NoZWR1bGUoKTsKLQkJCWhydGltZXJfY2FuY2VsKCZ0by0+dGltZXIp OwotCQkJaWYgKCF0by0+dGFzaykgewotCQkJCXJldCA9IC1FVElNRURPVVQ7Ci0JCQkJYnJlYWs7 Ci0JCQl9Ci0JCX0gZWxzZSB7Ci0JCQlmcmVlemFibGVfc2NoZWR1bGUoKTsKLQkJfQotCQkvKiBD b3VudCB0aGUgbnVtYmVyIG9mIHRpbWVzIHRoYXQgd2Ugd29rZSB1cC4gVGhpcyBpcyB1c2VmdWwK LQkJICogZm9yIHVuaXQgdGVzdGluZy4KLQkJICovCi0JCSsrYXJnLT53YWtlczsKLQkJaWYgKHNp Z25hbF9wZW5kaW5nKGN1cnJlbnQpKSB7Ci0JCQlyZXQgPSAtRUlOVFI7Ci0JCQlicmVhazsKLQkJ fQotCX0KLQlmaW5pc2hfd2FpdCgmZGF0YS0+ZnV0ZXhfd2FpdF9xdWV1ZSwgJndhaXQpOwotCWlm ICh0bykKLQkJZGVzdHJveV9ocnRpbWVyX29uX3N0YWNrKCZ0by0+dGltZXIpOwotCXJldHVybiBy ZXQ7Ci19Ci0KLS8qKgotICogSGFuZGxlcyB0aGUgZGV0YWlscyBvZiBjb3B5aW5nIGZyb20vdG8g dXNlcnNwYWNlIHRvIGVuc3VyZSB0aGF0IHRoZSBjb3BpZXMKLSAqIGhhcHBlbiBvbiBhbGwgb2Yg dGhlIHJldHVybiBwYXRocyBvZiBjb25kX3dhaXQuCi0gKi8KLXN0YXRpYyBpbnQgZG9fdnNvY19j b25kX3dhaXQoc3RydWN0IGZpbGUgKmZpbHAsCi0JCQkgICAgIHN0cnVjdCB2c29jX2NvbmRfd2Fp dCBfX3VzZXIgKnVudHJ1c3RlZF9pbikKLXsKLQlzdHJ1Y3QgdnNvY19jb25kX3dhaXQgYXJnOwot CWludCBydmFsID0gMDsKLQotCWlmIChjb3B5X2Zyb21fdXNlcigmYXJnLCB1bnRydXN0ZWRfaW4s IHNpemVvZihhcmcpKSkKLQkJcmV0dXJuIC1FRkFVTFQ7Ci0JLyogd2FrZXMgaXMgYW4gb3V0IHBh cmFtZXRlci4gSW5pdGlhbGl6ZSBpdCB0byBzb21ldGhpbmcgc2Vuc2libGUuICovCi0JYXJnLndh a2VzID0gMDsKLQlydmFsID0gaGFuZGxlX3Zzb2NfY29uZF93YWl0KGZpbHAsICZhcmcpOwotCWlm IChjb3B5X3RvX3VzZXIodW50cnVzdGVkX2luLCAmYXJnLCBzaXplb2YoYXJnKSkpCi0JCXJldHVy biAtRUZBVUxUOwotCXJldHVybiBydmFsOwotfQotCi1zdGF0aWMgaW50IGRvX3Zzb2NfY29uZF93 YWtlKHN0cnVjdCBmaWxlICpmaWxwLCB1aW50MzJfdCBvZmZzZXQpCi17Ci0Jc3RydWN0IHZzb2Nf ZGV2aWNlX3JlZ2lvbiAqcmVnaW9uX3AgPSB2c29jX3JlZ2lvbl9mcm9tX2ZpbGVwKGZpbHApOwot CXUzMiByZWdpb25fbnVtYmVyID0gaW1pbm9yKGZpbGVfaW5vZGUoZmlscCkpOwotCXN0cnVjdCB2 c29jX3JlZ2lvbl9kYXRhICpkYXRhID0gdnNvY19kZXYucmVnaW9uc19kYXRhICsgcmVnaW9uX251 bWJlcjsKLQkvKiBFbnN1cmUgdGhhdCB0aGUgb2Zmc2V0IGlzIGFsaWduZWQgKi8KLQlpZiAob2Zm c2V0ICYgKHNpemVvZih1aW50MzJfdCkgLSAxKSkKLQkJcmV0dXJuIC1FQUREUk5PVEFWQUlMOwot CS8qIEVuc3VyZSB0aGF0IHRoZSBvZmZzZXQgaXMgd2l0aGluIHNoYXJlZCBtZW1vcnkgKi8KLQlp ZiAoKCh1aW50NjRfdClvZmZzZXQpICsgcmVnaW9uX3AtPnJlZ2lvbl9iZWdpbl9vZmZzZXQgKwot CSAgICBzaXplb2YodWludDMyX3QpID4gcmVnaW9uX3AtPnJlZ2lvbl9lbmRfb2Zmc2V0KQotCQly ZXR1cm4gLUUyQklHOwotCS8qCi0JICogVE9ETyhiLzczNjY0MTgxKTogVXNlIG11bHRpcGxlIGZ1 dGV4IHdhaXQgcXVldWVzLgotCSAqIFdlIG5lZWQgdG8gd2FrZSBldmVyeSBzbGVlcGVyIHdoZW4g dGhlIGNvbmRpdGlvbiBjaGFuZ2VzLiBUeXBpY2FsbHkKLQkgKiBvbmx5IGEgc2luZ2xlIHRocmVh ZCB3aWxsIGJlIHdhaXRpbmcgb24gdGhlIGNvbmRpdGlvbiwgYnV0IHRoZXJlCi0JICogYXJlIGV4 Y2VwdGlvbnMuIFRoZSB3b3JzdCBjYXNlIGlzIGFib3V0IDEwIHRocmVhZHMuCi0JICovCi0Jd2Fr ZV91cF9pbnRlcnJ1cHRpYmxlX2FsbCgmZGF0YS0+ZnV0ZXhfd2FpdF9xdWV1ZSk7Ci0JcmV0dXJu IDA7Ci19Ci0KLXN0YXRpYyBsb25nIHZzb2NfaW9jdGwoc3RydWN0IGZpbGUgKmZpbHAsIHVuc2ln bmVkIGludCBjbWQsIHVuc2lnbmVkIGxvbmcgYXJnKQotewotCWludCBydiA9IDA7Ci0Jc3RydWN0 IHZzb2NfZGV2aWNlX3JlZ2lvbiAqcmVnaW9uX3A7Ci0JdTMyIHJlZ19udW07Ci0Jc3RydWN0IHZz b2NfcmVnaW9uX2RhdGEgKnJlZ19kYXRhOwotCWludCByZXR2YWwgPSB2c29jX3ZhbGlkYXRlX2Zp bGVwKGZpbHApOwotCi0JaWYgKHJldHZhbCkKLQkJcmV0dXJuIHJldHZhbDsKLQlyZWdpb25fcCA9 IHZzb2NfcmVnaW9uX2Zyb21fZmlsZXAoZmlscCk7Ci0JcmVnX251bSA9IGltaW5vcihmaWxlX2lu b2RlKGZpbHApKTsKLQlyZWdfZGF0YSA9IHZzb2NfZGV2LnJlZ2lvbnNfZGF0YSArIHJlZ19udW07 Ci0Jc3dpdGNoIChjbWQpIHsKLQljYXNlIFZTT0NfQ1JFQVRFX0ZEX1NDT1BFRF9QRVJNSVNTSU9O OgotCQl7Ci0JCQlzdHJ1Y3QgZmRfc2NvcGVkX3Blcm1pc3Npb25fbm9kZSAqbm9kZSA9IE5VTEw7 Ci0KLQkJCW5vZGUgPSBremFsbG9jKHNpemVvZigqbm9kZSksIEdGUF9LRVJORUwpOwotCQkJLyog V2UgY2FuJ3QgYWxsb2NhdGUgbWVtb3J5IGZvciB0aGUgcGVybWlzc2lvbiAqLwotCQkJaWYgKCFu b2RlKQotCQkJCXJldHVybiAtRU5PTUVNOwotCQkJSU5JVF9MSVNUX0hFQUQoJm5vZGUtPmxpc3Qp OwotCQkJcnYgPSBkb19jcmVhdGVfZmRfc2NvcGVkX3Blcm1pc3Npb24KLQkJCQkocmVnaW9uX3As Ci0JCQkJIG5vZGUsCi0JCQkJIChzdHJ1Y3QgZmRfc2NvcGVkX3Blcm1pc3Npb25fYXJnIF9fdXNl ciAqKWFyZyk7Ci0JCQlpZiAoIXJ2KSB7Ci0JCQkJbXV0ZXhfbG9jaygmdnNvY19kZXYubXR4KTsK LQkJCQlsaXN0X2FkZCgmbm9kZS0+bGlzdCwgJnZzb2NfZGV2LnBlcm1pc3Npb25zKTsKLQkJCQlt dXRleF91bmxvY2soJnZzb2NfZGV2Lm10eCk7Ci0JCQl9IGVsc2UgewotCQkJCWtmcmVlKG5vZGUp OwotCQkJCXJldHVybiBydjsKLQkJCX0KLQkJfQotCQlicmVhazsKLQotCWNhc2UgVlNPQ19HRVRf RkRfU0NPUEVEX1BFUk1JU1NJT046Ci0JCXsKLQkJCXN0cnVjdCBmZF9zY29wZWRfcGVybWlzc2lv bl9ub2RlICpub2RlID0KLQkJCSAgICAoKHN0cnVjdCB2c29jX3ByaXZhdGVfZGF0YSAqKWZpbHAt PnByaXZhdGVfZGF0YSktPgotCQkJICAgIGZkX3Njb3BlZF9wZXJtaXNzaW9uX25vZGU7Ci0JCQlp ZiAoIW5vZGUpCi0JCQkJcmV0dXJuIC1FTk9FTlQ7Ci0JCQlpZiAoY29weV90b191c2VyCi0JCQkg ICAgKChzdHJ1Y3QgZmRfc2NvcGVkX3Blcm1pc3Npb24gX191c2VyICopYXJnLAotCQkJICAgICAm bm9kZS0+cGVybWlzc2lvbiwgc2l6ZW9mKG5vZGUtPnBlcm1pc3Npb24pKSkKLQkJCQlyZXR1cm4g LUVGQVVMVDsKLQkJfQotCQlicmVhazsKLQotCWNhc2UgVlNPQ19NQVlCRV9TRU5EX0lOVEVSUlVQ VF9UT19IT1NUOgotCQlpZiAoIWF0b21pY194Y2hnKHJlZ19kYXRhLT5vdXRnb2luZ19zaWduYWxs ZWQsIDEpKSB7Ci0JCQl3cml0ZWwocmVnX251bSwgdnNvY19kZXYucmVncyArIERPT1JCRUxMKTsK LQkJCXJldHVybiAwOwotCQl9IGVsc2UgewotCQkJcmV0dXJuIC1FQlVTWTsKLQkJfQotCQlicmVh azsKLQotCWNhc2UgVlNPQ19TRU5EX0lOVEVSUlVQVF9UT19IT1NUOgotCQl3cml0ZWwocmVnX251 bSwgdnNvY19kZXYucmVncyArIERPT1JCRUxMKTsKLQkJcmV0dXJuIDA7Ci0JY2FzZSBWU09DX1dB SVRfRk9SX0lOQ09NSU5HX0lOVEVSUlVQVDoKLQkJd2FpdF9ldmVudF9pbnRlcnJ1cHRpYmxlCi0J CQkocmVnX2RhdGEtPmludGVycnVwdF93YWl0X3F1ZXVlLAotCQkJIChhdG9taWNfcmVhZChyZWdf ZGF0YS0+aW5jb21pbmdfc2lnbmFsbGVkKSAhPSAwKSk7Ci0JCWJyZWFrOwotCi0JY2FzZSBWU09D X0RFU0NSSUJFX1JFR0lPTjoKLQkJcmV0dXJuIGRvX3Zzb2NfZGVzY3JpYmVfcmVnaW9uCi0JCQko ZmlscCwKLQkJCSAoc3RydWN0IHZzb2NfZGV2aWNlX3JlZ2lvbiBfX3VzZXIgKilhcmcpOwotCi0J Y2FzZSBWU09DX1NFTEZfSU5URVJSVVBUOgotCQlhdG9taWNfc2V0KHJlZ19kYXRhLT5pbmNvbWlu Z19zaWduYWxsZWQsIDEpOwotCQl3YWtlX3VwX2ludGVycnVwdGlibGUoJnJlZ19kYXRhLT5pbnRl cnJ1cHRfd2FpdF9xdWV1ZSk7Ci0JCWJyZWFrOwotCi0JY2FzZSBWU09DX0NPTkRfV0FJVDoKLQkJ cmV0dXJuIGRvX3Zzb2NfY29uZF93YWl0KGZpbHAsCi0JCQkJCSAoc3RydWN0IHZzb2NfY29uZF93 YWl0IF9fdXNlciAqKWFyZyk7Ci0JY2FzZSBWU09DX0NPTkRfV0FLRToKLQkJcmV0dXJuIGRvX3Zz b2NfY29uZF93YWtlKGZpbHAsIGFyZyk7Ci0KLQlkZWZhdWx0OgotCQlyZXR1cm4gLUVJTlZBTDsK LQl9Ci0JcmV0dXJuIDA7Ci19Ci0KLXN0YXRpYyBzc2l6ZV90IHZzb2NfcmVhZChzdHJ1Y3QgZmls ZSAqZmlscCwgY2hhciBfX3VzZXIgKmJ1ZmZlciwgc2l6ZV90IGxlbiwKLQkJCSBsb2ZmX3QgKnBv ZmZzZXQpCi17Ci0JX191MzIgYXJlYV9vZmY7Ci0JY29uc3Qgdm9pZCAqYXJlYV9wOwotCXNzaXpl X3QgYXJlYV9sZW47Ci0JaW50IHJldHZhbCA9IHZzb2NfdmFsaWRhdGVfZmlsZXAoZmlscCk7Ci0K LQlpZiAocmV0dmFsKQotCQlyZXR1cm4gcmV0dmFsOwotCWFyZWFfbGVuID0gdnNvY19nZXRfYXJl YShmaWxwLCAmYXJlYV9vZmYpOwotCWFyZWFfcCA9IHNobV9vZmZfdG9fdmlydHVhbF9hZGRyKGFy ZWFfb2ZmKTsKLQlhcmVhX3AgKz0gKnBvZmZzZXQ7Ci0JYXJlYV9sZW4gLT0gKnBvZmZzZXQ7Ci0J aWYgKGFyZWFfbGVuIDw9IDApCi0JCXJldHVybiAwOwotCWlmIChhcmVhX2xlbiA8IGxlbikKLQkJ bGVuID0gYXJlYV9sZW47Ci0JaWYgKGNvcHlfdG9fdXNlcihidWZmZXIsIGFyZWFfcCwgbGVuKSkK LQkJcmV0dXJuIC1FRkFVTFQ7Ci0JKnBvZmZzZXQgKz0gbGVuOwotCXJldHVybiBsZW47Ci19Ci0K LXN0YXRpYyBsb2ZmX3QgdnNvY19sc2VlayhzdHJ1Y3QgZmlsZSAqZmlscCwgbG9mZl90IG9mZnNl dCwgaW50IG9yaWdpbikKLXsKLQlzc2l6ZV90IGFyZWFfbGVuID0gMDsKLQlpbnQgcmV0dmFsID0g dnNvY192YWxpZGF0ZV9maWxlcChmaWxwKTsKLQotCWlmIChyZXR2YWwpCi0JCXJldHVybiByZXR2 YWw7Ci0JYXJlYV9sZW4gPSB2c29jX2dldF9hcmVhKGZpbHAsIE5VTEwpOwotCXN3aXRjaCAob3Jp Z2luKSB7Ci0JY2FzZSBTRUVLX1NFVDoKLQkJYnJlYWs7Ci0KLQljYXNlIFNFRUtfQ1VSOgotCQlp ZiAob2Zmc2V0ID4gMCAmJiBvZmZzZXQgKyBmaWxwLT5mX3BvcyA8IDApCi0JCQlyZXR1cm4gLUVP VkVSRkxPVzsKLQkJb2Zmc2V0ICs9IGZpbHAtPmZfcG9zOwotCQlicmVhazsKLQotCWNhc2UgU0VF S19FTkQ6Ci0JCWlmIChvZmZzZXQgPiAwICYmIG9mZnNldCArIGFyZWFfbGVuIDwgMCkKLQkJCXJl dHVybiAtRU9WRVJGTE9XOwotCQlvZmZzZXQgKz0gYXJlYV9sZW47Ci0JCWJyZWFrOwotCi0JY2Fz ZSBTRUVLX0RBVEE6Ci0JCWlmIChvZmZzZXQgPj0gYXJlYV9sZW4pCi0JCQlyZXR1cm4gLUVJTlZB TDsKLQkJaWYgKG9mZnNldCA8IDApCi0JCQlvZmZzZXQgPSAwOwotCQlicmVhazsKLQotCWNhc2Ug U0VFS19IT0xFOgotCQkvKiBOZXh0IGhvbGUgaXMgYWx3YXlzIHRoZSBlbmQgb2YgdGhlIHJlZ2lv biwgdW5sZXNzIG9mZnNldCBpcwotCQkgKiBiZXlvbmQgdGhhdAotCQkgKi8KLQkJaWYgKG9mZnNl dCA8IGFyZWFfbGVuKQotCQkJb2Zmc2V0ID0gYXJlYV9sZW47Ci0JCWJyZWFrOwotCi0JZGVmYXVs dDoKLQkJcmV0dXJuIC1FSU5WQUw7Ci0JfQotCi0JaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ID4g YXJlYV9sZW4pCi0JCXJldHVybiAtRUlOVkFMOwotCWZpbHAtPmZfcG9zID0gb2Zmc2V0OwotCi0J cmV0dXJuIG9mZnNldDsKLX0KLQotc3RhdGljIHNzaXplX3QgdnNvY193cml0ZShzdHJ1Y3QgZmls ZSAqZmlscCwgY29uc3QgY2hhciBfX3VzZXIgKmJ1ZmZlciwKLQkJCSAgc2l6ZV90IGxlbiwgbG9m Zl90ICpwb2Zmc2V0KQotewotCV9fdTMyIGFyZWFfb2ZmOwotCXZvaWQgKmFyZWFfcDsKLQlzc2l6 ZV90IGFyZWFfbGVuOwotCWludCByZXR2YWwgPSB2c29jX3ZhbGlkYXRlX2ZpbGVwKGZpbHApOwot Ci0JaWYgKHJldHZhbCkKLQkJcmV0dXJuIHJldHZhbDsKLQlhcmVhX2xlbiA9IHZzb2NfZ2V0X2Fy ZWEoZmlscCwgJmFyZWFfb2ZmKTsKLQlhcmVhX3AgPSBzaG1fb2ZmX3RvX3ZpcnR1YWxfYWRkcihh cmVhX29mZik7Ci0JYXJlYV9wICs9ICpwb2Zmc2V0OwotCWFyZWFfbGVuIC09ICpwb2Zmc2V0Owot CWlmIChhcmVhX2xlbiA8PSAwKQotCQlyZXR1cm4gMDsKLQlpZiAoYXJlYV9sZW4gPCBsZW4pCi0J CWxlbiA9IGFyZWFfbGVuOwotCWlmIChjb3B5X2Zyb21fdXNlcihhcmVhX3AsIGJ1ZmZlciwgbGVu KSkKLQkJcmV0dXJuIC1FRkFVTFQ7Ci0JKnBvZmZzZXQgKz0gbGVuOwotCXJldHVybiBsZW47Ci19 Ci0KLXN0YXRpYyBpcnFyZXR1cm5fdCB2c29jX2ludGVycnVwdChpbnQgaXJxLCB2b2lkICpyZWdp b25fZGF0YV92KQotewotCXN0cnVjdCB2c29jX3JlZ2lvbl9kYXRhICpyZWdpb25fZGF0YSA9Ci0J ICAgIChzdHJ1Y3QgdnNvY19yZWdpb25fZGF0YSAqKXJlZ2lvbl9kYXRhX3Y7Ci0JaW50IHJlZ19u dW0gPSByZWdpb25fZGF0YSAtIHZzb2NfZGV2LnJlZ2lvbnNfZGF0YTsKLQotCWlmICh1bmxpa2Vs eSghcmVnaW9uX2RhdGEpKQotCQlyZXR1cm4gSVJRX05PTkU7Ci0KLQlpZiAodW5saWtlbHkocmVn X251bSA8IDAgfHwKLQkJICAgICByZWdfbnVtID49IHZzb2NfZGV2LmxheW91dC0+cmVnaW9uX2Nv dW50KSkgewotCQlkZXZfZXJyKCZ2c29jX2Rldi5kZXYtPmRldiwKLQkJCSJpbnZhbGlkIGlycSBA JXAgcmVnX251bT0weCUwNHhcbiIsCi0JCQlyZWdpb25fZGF0YSwgcmVnX251bSk7Ci0JCXJldHVy biBJUlFfTk9ORTsKLQl9Ci0JaWYgKHVubGlrZWx5KHZzb2NfZGV2LnJlZ2lvbnNfZGF0YSArIHJl Z19udW0gIT0gcmVnaW9uX2RhdGEpKSB7Ci0JCWRldl9lcnIoJnZzb2NfZGV2LmRldi0+ZGV2LAot CQkJImlycSBub3QgYWxpZ25lZCBAJXAgcmVnX251bT0weCUwNHhcbiIsCi0JCQlyZWdpb25fZGF0 YSwgcmVnX251bSk7Ci0JCXJldHVybiBJUlFfTk9ORTsKLQl9Ci0Jd2FrZV91cF9pbnRlcnJ1cHRp YmxlKCZyZWdpb25fZGF0YS0+aW50ZXJydXB0X3dhaXRfcXVldWUpOwotCXJldHVybiBJUlFfSEFO RExFRDsKLX0KLQotc3RhdGljIGludCB2c29jX3Byb2JlX2RldmljZShzdHJ1Y3QgcGNpX2RldiAq cGRldiwKLQkJCSAgICAgY29uc3Qgc3RydWN0IHBjaV9kZXZpY2VfaWQgKmVudCkKLXsKLQlpbnQg cmVzdWx0OwotCWludCBpOwotCXJlc291cmNlX3NpemVfdCByZWdfc2l6ZTsKLQlkZXZfdCBkZXZ0 OwotCi0JdnNvY19kZXYuZGV2ID0gcGRldjsKLQlyZXN1bHQgPSBwY2lfZW5hYmxlX2RldmljZShw ZGV2KTsKLQlpZiAocmVzdWx0KSB7Ci0JCWRldl9lcnIoJnBkZXYtPmRldiwKLQkJCSJwY2lfZW5h YmxlX2RldmljZSBmYWlsZWQgJXM6IGVycm9yICVkXG4iLAotCQkJcGNpX25hbWUocGRldiksIHJl c3VsdCk7Ci0JCXJldHVybiByZXN1bHQ7Ci0JfQotCXZzb2NfZGV2LmVuYWJsZWRfZGV2aWNlID0g dHJ1ZTsKLQlyZXN1bHQgPSBwY2lfcmVxdWVzdF9yZWdpb25zKHBkZXYsICJ2c29jIik7Ci0JaWYg KHJlc3VsdCA8IDApIHsKLQkJZGV2X2VycigmcGRldi0+ZGV2LCAicGNpX3JlcXVlc3RfcmVnaW9u cyBmYWlsZWRcbiIpOwotCQl2c29jX3JlbW92ZV9kZXZpY2UocGRldik7Ci0JCXJldHVybiAtRUJV U1k7Ci0JfQotCXZzb2NfZGV2LnJlcXVlc3RlZF9yZWdpb25zID0gdHJ1ZTsKLQkvKiBTZXQgdXAg dGhlIGNvbnRyb2wgcmVnaXN0ZXJzIGluIEJBUiAwICovCi0JcmVnX3NpemUgPSBwY2lfcmVzb3Vy Y2VfbGVuKHBkZXYsIFJFR0lTVEVSX0JBUik7Ci0JaWYgKHJlZ19zaXplID4gTUFYX1JFR0lTVEVS X0JBUl9MRU4pCi0JCXZzb2NfZGV2LnJlZ3MgPQotCQkgICAgcGNpX2lvbWFwKHBkZXYsIFJFR0lT VEVSX0JBUiwgTUFYX1JFR0lTVEVSX0JBUl9MRU4pOwotCWVsc2UKLQkJdnNvY19kZXYucmVncyA9 IHBjaV9pb21hcChwZGV2LCBSRUdJU1RFUl9CQVIsIHJlZ19zaXplKTsKLQotCWlmICghdnNvY19k ZXYucmVncykgewotCQlkZXZfZXJyKCZwZGV2LT5kZXYsCi0JCQkiY2Fubm90IG1hcCByZWdpc3Rl cnMgb2Ygc2l6ZSAlenVcbiIsCi0JCSAgICAgICAoc2l6ZV90KXJlZ19zaXplKTsKLQkJdnNvY19y ZW1vdmVfZGV2aWNlKHBkZXYpOwotCQlyZXR1cm4gLUVCVVNZOwotCX0KLQotCS8qIE1hcCB0aGUg c2hhcmVkIG1lbW9yeSBpbiBCQVIgMiAqLwotCXZzb2NfZGV2LnNobV9waHlzX3N0YXJ0ID0gcGNp X3Jlc291cmNlX3N0YXJ0KHBkZXYsIFNIQVJFRF9NRU1PUllfQkFSKTsKLQl2c29jX2Rldi5zaG1f c2l6ZSA9IHBjaV9yZXNvdXJjZV9sZW4ocGRldiwgU0hBUkVEX01FTU9SWV9CQVIpOwotCi0JZGV2 X2luZm8oJnBkZXYtPmRldiwgInNoYXJlZCBtZW1vcnkgQCBETUEgJXBhIHNpemU9MHglenhcbiIs Ci0JCSAmdnNvY19kZXYuc2htX3BoeXNfc3RhcnQsIHZzb2NfZGV2LnNobV9zaXplKTsKLQl2c29j X2Rldi5rZXJuZWxfbWFwcGVkX3NobSA9IHBjaV9pb21hcF93YyhwZGV2LCBTSEFSRURfTUVNT1JZ X0JBUiwgMCk7Ci0JaWYgKCF2c29jX2Rldi5rZXJuZWxfbWFwcGVkX3NobSkgewotCQlkZXZfZXJy KCZ2c29jX2Rldi5kZXYtPmRldiwgImNhbm5vdCBpb21hcCByZWdpb25cbiIpOwotCQl2c29jX3Jl bW92ZV9kZXZpY2UocGRldik7Ci0JCXJldHVybiAtRUJVU1k7Ci0JfQotCi0JdnNvY19kZXYubGF5 b3V0ID0gKHN0cnVjdCB2c29jX3NobV9sYXlvdXRfZGVzY3JpcHRvciBfX2ZvcmNlICopCi0JCQkJ dnNvY19kZXYua2VybmVsX21hcHBlZF9zaG07Ci0JZGV2X2luZm8oJnBkZXYtPmRldiwgIm1ham9y X3ZlcnNpb246ICVkXG4iLAotCQkgdnNvY19kZXYubGF5b3V0LT5tYWpvcl92ZXJzaW9uKTsKLQlk ZXZfaW5mbygmcGRldi0+ZGV2LCAibWlub3JfdmVyc2lvbjogJWRcbiIsCi0JCSB2c29jX2Rldi5s YXlvdXQtPm1pbm9yX3ZlcnNpb24pOwotCWRldl9pbmZvKCZwZGV2LT5kZXYsICJzaXplOiAweCV4 XG4iLCB2c29jX2Rldi5sYXlvdXQtPnNpemUpOwotCWRldl9pbmZvKCZwZGV2LT5kZXYsICJyZWdp b25zOiAlZFxuIiwgdnNvY19kZXYubGF5b3V0LT5yZWdpb25fY291bnQpOwotCWlmICh2c29jX2Rl di5sYXlvdXQtPm1ham9yX3ZlcnNpb24gIT0KLQkgICAgQ1VSUkVOVF9WU09DX0xBWU9VVF9NQUpP Ul9WRVJTSU9OKSB7Ci0JCWRldl9lcnIoJnZzb2NfZGV2LmRldi0+ZGV2LAotCQkJImRyaXZlciBz dXBwb3J0cyBvbmx5IG1ham9yX3ZlcnNpb24gJWRcbiIsCi0JCQlDVVJSRU5UX1ZTT0NfTEFZT1VU X01BSk9SX1ZFUlNJT04pOwotCQl2c29jX3JlbW92ZV9kZXZpY2UocGRldik7Ci0JCXJldHVybiAt RUJVU1k7Ci0JfQotCXJlc3VsdCA9IGFsbG9jX2NocmRldl9yZWdpb24oJmRldnQsIDAsIHZzb2Nf ZGV2LmxheW91dC0+cmVnaW9uX2NvdW50LAotCQkJCSAgICAgVlNPQ19ERVZfTkFNRSk7Ci0JaWYg KHJlc3VsdCkgewotCQlkZXZfZXJyKCZ2c29jX2Rldi5kZXYtPmRldiwgImFsbG9jX2NocmRldl9y ZWdpb24gZmFpbGVkXG4iKTsKLQkJdnNvY19yZW1vdmVfZGV2aWNlKHBkZXYpOwotCQlyZXR1cm4g LUVCVVNZOwotCX0KLQl2c29jX2Rldi5tYWpvciA9IE1BSk9SKGRldnQpOwotCWNkZXZfaW5pdCgm dnNvY19kZXYuY2RldiwgJnZzb2Nfb3BzKTsKLQl2c29jX2Rldi5jZGV2Lm93bmVyID0gVEhJU19N T0RVTEU7Ci0JcmVzdWx0ID0gY2Rldl9hZGQoJnZzb2NfZGV2LmNkZXYsIGRldnQsIHZzb2NfZGV2 LmxheW91dC0+cmVnaW9uX2NvdW50KTsKLQlpZiAocmVzdWx0KSB7Ci0JCWRldl9lcnIoJnZzb2Nf ZGV2LmRldi0+ZGV2LCAiY2Rldl9hZGQgZXJyb3JcbiIpOwotCQl2c29jX3JlbW92ZV9kZXZpY2Uo cGRldik7Ci0JCXJldHVybiAtRUJVU1k7Ci0JfQotCXZzb2NfZGV2LmNkZXZfYWRkZWQgPSB0cnVl OwotCXZzb2NfZGV2LmNsYXNzID0gY2xhc3NfY3JlYXRlKFRISVNfTU9EVUxFLCBWU09DX0RFVl9O QU1FKTsKLQlpZiAoSVNfRVJSKHZzb2NfZGV2LmNsYXNzKSkgewotCQlkZXZfZXJyKCZ2c29jX2Rl di5kZXYtPmRldiwgImNsYXNzX2NyZWF0ZSBmYWlsZWRcbiIpOwotCQl2c29jX3JlbW92ZV9kZXZp Y2UocGRldik7Ci0JCXJldHVybiBQVFJfRVJSKHZzb2NfZGV2LmNsYXNzKTsKLQl9Ci0JdnNvY19k ZXYuY2xhc3NfYWRkZWQgPSB0cnVlOwotCXZzb2NfZGV2LnJlZ2lvbnMgPSAoc3RydWN0IHZzb2Nf ZGV2aWNlX3JlZ2lvbiBfX2ZvcmNlICopCi0JCSgodm9pZCAqKXZzb2NfZGV2LmxheW91dCArCi0J CSB2c29jX2Rldi5sYXlvdXQtPnZzb2NfcmVnaW9uX2Rlc2Nfb2Zmc2V0KTsKLQl2c29jX2Rldi5t c2l4X2VudHJpZXMgPQotCQlrY2FsbG9jKHZzb2NfZGV2LmxheW91dC0+cmVnaW9uX2NvdW50LAot CQkJc2l6ZW9mKHZzb2NfZGV2Lm1zaXhfZW50cmllc1swXSksIEdGUF9LRVJORUwpOwotCWlmICgh dnNvY19kZXYubXNpeF9lbnRyaWVzKSB7Ci0JCWRldl9lcnIoJnZzb2NfZGV2LmRldi0+ZGV2LAot CQkJInVuYWJsZSB0byBhbGxvY2F0ZSBtc2l4X2VudHJpZXNcbiIpOwotCQl2c29jX3JlbW92ZV9k ZXZpY2UocGRldik7Ci0JCXJldHVybiAtRU5PU1BDOwotCX0KLQl2c29jX2Rldi5yZWdpb25zX2Rh dGEgPQotCQlrY2FsbG9jKHZzb2NfZGV2LmxheW91dC0+cmVnaW9uX2NvdW50LAotCQkJc2l6ZW9m KHZzb2NfZGV2LnJlZ2lvbnNfZGF0YVswXSksIEdGUF9LRVJORUwpOwotCWlmICghdnNvY19kZXYu cmVnaW9uc19kYXRhKSB7Ci0JCWRldl9lcnIoJnZzb2NfZGV2LmRldi0+ZGV2LAotCQkJInVuYWJs ZSB0byBhbGxvY2F0ZSByZWdpb25zJyBkYXRhXG4iKTsKLQkJdnNvY19yZW1vdmVfZGV2aWNlKHBk ZXYpOwotCQlyZXR1cm4gLUVOT1NQQzsKLQl9Ci0JZm9yIChpID0gMDsgaSA8IHZzb2NfZGV2Lmxh eW91dC0+cmVnaW9uX2NvdW50OyArK2kpCi0JCXZzb2NfZGV2Lm1zaXhfZW50cmllc1tpXS5lbnRy eSA9IGk7Ci0KLQlyZXN1bHQgPSBwY2lfZW5hYmxlX21zaXhfZXhhY3QodnNvY19kZXYuZGV2LCB2 c29jX2Rldi5tc2l4X2VudHJpZXMsCi0JCQkJICAgICAgIHZzb2NfZGV2LmxheW91dC0+cmVnaW9u X2NvdW50KTsKLQlpZiAocmVzdWx0KSB7Ci0JCWRldl9pbmZvKCZwZGV2LT5kZXYsICJwY2lfZW5h YmxlX21zaXggZmFpbGVkOiAlZFxuIiwgcmVzdWx0KTsKLQkJdnNvY19yZW1vdmVfZGV2aWNlKHBk ZXYpOwotCQlyZXR1cm4gLUVOT1NQQzsKLQl9Ci0JLyogQ2hlY2sgdGhhdCBhbGwgcmVnaW9ucyBh cmUgd2VsbCBmb3JtZWQgKi8KLQlmb3IgKGkgPSAwOyBpIDwgdnNvY19kZXYubGF5b3V0LT5yZWdp b25fY291bnQ7ICsraSkgewotCQljb25zdCBzdHJ1Y3QgdnNvY19kZXZpY2VfcmVnaW9uICpyZWdp b24gPSB2c29jX2Rldi5yZWdpb25zICsgaTsKLQotCQlpZiAoIVBBR0VfQUxJR05FRChyZWdpb24t PnJlZ2lvbl9iZWdpbl9vZmZzZXQpIHx8Ci0JCSAgICAhUEFHRV9BTElHTkVEKHJlZ2lvbi0+cmVn aW9uX2VuZF9vZmZzZXQpKSB7Ci0JCQlkZXZfZXJyKCZ2c29jX2Rldi5kZXYtPmRldiwKLQkJCQki cmVnaW9uICVkIG5vdCBhbGlnbmVkICgleDoleCkiLCBpLAotCQkJCXJlZ2lvbi0+cmVnaW9uX2Jl Z2luX29mZnNldCwKLQkJCQlyZWdpb24tPnJlZ2lvbl9lbmRfb2Zmc2V0KTsKLQkJCXZzb2NfcmVt b3ZlX2RldmljZShwZGV2KTsKLQkJCXJldHVybiAtRUZBVUxUOwotCQl9Ci0JCWlmIChyZWdpb24t PnJlZ2lvbl9iZWdpbl9vZmZzZXQgPj0gcmVnaW9uLT5yZWdpb25fZW5kX29mZnNldCB8fAotCQkg ICAgcmVnaW9uLT5yZWdpb25fZW5kX29mZnNldCA+IHZzb2NfZGV2LnNobV9zaXplKSB7Ci0JCQlk ZXZfZXJyKCZ2c29jX2Rldi5kZXYtPmRldiwKLQkJCQkicmVnaW9uICVkIG9mZnNldHMgYXJlIHdy b25nOiAleCAleCAlengiLAotCQkJCWksIHJlZ2lvbi0+cmVnaW9uX2JlZ2luX29mZnNldCwKLQkJ CQlyZWdpb24tPnJlZ2lvbl9lbmRfb2Zmc2V0LCB2c29jX2Rldi5zaG1fc2l6ZSk7Ci0JCQl2c29j X3JlbW92ZV9kZXZpY2UocGRldik7Ci0JCQlyZXR1cm4gLUVGQVVMVDsKLQkJfQotCQlpZiAocmVn aW9uLT5tYW5hZ2VkX2J5ID49IHZzb2NfZGV2LmxheW91dC0+cmVnaW9uX2NvdW50KSB7Ci0JCQlk ZXZfZXJyKCZ2c29jX2Rldi5kZXYtPmRldiwKLQkJCQkicmVnaW9uICVkIGhhcyBpbnZhbGlkIG93 bmVyOiAldSIsCi0JCQkJaSwgcmVnaW9uLT5tYW5hZ2VkX2J5KTsKLQkJCXZzb2NfcmVtb3ZlX2Rl dmljZShwZGV2KTsKLQkJCXJldHVybiAtRUZBVUxUOwotCQl9Ci0JfQotCXZzb2NfZGV2Lm1zaXhf ZW5hYmxlZCA9IHRydWU7Ci0JZm9yIChpID0gMDsgaSA8IHZzb2NfZGV2LmxheW91dC0+cmVnaW9u X2NvdW50OyArK2kpIHsKLQkJY29uc3Qgc3RydWN0IHZzb2NfZGV2aWNlX3JlZ2lvbiAqcmVnaW9u ID0gdnNvY19kZXYucmVnaW9ucyArIGk7Ci0JCXNpemVfdCBuYW1lX3N6ID0gc2l6ZW9mKHZzb2Nf ZGV2LnJlZ2lvbnNfZGF0YVtpXS5uYW1lKSAtIDE7Ci0JCWNvbnN0IHN0cnVjdCB2c29jX3NpZ25h bF90YWJsZV9sYXlvdXQgKmhfdG9fZ19zaWduYWxfdGFibGUgPQotCQkJJnJlZ2lvbi0+aG9zdF90 b19ndWVzdF9zaWduYWxfdGFibGU7Ci0JCWNvbnN0IHN0cnVjdCB2c29jX3NpZ25hbF90YWJsZV9s YXlvdXQgKmdfdG9faF9zaWduYWxfdGFibGUgPQotCQkJJnJlZ2lvbi0+Z3Vlc3RfdG9faG9zdF9z aWduYWxfdGFibGU7Ci0KLQkJdnNvY19kZXYucmVnaW9uc19kYXRhW2ldLm5hbWVbbmFtZV9zel0g PSAnXDAnOwotCQltZW1jcHkodnNvY19kZXYucmVnaW9uc19kYXRhW2ldLm5hbWUsIHJlZ2lvbi0+ ZGV2aWNlX25hbWUsCi0JCSAgICAgICBuYW1lX3N6KTsKLQkJZGV2X2luZm8oJnBkZXYtPmRldiwg InJlZ2lvbiAlZCBuYW1lPSVzXG4iLAotCQkJIGksIHZzb2NfZGV2LnJlZ2lvbnNfZGF0YVtpXS5u YW1lKTsKLQkJaW5pdF93YWl0cXVldWVfaGVhZAotCQkJKCZ2c29jX2Rldi5yZWdpb25zX2RhdGFb aV0uaW50ZXJydXB0X3dhaXRfcXVldWUpOwotCQlpbml0X3dhaXRxdWV1ZV9oZWFkKCZ2c29jX2Rl di5yZWdpb25zX2RhdGFbaV0uZnV0ZXhfd2FpdF9xdWV1ZSk7Ci0JCXZzb2NfZGV2LnJlZ2lvbnNf ZGF0YVtpXS5pbmNvbWluZ19zaWduYWxsZWQgPQotCQkJc2htX29mZl90b192aXJ0dWFsX2FkZHIo cmVnaW9uLT5yZWdpb25fYmVnaW5fb2Zmc2V0KSArCi0JCQloX3RvX2dfc2lnbmFsX3RhYmxlLT5p bnRlcnJ1cHRfc2lnbmFsbGVkX29mZnNldDsKLQkJdnNvY19kZXYucmVnaW9uc19kYXRhW2ldLm91 dGdvaW5nX3NpZ25hbGxlZCA9Ci0JCQlzaG1fb2ZmX3RvX3ZpcnR1YWxfYWRkcihyZWdpb24tPnJl Z2lvbl9iZWdpbl9vZmZzZXQpICsKLQkJCWdfdG9faF9zaWduYWxfdGFibGUtPmludGVycnVwdF9z aWduYWxsZWRfb2Zmc2V0OwotCQlyZXN1bHQgPSByZXF1ZXN0X2lycSh2c29jX2Rldi5tc2l4X2Vu dHJpZXNbaV0udmVjdG9yLAotCQkJCSAgICAgdnNvY19pbnRlcnJ1cHQsIDAsCi0JCQkJICAgICB2 c29jX2Rldi5yZWdpb25zX2RhdGFbaV0ubmFtZSwKLQkJCQkgICAgIHZzb2NfZGV2LnJlZ2lvbnNf ZGF0YSArIGkpOwotCQlpZiAocmVzdWx0KSB7Ci0JCQlkZXZfaW5mbygmcGRldi0+ZGV2LAotCQkJ CSAicmVxdWVzdF9pcnEgZmFpbGVkIGlycT0lZCB2ZWN0b3I9JWRcbiIsCi0JCQkJaSwgdnNvY19k ZXYubXNpeF9lbnRyaWVzW2ldLnZlY3Rvcik7Ci0JCQl2c29jX3JlbW92ZV9kZXZpY2UocGRldik7 Ci0JCQlyZXR1cm4gLUVOT1NQQzsKLQkJfQotCQl2c29jX2Rldi5yZWdpb25zX2RhdGFbaV0uaXJx X3JlcXVlc3RlZCA9IHRydWU7Ci0JCWlmICghZGV2aWNlX2NyZWF0ZSh2c29jX2Rldi5jbGFzcywg TlVMTCwKLQkJCQkgICBNS0RFVih2c29jX2Rldi5tYWpvciwgaSksCi0JCQkJICAgTlVMTCwgdnNv Y19kZXYucmVnaW9uc19kYXRhW2ldLm5hbWUpKSB7Ci0JCQlkZXZfZXJyKCZ2c29jX2Rldi5kZXYt PmRldiwgImRldmljZV9jcmVhdGUgZmFpbGVkXG4iKTsKLQkJCXZzb2NfcmVtb3ZlX2RldmljZShw ZGV2KTsKLQkJCXJldHVybiAtRUJVU1k7Ci0JCX0KLQkJdnNvY19kZXYucmVnaW9uc19kYXRhW2ld LmRldmljZV9jcmVhdGVkID0gdHJ1ZTsKLQl9Ci0JcmV0dXJuIDA7Ci19Ci0KLS8qCi0gKiBUaGlz IHNob3VsZCB1bmRvIGFsbCBvZiB0aGUgYWxsb2NhdGlvbnMgaW4gdGhlIHByb2JlIGZ1bmN0aW9u IGluIHJldmVyc2UKLSAqIG9yZGVyLgotICoKLSAqIE5vdGVzOgotICoKLSAqICAgVGhlIGRldmlj ZSBtYXkgaGF2ZSBiZWVuIHBhcnRpYWxseSBpbml0aWFsaXplZCwgc28gZG91YmxlIGNoZWNrCi0g KiAgIHRoYXQgdGhlIGFsbG9jYXRpb25zIGhhcHBlbmVkLgotICoKLSAqICAgVGhpcyBmdW5jdGlv biBtYXkgYmUgY2FsbGVkIG11bHRpcGxlIHRpbWVzLCBzbyBtYXJrIHJlc291cmNlcyBhcyBmcmVl ZAotICogICBhcyB0aGV5IGFyZSBkZWFsbG9jYXRlZC4KLSAqLwotc3RhdGljIHZvaWQgdnNvY19y ZW1vdmVfZGV2aWNlKHN0cnVjdCBwY2lfZGV2ICpwZGV2KQotewotCWludCBpOwotCS8qCi0JICog cGRldiBpcyB0aGUgZmlyc3QgdGhpbmcgdG8gYmUgc2V0IG9uIHByb2JlIGFuZCB0aGUgbGFzdCB0 aGluZwotCSAqIHRvIGJlIGNsZWFyZWQgaGVyZS4gSWYgaXQncyBOVUxMIHRoZW4gdGhlcmUgaXMg bm8gY2xlYW51cC4KLQkgKi8KLQlpZiAoIXBkZXYgfHwgIXZzb2NfZGV2LmRldikKLQkJcmV0dXJu OwotCWRldl9pbmZvKCZwZGV2LT5kZXYsICJyZW1vdmVfZGV2aWNlXG4iKTsKLQlpZiAodnNvY19k ZXYucmVnaW9uc19kYXRhKSB7Ci0JCWZvciAoaSA9IDA7IGkgPCB2c29jX2Rldi5sYXlvdXQtPnJl Z2lvbl9jb3VudDsgKytpKSB7Ci0JCQlpZiAodnNvY19kZXYucmVnaW9uc19kYXRhW2ldLmRldmlj ZV9jcmVhdGVkKSB7Ci0JCQkJZGV2aWNlX2Rlc3Ryb3kodnNvY19kZXYuY2xhc3MsCi0JCQkJCSAg ICAgICBNS0RFVih2c29jX2Rldi5tYWpvciwgaSkpOwotCQkJCXZzb2NfZGV2LnJlZ2lvbnNfZGF0 YVtpXS5kZXZpY2VfY3JlYXRlZCA9IGZhbHNlOwotCQkJfQotCQkJaWYgKHZzb2NfZGV2LnJlZ2lv bnNfZGF0YVtpXS5pcnFfcmVxdWVzdGVkKQotCQkJCWZyZWVfaXJxKHZzb2NfZGV2Lm1zaXhfZW50 cmllc1tpXS52ZWN0b3IsIE5VTEwpOwotCQkJdnNvY19kZXYucmVnaW9uc19kYXRhW2ldLmlycV9y ZXF1ZXN0ZWQgPSBmYWxzZTsKLQkJfQotCQlrZnJlZSh2c29jX2Rldi5yZWdpb25zX2RhdGEpOwot CQl2c29jX2Rldi5yZWdpb25zX2RhdGEgPSBOVUxMOwotCX0KLQlpZiAodnNvY19kZXYubXNpeF9l bmFibGVkKSB7Ci0JCXBjaV9kaXNhYmxlX21zaXgocGRldik7Ci0JCXZzb2NfZGV2Lm1zaXhfZW5h YmxlZCA9IGZhbHNlOwotCX0KLQlrZnJlZSh2c29jX2Rldi5tc2l4X2VudHJpZXMpOwotCXZzb2Nf ZGV2Lm1zaXhfZW50cmllcyA9IE5VTEw7Ci0JdnNvY19kZXYucmVnaW9ucyA9IE5VTEw7Ci0JaWYg KHZzb2NfZGV2LmNsYXNzX2FkZGVkKSB7Ci0JCWNsYXNzX2Rlc3Ryb3kodnNvY19kZXYuY2xhc3Mp OwotCQl2c29jX2Rldi5jbGFzc19hZGRlZCA9IGZhbHNlOwotCX0KLQlpZiAodnNvY19kZXYuY2Rl dl9hZGRlZCkgewotCQljZGV2X2RlbCgmdnNvY19kZXYuY2Rldik7Ci0JCXZzb2NfZGV2LmNkZXZf YWRkZWQgPSBmYWxzZTsKLQl9Ci0JaWYgKHZzb2NfZGV2Lm1ham9yICYmIHZzb2NfZGV2LmxheW91 dCkgewotCQl1bnJlZ2lzdGVyX2NocmRldl9yZWdpb24oTUtERVYodnNvY19kZXYubWFqb3IsIDAp LAotCQkJCQkgdnNvY19kZXYubGF5b3V0LT5yZWdpb25fY291bnQpOwotCQl2c29jX2Rldi5tYWpv ciA9IDA7Ci0JfQotCXZzb2NfZGV2LmxheW91dCA9IE5VTEw7Ci0JaWYgKHZzb2NfZGV2Lmtlcm5l bF9tYXBwZWRfc2htKSB7Ci0JCXBjaV9pb3VubWFwKHBkZXYsIHZzb2NfZGV2Lmtlcm5lbF9tYXBw ZWRfc2htKTsKLQkJdnNvY19kZXYua2VybmVsX21hcHBlZF9zaG0gPSBOVUxMOwotCX0KLQlpZiAo dnNvY19kZXYucmVncykgewotCQlwY2lfaW91bm1hcChwZGV2LCB2c29jX2Rldi5yZWdzKTsKLQkJ dnNvY19kZXYucmVncyA9IE5VTEw7Ci0JfQotCWlmICh2c29jX2Rldi5yZXF1ZXN0ZWRfcmVnaW9u cykgewotCQlwY2lfcmVsZWFzZV9yZWdpb25zKHBkZXYpOwotCQl2c29jX2Rldi5yZXF1ZXN0ZWRf cmVnaW9ucyA9IGZhbHNlOwotCX0KLQlpZiAodnNvY19kZXYuZW5hYmxlZF9kZXZpY2UpIHsKLQkJ cGNpX2Rpc2FibGVfZGV2aWNlKHBkZXYpOwotCQl2c29jX2Rldi5lbmFibGVkX2RldmljZSA9IGZh bHNlOwotCX0KLQkvKiBEbyB0aGlzIGxhc3Q6IGl0IGluZGljYXRlcyB0aGF0IHRoZSBkZXZpY2Ug aXMgbm90IGluaXRpYWxpemVkLiAqLwotCXZzb2NfZGV2LmRldiA9IE5VTEw7Ci19Ci0KLXN0YXRp YyB2b2lkIF9fZXhpdCB2c29jX2NsZWFudXBfbW9kdWxlKHZvaWQpCi17Ci0JdnNvY19yZW1vdmVf ZGV2aWNlKHZzb2NfZGV2LmRldik7Ci0JcGNpX3VucmVnaXN0ZXJfZHJpdmVyKCZ2c29jX3BjaV9k cml2ZXIpOwotfQotCi1zdGF0aWMgaW50IF9faW5pdCB2c29jX2luaXRfbW9kdWxlKHZvaWQpCi17 Ci0JaW50IGVyciA9IC1FTk9NRU07Ci0KLQlJTklUX0xJU1RfSEVBRCgmdnNvY19kZXYucGVybWlz c2lvbnMpOwotCW11dGV4X2luaXQoJnZzb2NfZGV2Lm10eCk7Ci0KLQllcnIgPSBwY2lfcmVnaXN0 ZXJfZHJpdmVyKCZ2c29jX3BjaV9kcml2ZXIpOwotCWlmIChlcnIgPCAwKQotCQlyZXR1cm4gZXJy OwotCXJldHVybiAwOwotfQotCi1zdGF0aWMgaW50IHZzb2Nfb3BlbihzdHJ1Y3QgaW5vZGUgKmlu b2RlLCBzdHJ1Y3QgZmlsZSAqZmlscCkKLXsKLQkvKiBDYW4ndCB1c2UgdnNvY192YWxpZGF0ZV9m aWxlcCBiZWNhdXNlIGZpbHAgaXMgc3RpbGwgaW5jb21wbGV0ZSAqLwotCWludCByZXQgPSB2c29j X3ZhbGlkYXRlX2lub2RlKGlub2RlKTsKLQotCWlmIChyZXQpCi0JCXJldHVybiByZXQ7Ci0JZmls cC0+cHJpdmF0ZV9kYXRhID0KLQkJa3phbGxvYyhzaXplb2Yoc3RydWN0IHZzb2NfcHJpdmF0ZV9k YXRhKSwgR0ZQX0tFUk5FTCk7Ci0JaWYgKCFmaWxwLT5wcml2YXRlX2RhdGEpCi0JCXJldHVybiAt RU5PTUVNOwotCXJldHVybiAwOwotfQotCi1zdGF0aWMgaW50IHZzb2NfcmVsZWFzZShzdHJ1Y3Qg aW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlscCkKLXsKLQlzdHJ1Y3QgdnNvY19wcml2YXRl X2RhdGEgKnByaXZhdGVfZGF0YSA9IE5VTEw7Ci0Jc3RydWN0IGZkX3Njb3BlZF9wZXJtaXNzaW9u X25vZGUgKm5vZGUgPSBOVUxMOwotCXN0cnVjdCB2c29jX2RldmljZV9yZWdpb24gKm93bmVyX3Jl Z2lvbl9wID0gTlVMTDsKLQlpbnQgcmV0dmFsID0gdnNvY192YWxpZGF0ZV9maWxlcChmaWxwKTsK LQotCWlmIChyZXR2YWwpCi0JCXJldHVybiByZXR2YWw7Ci0JcHJpdmF0ZV9kYXRhID0gKHN0cnVj dCB2c29jX3ByaXZhdGVfZGF0YSAqKWZpbHAtPnByaXZhdGVfZGF0YTsKLQlpZiAoIXByaXZhdGVf ZGF0YSkKLQkJcmV0dXJuIDA7Ci0KLQlub2RlID0gcHJpdmF0ZV9kYXRhLT5mZF9zY29wZWRfcGVy bWlzc2lvbl9ub2RlOwotCWlmIChub2RlKSB7Ci0JCW93bmVyX3JlZ2lvbl9wID0gdnNvY19yZWdp b25fZnJvbV9pbm9kZShpbm9kZSk7Ci0JCWlmIChvd25lcl9yZWdpb25fcC0+bWFuYWdlZF9ieSAh PSBWU09DX1JFR0lPTl9XSE9MRSkgewotCQkJb3duZXJfcmVnaW9uX3AgPQotCQkJICAgICZ2c29j X2Rldi5yZWdpb25zW293bmVyX3JlZ2lvbl9wLT5tYW5hZ2VkX2J5XTsKLQkJfQotCQlkb19kZXN0 cm95X2ZkX3Njb3BlZF9wZXJtaXNzaW9uX25vZGUob3duZXJfcmVnaW9uX3AsIG5vZGUpOwotCQlw cml2YXRlX2RhdGEtPmZkX3Njb3BlZF9wZXJtaXNzaW9uX25vZGUgPSBOVUxMOwotCX0KLQlrZnJl ZShwcml2YXRlX2RhdGEpOwotCWZpbHAtPnByaXZhdGVfZGF0YSA9IE5VTEw7Ci0KLQlyZXR1cm4g MDsKLX0KLQotLyoKLSAqIFJldHVybnMgdGhlIGRldmljZSByZWxhdGl2ZSBvZmZzZXQgYW5kIGxl bmd0aCBvZiB0aGUgYXJlYSBzcGVjaWZpZWQgYnkgdGhlCi0gKiBmZCBzY29wZWQgcGVybWlzc2lv bi4gSWYgdGhlcmUgaXMgbm8gZmQgc2NvcGVkIHBlcm1pc3Npb24gc2V0LCBhIGRlZmF1bHQKLSAq IHBlcm1pc3Npb24gY292ZXJpbmcgdGhlIGVudGlyZSByZWdpb24gaXMgYXNzdW1lZCwgdW5sZXNz IHRoZSByZWdpb24gaXMgb3duZWQKLSAqIGJ5IGFub3RoZXIgb25lLCBpbiB3aGljaCBjYXNlIHRo ZSBkZWZhdWx0IGlzIGEgcGVybWlzc2lvbiB3aXRoIHplcm8gc2l6ZS4KLSAqLwotc3RhdGljIHNz aXplX3QgdnNvY19nZXRfYXJlYShzdHJ1Y3QgZmlsZSAqZmlscCwgX191MzIgKmFyZWFfb2Zmc2V0 KQotewotCV9fdTMyIG9mZiA9IDA7Ci0Jc3NpemVfdCBsZW5ndGggPSAwOwotCXN0cnVjdCB2c29j X2RldmljZV9yZWdpb24gKnJlZ2lvbl9wOwotCXN0cnVjdCBmZF9zY29wZWRfcGVybWlzc2lvbiAq cGVybTsKLQotCXJlZ2lvbl9wID0gdnNvY19yZWdpb25fZnJvbV9maWxlcChmaWxwKTsKLQlvZmYg PSByZWdpb25fcC0+cmVnaW9uX2JlZ2luX29mZnNldDsKLQlwZXJtID0gJigoc3RydWN0IHZzb2Nf cHJpdmF0ZV9kYXRhICopZmlscC0+cHJpdmF0ZV9kYXRhKS0+Ci0JCWZkX3Njb3BlZF9wZXJtaXNz aW9uX25vZGUtPnBlcm1pc3Npb247Ci0JaWYgKHBlcm0pIHsKLQkJb2ZmICs9IHBlcm0tPmJlZ2lu X29mZnNldDsKLQkJbGVuZ3RoID0gcGVybS0+ZW5kX29mZnNldCAtIHBlcm0tPmJlZ2luX29mZnNl dDsKLQl9IGVsc2UgaWYgKHJlZ2lvbl9wLT5tYW5hZ2VkX2J5ID09IFZTT0NfUkVHSU9OX1dIT0xF KSB7Ci0JCS8qIE5vIHBlcm1pc3Npb24gc2V0IGFuZCB0aGUgcmVnaW9ucyBpcyBub3Qgb3duZWQg YnkgYW5vdGhlciwKLQkJICogZGVmYXVsdCB0byBmdWxsIHJlZ2lvbiBhY2Nlc3MuCi0JCSAqLwot CQlsZW5ndGggPSB2c29jX2RldmljZV9yZWdpb25fc2l6ZShyZWdpb25fcCk7Ci0JfSBlbHNlIHsK LQkJLyogcmV0dXJuIHplcm8gbGVuZ3RoLCBhY2Nlc3MgaXMgZGVuaWVkLiAqLwotCQlsZW5ndGgg PSAwOwotCX0KLQlpZiAoYXJlYV9vZmZzZXQpCi0JCSphcmVhX29mZnNldCA9IG9mZjsKLQlyZXR1 cm4gbGVuZ3RoOwotfQotCi1zdGF0aWMgaW50IHZzb2NfbW1hcChzdHJ1Y3QgZmlsZSAqZmlscCwg c3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEpCi17Ci0JdW5zaWduZWQgbG9uZyBsZW4gPSB2bWEt PnZtX2VuZCAtIHZtYS0+dm1fc3RhcnQ7Ci0JX191MzIgYXJlYV9vZmY7Ci0JcGh5c19hZGRyX3Qg bWVtX29mZjsKLQlzc2l6ZV90IGFyZWFfbGVuOwotCWludCByZXR2YWwgPSB2c29jX3ZhbGlkYXRl X2ZpbGVwKGZpbHApOwotCi0JaWYgKHJldHZhbCkKLQkJcmV0dXJuIHJldHZhbDsKLQlhcmVhX2xl biA9IHZzb2NfZ2V0X2FyZWEoZmlscCwgJmFyZWFfb2ZmKTsKLQkvKiBBZGQgdGhlIHJlcXVlc3Rl ZCBvZmZzZXQgKi8KLQlhcmVhX29mZiArPSAodm1hLT52bV9wZ29mZiA8PCBQQUdFX1NISUZUKTsK LQlhcmVhX2xlbiAtPSAodm1hLT52bV9wZ29mZiA8PCBQQUdFX1NISUZUKTsKLQlpZiAoYXJlYV9s ZW4gPCBsZW4pCi0JCXJldHVybiAtRUlOVkFMOwotCXZtYS0+dm1fcGFnZV9wcm90ID0gcGdwcm90 X25vbmNhY2hlZCh2bWEtPnZtX3BhZ2VfcHJvdCk7Ci0JbWVtX29mZiA9IHNobV9vZmZfdG9fcGh5 c19hZGRyKGFyZWFfb2ZmKTsKLQlpZiAoaW9fcmVtYXBfcGZuX3JhbmdlKHZtYSwgdm1hLT52bV9z dGFydCwgbWVtX29mZiA+PiBQQUdFX1NISUZULAotCQkJICAgICAgIGxlbiwgdm1hLT52bV9wYWdl X3Byb3QpKQotCQlyZXR1cm4gLUVBR0FJTjsKLQlyZXR1cm4gMDsKLX0KLQotbW9kdWxlX2luaXQo dnNvY19pbml0X21vZHVsZSk7Ci1tb2R1bGVfZXhpdCh2c29jX2NsZWFudXBfbW9kdWxlKTsKLQot TU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwotTU9EVUxFX0FVVEhPUigiR3JlZyBIYXJ0bWFuIDxnaGFy dG1hbkBnb29nbGUuY29tPiIpOwotTU9EVUxFX0RFU0NSSVBUSU9OKCJWU29DIGludGVycHJldGF0 aW9uIG9mIFFFbXUncyBpdnNobWVtIGRldmljZSIpOwotTU9EVUxFX1ZFUlNJT04oIjEuMCIpOwot LSAKMi4yNS4wLjM0MS5nNzYwYmZiYjMwOS1nb29nCgpfX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fXwpkZXZlbCBtYWlsaW5nIGxpc3QKZGV2ZWxAbGludXhkcml2 ZXJwcm9qZWN0Lm9yZwpodHRwOi8vZHJpdmVyZGV2LmxpbnV4ZHJpdmVycHJvamVjdC5vcmcvbWFp bG1hbi9saXN0aW5mby9kcml2ZXJkZXYtZGV2ZWwK