diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt index ab0a9845..ec9ae670 100644 --- a/Documentation/kbuild/makefiles.txt +++ b/Documentation/kbuild/makefiles.txt @@ -45,7 +45,7 @@ This document describes the Linux kernel Makefiles. === 7 Kbuild syntax for exported headers --- 7.1 header-y - --- 7.2 objhdr-y + --- 7.2 genhdr-y --- 7.3 destination-y --- 7.4 generic-y @@ -1282,15 +1282,15 @@ See subsequent chapter for the syntax of the Kbuild file. Subdirectories are visited before their parent directories. - --- 7.2 objhdr-y + --- 7.2 genhdr-y - objhdr-y specifies generated files to be exported. + genhdr-y specifies generated files to be exported. Generated files are special as they need to be looked up in another directory when doing 'make O=...' builds. Example: #include/linux/Kbuild - objhdr-y += version.h + genhdr-y += version.h --- 7.3 destination-y diff --git a/Documentation/siphash.txt b/Documentation/siphash.txt new file mode 100644 index 00000000..e8e6ddbb --- /dev/null +++ b/Documentation/siphash.txt @@ -0,0 +1,100 @@ + SipHash - a short input PRF +----------------------------------------------- +Written by Jason A. Donenfeld + +SipHash is a cryptographically secure PRF -- a keyed hash function -- that +performs very well for short inputs, hence the name. It was designed by +cryptographers Daniel J. Bernstein and Jean-Philippe Aumasson. It is intended +as a replacement for some uses of: `jhash`, `md5_transform`, `sha_transform`, +and so forth. + +SipHash takes a secret key filled with randomly generated numbers and either +an input buffer or several input integers. It spits out an integer that is +indistinguishable from random. You may then use that integer as part of secure +sequence numbers, secure cookies, or mask it off for use in a hash table. + +1. Generating a key + +Keys should always be generated from a cryptographically secure source of +random numbers, either using get_random_bytes or get_random_once: + +siphash_key_t key; +get_random_bytes(&key, sizeof(key)); + +If you're not deriving your key from here, you're doing it wrong. + +2. Using the functions + +There are two variants of the function, one that takes a list of integers, and +one that takes a buffer: + +u64 siphash(const void *data, size_t len, const siphash_key_t *key); + +And: + +u64 siphash_1u64(u64, const siphash_key_t *key); +u64 siphash_2u64(u64, u64, const siphash_key_t *key); +u64 siphash_3u64(u64, u64, u64, const siphash_key_t *key); +u64 siphash_4u64(u64, u64, u64, u64, const siphash_key_t *key); +u64 siphash_1u32(u32, const siphash_key_t *key); +u64 siphash_2u32(u32, u32, const siphash_key_t *key); +u64 siphash_3u32(u32, u32, u32, const siphash_key_t *key); +u64 siphash_4u32(u32, u32, u32, u32, const siphash_key_t *key); + +If you pass the generic siphash function something of a constant length, it +will constant fold at compile-time and automatically choose one of the +optimized functions. + +3. Hashtable key function usage: + +struct some_hashtable { + DECLARE_HASHTABLE(hashtable, 8); + siphash_key_t key; +}; + +void init_hashtable(struct some_hashtable *table) +{ + get_random_bytes(&table->key, sizeof(table->key)); +} + +static inline hlist_head *some_hashtable_bucket(struct some_hashtable *table, struct interesting_input *input) +{ + return &table->hashtable[siphash(input, sizeof(*input), &table->key) & (HASH_SIZE(table->hashtable) - 1)]; +} + +You may then iterate like usual over the returned hash bucket. + +4. Security + +SipHash has a very high security margin, with its 128-bit key. So long as the +key is kept secret, it is impossible for an attacker to guess the outputs of +the function, even if being able to observe many outputs, since 2^128 outputs +is significant. + +Linux implements the "2-4" variant of SipHash. + +5. Struct-passing Pitfalls + +Often times the XuY functions will not be large enough, and instead you'll +want to pass a pre-filled struct to siphash. When doing this, it's important +to always ensure the struct has no padding holes. The easiest way to do this +is to simply arrange the members of the struct in descending order of size, +and to use offsetendof() instead of sizeof() for getting the size. For +performance reasons, if possible, it's probably a good thing to align the +struct to the right boundary. Here's an example: + +const struct { + struct in6_addr saddr; + u32 counter; + u16 dport; +} __aligned(SIPHASH_ALIGNMENT) combined = { + .saddr = *(struct in6_addr *)saddr, + .counter = counter, + .dport = dport +}; +u64 h = siphash(&combined, offsetofend(typeof(combined), dport), &secret); + +6. Resources + +Read the SipHash paper if you're interested in learning more: +https://131002.net/siphash/siphash.pdf diff --git a/MAINTAINERS b/MAINTAINERS index d7ccaf49..d02693c6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6096,6 +6096,13 @@ F: arch/arm/mach-s3c2410/mach-bast.c F: arch/arm/mach-s3c2410/bast-ide.c F: arch/arm/mach-s3c2410/bast-irq.c +SIPHASH PRF ROUTINES +M: Jason A. Donenfeld +S: Maintained +F: lib/siphash.c +F: lib/test_siphash.c +F: include/linux/siphash.h + TI DAVINCI MACHINE SUPPORT M: Sekhar Nori M: Kevin Hilman diff --git a/Makefile b/Makefile index 4ef3004c..4ac46468 100644 --- a/Makefile +++ b/Makefile @@ -359,13 +359,21 @@ CFLAGS_KERNEL =-mcpu=cortex-a15 -mtune=cortex-a15 -mfpu=neon-vfpv4 AFLAGS_KERNEL = CFLAGS_GCOV = -fprofile-arcs -ftest-coverage +# Use USERINCLUDE when you must reference the UAPI directories only. +USERINCLUDE := \ + -I$(srctree)/arch/$(hdr-arch)/include/uapi \ + -Iarch/$(hdr-arch)/include/generated/uapi \ + -I$(srctree)/include/uapi \ + -Iinclude/generated/uapi \ + -include $(srctree)/include/linux/kconfig.h # Use LINUXINCLUDE when you must reference the include/ directory. # Needed to be compatible with the O= option LINUXINCLUDE := -I$(srctree)/arch/$(hdr-arch)/include \ -Iarch/$(hdr-arch)/include/generated -Iinclude \ $(if $(KBUILD_SRC), -I$(srctree)/include) \ - -include $(srctree)/include/linux/kconfig.h + -Iinclude \ + $(USERINCLUDE) KBUILD_CPPFLAGS := -D__KERNEL__ @@ -445,9 +453,11 @@ asm-generic: # Detect when mixed targets is specified, and make a second invocation # of make so .config is not included in this case either (for *config). +version_h := include/generated/uapi/linux/version.h + no-dot-config-targets := clean mrproper distclean \ cscope gtags TAGS tags help %docs check% coccicheck \ - include/linux/version.h headers_% archheaders archscripts \ + $(version_h) headers_% archheaders archscripts \ kernelversion %src-pkg config-targets := 0 @@ -987,7 +997,7 @@ endif # prepare2 creates a makefile if using a separate output directory prepare2: prepare3 outputmakefile asm-generic -prepare1: prepare2 include/linux/version.h include/generated/utsrelease.h \ +prepare1: prepare2 $(version_h) include/generated/utsrelease.h \ include/config/auto.conf $(cmd_crmodverdir) @@ -1020,7 +1030,7 @@ define filechk_version.h echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))';) endef -include/linux/version.h: $(srctree)/Makefile FORCE +$(version_h): $(srctree)/Makefile FORCE $(call filechk,version.h) include/generated/utsrelease.h: include/config/kernel.release FORCE @@ -1065,7 +1075,7 @@ PHONY += archscripts archscripts: PHONY += __headers -__headers: include/linux/version.h scripts_basic asm-generic archheaders archscripts FORCE +__headers: $(version_h) scripts_basic asm-generic archheaders archscripts FORCE $(Q)$(MAKE) $(build)=scripts build_unifdef PHONY += headers_install_all @@ -1074,10 +1084,10 @@ headers_install_all: PHONY += headers_install headers_install: __headers - $(if $(wildcard $(srctree)/arch/$(hdr-arch)/include/asm/Kbuild),, \ - $(error Headers not exportable for the $(SRCARCH) architecture)) - $(Q)$(MAKE) $(hdr-inst)=include - $(Q)$(MAKE) $(hdr-inst)=arch/$(hdr-arch)/include/asm $(hdr-dst) + $(if $(wildcard $(srctree)/arch/$(hdr-arch)/include/uapi/asm/Kbuild),, \ + $(error Headers not exportable for the $(SRCARCH) architecture)) + $(Q)$(MAKE) $(hdr-inst)=include/uapi + $(Q)$(MAKE) $(hdr-inst)=arch/$(hdr-arch)/include/uapi/asm $(hdr-dst) PHONY += headers_check_all headers_check_all: headers_install_all @@ -1085,8 +1095,8 @@ headers_check_all: headers_install_all PHONY += headers_check headers_check: headers_install - $(Q)$(MAKE) $(hdr-inst)=include HDRCHECK=1 - $(Q)$(MAKE) $(hdr-inst)=arch/$(hdr-arch)/include/asm $(hdr-dst) HDRCHECK=1 + $(Q)$(MAKE) $(hdr-inst)=include/uapi HDRCHECK=1 + $(Q)$(MAKE) $(hdr-inst)=arch/$(hdr-arch)/include/uapi/asm $(hdr-dst) HDRCHECK=1 # --------------------------------------------------------------------------- # Modules @@ -1177,8 +1187,7 @@ CLEAN_FILES += vmlinux System.map \ # Directories & files removed with 'make mrproper' MRPROPER_DIRS += include/config usr/include include/generated \ arch/*/include/generated -MRPROPER_FILES += .config .config.old .version .old_version \ - include/linux/version.h \ +MRPROPER_FILES += .config .config.old .version .old_version $(version_h) \ Module.symvers tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS # clean - Delete most, but leave enough to build external modules diff --git a/anykernel_Ares/LICENSE b/anykernel_Ares/LICENSE new file mode 100644 index 00000000..53c8e491 --- /dev/null +++ b/anykernel_Ares/LICENSE @@ -0,0 +1,195 @@ +## AnyKernel3 (AK3), and AnyKernel2/AnyKernel 2.0 (AK2) Scripts License: + + AnyKernel (versions 2.0/2 and later) Android image modifying scripts. + Copyright (c) 2019 Chris Renshaw (osm0sis @ xda-developers), + and additional contributors per readily available commit history/credits. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted (subject to the limitations in the disclaimer + below) provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + + NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + +## Included Binary Licenses: + +magiskboot, magiskpolicy (Magisk): GPLv3+ + + Magisk, including all git submodules are free software: + you can redistribute it and/or modify it under the terms of the + GNU General Public License as published by the Free Software Foundation, + either version 3 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + Per Section 6(d), official compiled binaries from unmodified source: + https://github.com/topjohnwu/Magisk + +busybox: GPLv2 + + BusyBox is distributed under version 2 of the General Public + License. Version 2 is the only version of this license which this + version of BusyBox (or modified versions derived from this one) may + be distributed under. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Per Section 3(b), self-compiled binary from modified source: + https://git.busybox.net/busybox/ + https://github.com/osm0sis/android-busybox-ndk + (pre-patched source tree used to build available upon request) + + +## Optional Binary Licenses: + +mkbootfs, mkbootimg: Apache License 2.0 +mkmtkhdr: Apache License 2.0, implied (AOSP mkbootimg derived) +BootSignature*.jar: Apache License 2.0 + + Copyright (c) 2008 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + Source not required, however, respective sources are provided: + https://github.com/osm0sis/mkbootfs + https://github.com/osm0sis/mkbootimg + https://github.com/osm0sis/mkmtkhdr + https://android.googlesource.com/platform/system/extras/+/master + +flash_erase, nanddump, nandwrite (mtd-utils): GPLv2 +dumpimage, mkimage (U-Boot): GPLv2+ +mboot: GPLv2 (Intel mboot.py derived) + + Copyright their respective authors, (linked below). + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Per Section 3(b), self-compiled binaries from unmodified respective sources: + http://git.infradead.org/mtd-utils.git + https://gitlab.denx.de/u-boot/u-boot + https://github.com/osm0sis/mboot + +futility: BSD 3-Clause License (Chromium OS) +unpackelf, elftool: BSD 3-Clause License, implied (Sony mkelf.py derived) + + Copyright their respective authors, (linked below). + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Source not required, however, respective sources are provided: + https://github.com/osm0sis/futility + https://github.com/osm0sis/unpackelf + https://github.com/osm0sis/elftool + (https://github.com/sonyxperiadev/device-sony-lt26/tree/master/tools) + +rkcrc: BSD 2-Clause License + + Copyright (c) 2010, 2011 Fukaumi Naoki + Copyright (c) 2013 Ivo van Poorten + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Source not required, however, respective source is provided: + https://github.com/linux-rockchip/rkflashtool + + +## Additional Build Scripts for Listed Binaries (where used): + +osm0sis' Odds and Ends Thread - Knowledge Base: +https://forum.xda-developers.com/showthread.php?p=53554719 + diff --git a/anykernel_Ares/META-INF/com/google/android/update-binary b/anykernel_Ares/META-INF/com/google/android/update-binary index 7ef3acc9..097f4ae0 100755 --- a/anykernel_Ares/META-INF/com/google/android/update-binary +++ b/anykernel_Ares/META-INF/com/google/android/update-binary @@ -1,175 +1,427 @@ #!/sbin/sh -# AnyKernel2 Backend -# osm0sis @ xda-developers +# AnyKernel3 Backend (DO NOT CHANGE) +# osm0sis@xda-developers.com OUTFD=/proc/self/fd/$2; ZIPFILE="$3"; -DIR=`dirname "$ZIPFILE"`; + +ps | grep zygote | grep -v grep >/dev/null && BOOTMODE=true || BOOTMODE=false; +$BOOTMODE || ps -A 2>/dev/null | grep zygote | grep -v grep >/dev/null && BOOTMODE=true; + +$BOOTMODE && DIR=/sdcard || DIR=$(dirname "$ZIPFILE"); + +test -d /postinstall/tmp && POSTINSTALL=/postinstall; +test "$AKHOME" || AKHOME=$POSTINSTALL/tmp/anykernel; +test "$ANDROID_ROOT" || ANDROID_ROOT=/system; ui_print() { until [ ! "$1" ]; do - echo -e "ui_print $1\nui_print" > $OUTFD; + echo "ui_print $1 + ui_print" >> $OUTFD; shift; done; } -show_progress() { echo "progress $1 $2" > $OUTFD; } -file_getprop() { grep "^$2=" "$1" | cut -d= -f2; } -if [ ! "$(getprop 2>/dev/null)" ]; then - getprop() { - local propval="$(file_getprop /default.prop $1 2>/dev/null)"; - test "$propval" || local propval="$(file_getprop $root/system/build.prop $1 2>/dev/null)"; - test "$propval" && echo "$propval" || echo ""; - } -fi; -cleanup() { rm -rf /tmp/anykernel; } +ui_printfile() { + while IFS='' read -r line || $BB [[ -n "$line" ]]; do + ui_print "$line"; + done < $1; +} +show_progress() { echo "progress $1 $2" >> $OUTFD; } +file_getprop() { $BB grep "^$2=" "$1" | $BB cut -d= -f2-; } +setup_mountpoint() { + test -L $1 && $BB mv -f $1 ${1}_link; + if [ ! -d $1 ]; then + rm -f $1; + mkdir -p $1; + fi; +} +is_mounted() { $BB mount | $BB grep -q " $1 "; } +mount_apex() { + test -d /system/apex || return 1; + local apex dest loop minorx num; + setup_mountpoint /apex; + test -e /dev/block/loop1 && minorx=$($BB ls -l /dev/block/loop1 | $BB awk '{ print $6 }') || minorx=1; + num=0; + for apex in /system/apex/*; do + dest=/apex/$($BB basename $apex .apex); + test "$dest" == /apex/com.android.runtime.release && dest=/apex/com.android.runtime; + $BB mkdir -p $dest; + case $apex in + *.apex) + $BB unzip -qo $apex apex_payload.img -d /apex; + $BB mv -f /apex/apex_payload.img $dest.img; + $BB mount -t ext4 -o ro,noatime $dest.img $dest 2>/dev/null; + if [ $? != 0 ]; then + while [ $num -lt 64 ]; do + loop=/dev/block/loop$num; + ($BB mknod $loop b 7 $((num * minorx)); + $BB losetup $loop $dest.img) 2>/dev/null; + num=$((num + 1)); + $BB losetup $loop | $BB grep -q $dest.img && break; + done; + $BB mount -t ext4 -o ro,loop,noatime $loop $dest; + if [ $? != 0 ]; then + $BB losetup -d $loop 2>/dev/null; + fi; + fi; + ;; + *) $BB mount -o bind $apex $dest;; + esac; + done; + export ANDROID_RUNTIME_ROOT=/apex/com.android.runtime; + export ANDROID_TZDATA_ROOT=/apex/com.android.tzdata; + export BOOTCLASSPATH=/apex/com.android.runtime/javalib/core-oj.jar:/apex/com.android.runtime/javalib/core-libart.jar:/apex/com.android.runtime/javalib/okhttp.jar:/apex/com.android.runtime/javalib/bouncycastle.jar:/apex/com.android.runtime/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/android.test.base.jar:/system/framework/telephony-ext.jar:/apex/com.android.conscrypt/javalib/conscrypt.jar:/apex/com.android.media/javalib/updatable-media.jar; +} +umount_apex() { + test -d /apex || return 1; + local dest loop; + for dest in $($BB find /apex -type d -mindepth 1 -maxdepth 1); do + if [ -f $dest.img ]; then + loop=$($BB mount | $BB grep $dest | $BB cut -d" " -f1); + fi; + ($BB umount -l $dest; + $BB losetup -d $loop) 2>/dev/null; + done; + $BB rm -rf /apex 2>/dev/null; + unset ANDROID_RUNTIME_ROOT ANDROID_TZDATA_ROOT BOOTCLASSPATH; +} +mount_all() { + if ! is_mounted /data; then + $BB mount /data; + UMOUNT_DATA=1; + fi; + $BB mount -o ro -t auto /vendor 2>/dev/null; + setup_mountpoint $ANDROID_ROOT; + if ! is_mounted $ANDROID_ROOT; then + $BB mount -o ro -t auto $ANDROID_ROOT 2>/dev/null; + fi; + case $ANDROID_ROOT in + /system_root) setup_mountpoint /system;; + /system) + if ! is_mounted /system && ! is_mounted /system_root; then + setup_mountpoint /system_root; + $BB mount -o ro -t auto /system_root; + elif [ -f /system/system/build.prop ]; then + setup_mountpoint /system_root; + $BB mount --move /system /system_root; + fi; + if [ $? != 0 ]; then + $BB umount /system; + $BB umount -l /system 2>/dev/null; + test -e /dev/block/bootdevice/by-name/system || local slot=$(getprop ro.boot.slot_suffix 2>/dev/null); + $BB mount -o ro -t auto /dev/block/bootdevice/by-name/system$slot /system_root; + fi; + ;; + esac; + if is_mounted /system_root; then + if [ -f /system_root/build.prop ]; then + $BB mount -o bind /system_root /system; + else + $BB mount -o bind /system_root/system /system; + fi; + fi; + mount_apex; +} +umount_all() { + (umount_apex; + if [ ! -d /postinstall/tmp ]; then + $BB umount /system; + $BB umount -l /system; + if [ -e /system_root ]; then + $BB umount /system_root; + $BB umount -l /system_root; + fi; + fi; + umount /vendor; + umount -l /vendor; + if [ "$UMOUNT_DATA" ]; then + $BB umount /data; + $BB umount -l /data; + fi) 2>/dev/null; +} +setup_env() { + $BOOTMODE && return 1; + $BB mount -o bind /dev/urandom /dev/random; + umount_all; + mount_all; + OLD_LD_PATH=$LD_LIBRARY_PATH; + OLD_LD_PRE=$LD_PRELOAD; + OLD_LD_CFG=$LD_CONFIG_FILE; + unset LD_LIBRARY_PATH LD_PRELOAD LD_CONFIG_FILE; + if [ ! "$(getprop 2>/dev/null)" ]; then + getprop() { + local propdir propfile propval; + for propdir in / /system_root /system /vendor /odm /product; do + for propfile in default.prop build.prop; do + test "$propval" && break 2 || propval="$(file_getprop $propdir/$propfile $1 2>/dev/null)"; + done; + done; + test "$propval" && echo "$propval" || echo ""; + } + elif [ ! "$(getprop ro.build.type 2>/dev/null)" ]; then + getprop() { + ($(which getprop) | $BB grep "$1" | $BB cut -d[ -f3 | $BB cut -d] -f1) 2>/dev/null; + } + fi; +} +restore_env() { + $BOOTMODE && return 1; + local dir; + unset -f getprop; + test "$OLD_LD_PATH" && export LD_LIBRARY_PATH=$OLD_LD_PATH; + test "$OLD_LD_PRE" && export LD_PRELOAD=$OLD_LD_PRE; + test "$OLD_LD_CFG" && export LD_CONFIG_FILE=$OLD_LD_CFG; + umount_all; + (for dir in /apex /system /system_root; do + if [ -L "${dir}_link" ]; then + rmdir $dir; + $BB mv -f ${dir}_link $dir; + fi; + done; + $BB umount -l /dev/random) 2>/dev/null; +} debugging() { case $(basename "$ZIPFILE" .zip) in *-debugging) - ui_print " "; - ui_print "Creating debugging archive in zip directory..."; - $bb tar -czvf "$DIR/anykernel2-$(date +%Y-%m-%d_%H%M%S)-debug.tgz" /tmp/*; + ui_print " " "Creating debugging archive in $DIR..."; + test -f /tmp/recovery.log && local log=/tmp/recovery.log; + $BB tar -czf "$DIR/anykernel3-$(date +%Y-%m-%d_%H%M%S)-debug.tgz" $AKHOME $log; ;; esac; } -unmount_all() { - (umount /system; - if [ -d /system_root -a ! -f /system/build.prop ]; then - umount /system_root; - fi; - umount /system; - umount /vendor; - umount /data) 2>/dev/null; +cleanup() { + cd $(dirname $AKHOME); + rm -rf $AKHOME; } abort() { - ui_print "$*"; + ui_print "$@"; debugging; - if [ ! -f /tmp/anykernel/anykernel.sh -o "$(file_getprop /tmp/anykernel/anykernel.sh do.cleanuponabort 2>/dev/null)" == 1 ]; then + restore_env; + if [ ! -f anykernel.sh -o "$(file_getprop anykernel.sh do.cleanuponabort 2>/dev/null)" == 1 ]; then cleanup; fi; - unmount_all; exit 1; } +do_devicecheck() { + test "$(file_getprop anykernel.sh do.devicecheck)" == 1 || return 1; + local device devicename match product testname vendordevice vendorproduct; + ui_print "Checking device..."; + device=$(getprop ro.product.device 2>/dev/null); + product=$(getprop ro.build.product 2>/dev/null); + vendordevice=$(getprop ro.product.vendor.device 2>/dev/null); + vendorproduct=$(getprop ro.vendor.product.device 2>/dev/null); + for testname in $(file_getprop anykernel.sh 'device.name.*'); do + for devicename in $device $product $vendordevice $vendorproduct; do + if [ "$devicename" == "$testname" ]; then + ui_print "$testname" " "; + match=1; + break 2; + fi; + done; + done; + if [ ! "$match" ]; then + abort " " "Unsupported device. Aborting..."; + fi; +} +int2ver() { + if $BB [ "$1" -eq "$1" ] 2>/dev/null; then + echo "$1.0.0"; + elif [ ! "$(echo "$1" | $BB cut -d. -f3)" ]; then + echo "$1.0"; + else + echo "$1"; + fi; +} +do_versioncheck() { + test "$(file_getprop anykernel.sh supported.versions)" || return 1; + local android_ver hi_ver lo_ver parsed_ver supported supported_ver; + ui_print "Checking Android version..."; + supported_ver=$(file_getprop anykernel.sh supported.versions | $BB tr -d '[:space:]'); + android_ver=$(file_getprop /system/build.prop ro.build.version.release); + parsed_ver=$(int2ver $android_ver); + if echo $supported_ver | $BB grep -q '-'; then + lo_ver=$(int2ver "$(echo $supported_ver | $BB cut -d- -f1)"); + hi_ver=$(int2ver "$(echo $supported_ver | $BB cut -d- -f2)"); + if echo -e "$hi_ver\n$lo_ver\n$parsed_ver" | $BB sort -g | $BB grep -n "$parsed_ver" | $BB grep -q '^2:'; then + supported=1; + fi; + else + for ver in $(echo $supported_ver | $BB sed 's;,; ;g'); do + if [ "$(int2ver $ver)" == "$parsed_ver" ]; then + supported=1; + break; + fi; + done; + fi; + if [ "$supported" ]; then + ui_print "$android_ver" " "; + else + abort " " "Unsupported Android version. Aborting..."; + fi; +} +do_levelcheck() { + test "$(file_getprop anykernel.sh supported.patchlevels)" || return 1; + local android_lvl hi_lvl lo_lvl parsed_lvl supported_lvl; + ui_print "Checking Android security patch level..."; + supported_lvl=$(file_getprop anykernel.sh supported.patchlevels | $BB grep -oE '[0-9]{4}-[0-9]{2}|-'); + android_lvl=$(file_getprop /system/build.prop ro.build.version.security_patch); + parsed_lvl=$(echo $android_lvl | $BB grep -oE '[0-9]{4}-[0-9]{2}'); + if echo $supported_lvl | $BB grep -q '^\-'; then + lo_lvl=0000-00; + hi_lvl=$(echo $supported_lvl | $BB awk '{ print $2 }'); + elif echo $supported_lvl | $BB grep -q ' - '; then + lo_lvl=$(echo $supported_lvl | $BB awk '{ print $1 }'); + hi_lvl=$(echo $supported_lvl | $BB awk '{ print $3 }'); + elif echo $supported_lvl | $BB grep -q '\-$'; then + lo_lvl=$(echo $supported_lvl | $BB awk '{ print $1 }'); + hi_lvl=9999-99; + fi; + if echo -e "$hi_lvl\n$lo_lvl\n$parsed_lvl" | $BB sort -g | $BB grep -n "$parsed_lvl" | $BB grep -q '^2:'; then + ui_print "$android_lvl" " "; + else + abort " " "Unsupported Android security patch level. Aborting..."; + fi; +} +dump_moduleinfo() { +cat < $1; +name=AK3 Helper Module +version=$($BB awk '{ print $3 }' $AKHOME/vertmp) $($BB grep -oE '#.[0-9]' $AKHOME/vertmp) +versionCode=1 +author=AnyKernel3 +description=$KERNEL_STRING +EOF +} +dump_moduleremover() { +cat <<'EOF' > $1; +#!/system/bin/sh +MODDIR=${0%/*}; +if [ "$(cat /proc/version)" != "$(cat $MODDIR/version)" ]; then + rm -rf $MODDIR; +fi; +EOF +} +do_modules() { + test "$(file_getprop anykernel.sh do.modules)" == 1 || return 1; + local modcon moddir modtarget module umask; + if [ "$(file_getprop anykernel.sh do.systemless)" == 1 ]; then + cd $AKHOME/modules; + ui_print " " "Creating kernel helper Magisk module..."; + if [ -d /data/adb/magisk -a -f $AKHOME/split_img/.magisk ]; then + umask=$(umask); + umask 022; + moddir=/data/adb/modules/ak3-helper; + rm -rf $moddir; + mkdir -p system $moddir; + ($BB mv -f product system; + $BB mv -f vendor system) 2>/dev/null; + $BB cp -rLf * $moddir; + dump_moduleinfo $moddir/module.prop; + dump_moduleremover $moddir/post-fs-data.sh; + cp -f $AKHOME/vertmp $moddir/version; + umask $umask; + else + ui_print "Magisk installation not found. Skipped!"; + fi; + else + cd $AKHOME/modules; + ui_print " " "Pushing modules..."; + if [ ! -d /postinstall/tmp ]; then + $BB mount -o rw,remount -t auto /system; + $BB mount -o rw,remount -t auto /vendor 2>/dev/null; + fi; + for module in $(find . -name '*.ko'); do + modtarget=$POSTINSTALL$(echo $module | $BB cut -c2-); + if [ ! -e $modtarget ]; then + case $module in + */vendor/*) modcon=vendor;; + *) modcon=system;; + esac; + fi; + if is_mounted $modtarget; then + $BB mount -o rw,remount -t auto $modtarget; + fi; + mkdir -p $(dirname $modtarget); + $BB cp -rLf $module $modtarget; + $BB chown 0:0 $modtarget; + $BB chmod 644 $modtarget; + if [ "$modcon" ]; then + chcon "u:object_r:${modcon}_file:s0" $modtarget; + fi; + if is_mounted $modtarget; then + $BB mount -o ro,remount -t auto $modtarget; + fi; + done; + if [ ! -d /postinstall/tmp ]; then + $BB mount -o ro,remount -t auto /system; + $BB mount -o ro,remount -t auto /vendor 2>/dev/null; + fi; + fi; + cd $AKHOME; +} show_progress 1.34 4; ui_print " "; cleanup; -mkdir -p /tmp/anykernel/bin; -cd /tmp/anykernel; +mkdir -p $AKHOME/bin; +cd $AKHOME; unzip -o "$ZIPFILE"; -if [ $? != 0 -o -z "$(ls /tmp/anykernel/tools)" ]; then +if [ $? != 0 -o ! "$(ls tools)" ]; then abort "Unzip failed. Aborting..."; fi; -bb=/tmp/anykernel/tools/busybox; -chmod 755 $bb; -$bb chmod -R 755 /tmp/anykernel/tools /tmp/anykernel/bin; +for ARCH32 in x86 arm; do + if [ -d $AKHOME/tools/$ARCH32 ]; then + BB=$AKHOME/tools/$ARCH32/busybox; + chmod 755 $BB; + $BB >/dev/null 2>&1; + if [ $? == 0 ]; then + $BB mv -f $AKHOME/tools/$ARCH32/* $AKHOME/tools; + break; + fi; + fi; +done; +BB=$AKHOME/tools/busybox; +chmod 755 $BB; +$BB chmod -R 755 tools bin; +$BB --install -s bin; +if [ $? != 0 -o -z "$(ls bin)" ]; then + abort "Busybox setup failed. Aborting..."; +fi; -if [ -f /tmp/anykernel/banner ]; then - while IFS='' read -r line || $bb [[ -n "$line" ]]; do - ui_print "$line"; - done < /tmp/anykernel/banner; - ui_print " "; - ui_print " "; +if [ -f banner ]; then + ui_printfile banner; + ui_print " " " "; fi; -ui_print "Aries-Kernel $(cat /tmp/anykernel/ramdisk/version) for Samsung Galaxy S5"; -if [ -f /tmp/anykernel/version ]; then +KERNEL_STRING="$(file_getprop anykernel.sh kernel.string)"; +ui_print "$KERNEL_STRING"; +if [ -f version ]; then ui_print " "; - ui_print "$(cat /tmp/anykernel/version)"; + ui_printfile version; ui_print " "; fi; -ui_print " "; -ui_print "By: The~Skater~187@xda-developers.com..."; -ui_print " "; -ui_print "...(c) 187Mod "; -ui_print " "; - -unmount_all; -mount -o ro -t auto /system; -mount -o ro -t auto /vendor 2>/dev/null; -mount /data 2>/dev/null; -test -f /system/system/build.prop && root=/system; +ui_print " " "AnyKernel3 by osm0sis @ xda-developers" " " " "; -if [ "$(file_getprop /tmp/anykernel/anykernel.sh do.devicecheck)" == 1 ]; then - ui_print "Checking device..."; - device="$(getprop ro.product.device)"; - product="$(getprop ro.build.product)"; - for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15; do - testname="$(file_getprop /tmp/anykernel/anykernel.sh device.name$i)"; - test "$testname" || break; - if [ "$device" == "$testname" -o "$product" == "$testname" ]; then - ui_print "$testname"; - match=1; - break; - fi; - done; - ui_print "Device is compatible..."; - if [ "$match" != 1 ]; then - abort "Unsupported device. Aborting..."; - fi; -fi; +setup_env; -if [ -f /system/system/build.prop ]; then - umount /system; - umount /system 2>/dev/null; - mkdir /system_root 2>/dev/null; - mount -o ro -t auto /dev/block/bootdevice/by-name/system /system_root; - mount -o bind /system_root/system /system; - unset root; -fi; -savedpath="$LD_LIBRARY_PATH"; -savedpre="$LD_PRELOAD"; -unset LD_LIBRARY_PATH; -unset LD_PRELOAD; +do_devicecheck; +do_versioncheck; +do_levelcheck; ui_print "Installing..."; -for i in $($bb --list); do - $bb ln -s $bb /tmp/anykernel/bin/$i; -done; -if [ $? != 0 -o -z "$(ls /tmp/anykernel/bin)" ]; then - abort "Recovery busybox setup failed. Aborting..."; -fi; -PATH="/tmp/anykernel/bin:$PATH" $bb ash /tmp/anykernel/anykernel.sh $2; -if [ $? != "0" ]; then +CORE=$($BB grep -oE 'ak.*core.sh' anykernel.sh); +test -f tools/$CORE || $BB ln -s $AKHOME/tools/ak*-core.sh $AKHOME/tools/$CORE; +PATH="$AKHOME/bin:$PATH" home=$AKHOME $BB ash anykernel.sh $2; +if [ $? != 0 ]; then abort; fi; -if [ "$(file_getprop /tmp/anykernel/anykernel.sh do.modules)" == 1 ]; then - ui_print " "; - ui_print "Pushing modules..."; - mount -o rw,remount -t auto /system; - mount -o rw,remount -t auto /vendor 2>/dev/null; - cd /tmp/anykernel/modules; - for module in $(find . -name '*.ko'); do - if [ ! -e /$module ]; then - case $module in - */vendor/*) mod=vendor;; - *) mod=system;; - esac; - fi; - mkdir -p $(dirname /$module); - $bb cp -rLf $module /$module; - $bb chown 0:0 /$module; - $bb chmod 644 /$module; - if [ "$mod" ]; then - chcon "u:object_r:${mod}_file:s0" /$module; - fi; - done; - cd /tmp/anykernel; - mount -o ro,remount -t auto /system; - mount -o ro,remount -t auto /vendor 2>/dev/null; -fi; +do_modules; debugging; +restore_env; -if [ "$(file_getprop /tmp/anykernel/anykernel.sh do.cleanup)" == 1 ]; then +if [ "$(file_getprop anykernel.sh do.cleanup)" == 1 ]; then cleanup; fi; -test "$savedpath" && export LD_LIBRARY_PATH="$savedpath"; -test "$savedpre" && export LD_PRELOAD="$savedpre"; - -unmount_all; - -ui_print " "; -ui_print " "; -ui_print "Done!"; +ui_print " " " " "Done!"; diff --git a/anykernel_Ares/README.md b/anykernel_Ares/README.md index d98fbee7..7d90b314 100644 --- a/anykernel_Ares/README.md +++ b/anykernel_Ares/README.md @@ -1,52 +1,75 @@ ---------------------------------------------------------------------------------- -AnyKernel2 - Flashable Zip Template for Kernel Releases with Ramdisk Modifications +AnyKernel3 - Flashable Zip Template for Kernel Releases with Ramdisk Modifications ---------------------------------------------------------------------------------- ### by osm0sis @ xda-developers ### "AnyKernel is a template for an update.zip that can apply any kernel to any ROM, regardless of ramdisk." - Koush -AnyKernel2 pushes the format even further by allowing kernel developers to modify the underlying ramdisk for kernel feature support easily using a number of included command methods along with properties and variables. +AnyKernel2 pushed the format further by allowing kernel developers to modify the underlying ramdisk for kernel feature support easily using a number of included command methods along with properties and variables to customize the installation experience to their kernel. AnyKernel3 adds the power of topjohnwu's magiskboot for wider format support by default, and to automatically detect and retain Magisk root by patching the new Image.*-dtb as Magisk would. -A working script based on DirtyV Kernel for Galaxy Nexus (tuna) is included for reference. +_A script based on Galaxy Nexus (tuna) is included for reference. Everything to edit is self-contained in __anykernel.sh__._ ## // Properties / Variables ## ``` kernel.string=KernelName by YourName @ xda-developers do.devicecheck=1 do.modules=1 +do.systemless=1 do.cleanup=1 do.cleanuponabort=0 device.name1=maguro device.name2=toro device.name3=toroplus +device.name4=tuna +supported.versions=6.0 - 7.1.2 +supported.patchlevels=2019-07 - block=/dev/block/platform/omap/omap_hsmmc.0/by-name/boot; is_slot_device=0; ramdisk_compression=auto; ``` -__do.devicecheck=1__ specified requires at least device.name1 to be present. This should match ro.product.device or ro.build.product for your device. There is support for up to 5 device.name# properties. +__do.devicecheck=1__ specified requires at least device.name1 to be present. This should match ro.product.device, ro.build.product, ro.product.vendor.device or ro.vendor.product.device from the build.prop files for your device. There is support for as many device.name# properties as needed. You may remove any empty ones that aren't being used. -__do.modules=1__ will push the contents of the module directory to the same location relative to root (/) and apply 644 permissions. +__do.modules=1__ will push the .ko contents of the modules directory to the same location relative to root (/) and apply correct permissions. On A/B devices this can only be done to the active slot. -__do.cleanup=0__ will keep the zip from removing it's working directory in /tmp/anykernel - this can be useful if trying to debug in adb shell whether the patches worked correctly. +__do.systemless=1__ (with __do.modules=1__) will instead push the full contents of the modules directory to create a simple "ak3-helper" Magisk module, allowing developers to effectively replace system files, including .ko files. If the current kernel is changed then the kernel helper module automatically removes itself to prevent conflicts. -__do.cleanuponabort=0__ will keep the zip from removing it's working directory in /tmp/anykernel in case of installation abort. +__do.cleanup=0__ will keep the zip from removing its working directory in /tmp/anykernel (by default) - this can be useful if trying to debug in adb shell whether the patches worked correctly. + +__do.cleanuponabort=0__ will keep the zip from removing its working directory in /tmp/anykernel (by default) in case of installation abort. + +__supported.versions=__ will match against ro.build.version.release from the current ROM's build.prop. It can be set to a list or range. As a list of one or more entries, e.g. `7.1.2` or `8.1.0, 9` it will look for exact matches, as a range, e.g. `7.1.2 - 9` it will check to make sure the current version falls within those limits. Whitespace optional, and supplied version values should be in the same number format they are in the build.prop value for that Android version. + +__supported.patchlevels=__ will match against ro.build.version.security_patch from the current ROM's build.prop. It can be set as a closed or open-ended range of dates in the format YYYY-MM, whitespace optional, e.g. `2019-04 - 2019-06`, `2019-04 -` or `- 2019-06` where the last two examples show setting a minimum and maximum, respectively. `block=auto` instead of a direct block filepath enables detection of the device boot partition for use with broad, device non-specific zips. Also accepts specifically `boot` or `recovery`. `is_slot_device=1` enables detection of the suffix for the active boot partition on slot-based devices and will add this to the end of the supplied `block=` path. Also accepts `auto` for use with broad, device non-specific zips. -`ramdisk_compression=auto` allows automatically repacking the ramdisk with the format detected during unpack, changing `auto` to `gz`, `lzo`, `lzma`, `xz`, `bz2`, `lz4`, or `lz4-l` (for lz4 legacy) instead forces the repack as that format. +`ramdisk_compression=auto` allows automatically repacking the ramdisk with the format detected during unpack. Changing `auto` to `gz`, `lzo`, `lzma`, `xz`, `bz2`, `lz4`, or `lz4-l` (for lz4 legacy) instead forces the repack as that format, and using `cpio` or `none` will (attempt to) force the repack as uncompressed. + +`customdd=""` may be added to allow specifying additional dd parameters for devices that need to hack their kernel directly into a large partition like mmcblk0, or force use of dd for flashing. + +`slot_select=active|inactive` may be added to allow specifying the target slot. If omitted the default remains `active`. ## // Command Methods ## ``` +ui_print "" [...] +abort ["" [...]] +contains +file_getprop + +set_perm [ ...] +set_perm_recursive [ ...] + dump_boot split_boot unpack_ramdisk + backup_file restore_file -replace_string +replace_string replace_section remove_section insert_line @@ -56,36 +79,43 @@ prepend_file insert_file append_file replace_file -patch_fstab +patch_fstab block|mount|fstype|options|flags patch_cmdline patch_prop patch_ueventd + repack_ramdisk flash_boot -write_boot -reset_ak flash_dtbo +write_boot + +reset_ak [keep] +setup_ak ``` __"if search string"__ is the string it looks for to decide whether it needs to add the tweak or not, so generally something to indicate the tweak already exists. __"cmdline entry name"__ behaves somewhat like this as a match check for the name of the cmdline entry to be changed/added by the _patch_cmdline_ function, followed by the full entry to replace it. __"prop name"__ also serves as a match check in _patch_prop_ for a property in the given prop file, but is only the prop name as the prop value is specified separately. Similarly, __"line match string"__ and __"line replace string"__ are the search strings that locate where the modification needs to be made for those commands, __"begin search string"__ and __"end search string"__ are both required to select the first and last lines of the script block to be replaced for _replace_section_, and __"mount match name"__ and __"fs match type"__ are both required to narrow the _patch_fstab_ command down to the correct entry. +__"scope"__ may be specified as __"global"__ to force all instances of the string targeted by _replace_string_ to be replaced. Omitted or set to anything else and it will perform the default first-match replacement. + __"before|after"__ requires you simply specify __"before"__ or __"after"__ for the placement of the inserted line, in relation to __"line match string"__. __"block|mount|fstype|options|flags"__ requires you specify which part (listed in order) of the fstab entry you want to check and alter. _dump_boot_ and _write_boot_ are the default method of unpacking/repacking, but for more granular control, or omitting ramdisk changes entirely ("OG AK" mode), these can be separated into _split_boot; unpack_ramdisk_ and _repack_ramdisk; flash_boot_ respectively. _flash_dtbo_ can be used to flash a dtbo image. It is automatically included in _write_boot_ but can be called separately if using "OG AK" mode or creating a dtbo only zip. -Multi-partition zips can be created by removing the ramdisk and patch folders from the zip and including instead "-files" folders named for the partition (without slot suffix), e.g. boot-files + recovery-files, or kernel-files + ramdisk-files (on some Treble devices). These then contain zImage, and ramdisk, patch, etc. subfolders for each partition. To setup for the next partition, simply set `block=` and `ramdisk_compression=` for the new target partition and use the _reset_ak_ command. +Multi-partition zips can be created by removing the ramdisk and patch folders from the zip and including instead "-files" folders named for the partition (without slot suffix), e.g. boot-files + recovery-files, or kernel-files + ramdisk-files (on some Treble devices). These then contain Image.gz, and ramdisk, patch, etc. subfolders for each partition. To setup for the next partition, simply set `block=` (without slot suffix) and `ramdisk_compression=` for the new target partition and use the _reset_ak_ command. + +Similarly, multi-slot zips can be created with the normal zip layout for the active (current) slot, then resetting for the inactive slot by setting `block=` (without slot suffix) again, `slot_select=inactive` and `ramdisk_compression=` for the target slot and using the _reset_ak keep_ command, which will retain the patch and any added ramdisk files for the next slot. _backup_file_ may be used for testing to ensure ramdisk changes are made correctly, transparency for the end-user, or in a ramdisk-only "mod" zip. In the latter case _restore_file_ could also be used to create a "restore" zip to undo the changes, but should be used with caution since the underlying patched files could be changed with ROM/kernel updates. -You may also use _ui_print "\"_ to write messages back to the recovery during the modification process, and _file_getprop "\" "\"_ and _contains "\" "\"_ to simplify string testing logic you might want in your script. +You may also use _ui_print "\"_ to write messages back to the recovery during the modification process, _abort "\"_ to abort with optional message, and _file_getprop "\" "\"_ and _contains "\" "\"_ to simplify string testing logic you might want in your script. ## // Binary Inclusion ## -The AK2 repo includes my latest static ARM builds of `mkbootimg`, `unpackbootimg`,`busybox`, `xz` and `lz4` by default to keep the basic package small. Builds for other architectures and optional binaries (see below) are available from my latest AIK-mobile and FlashIt packages, respectively, here: +The AK3 repo includes current ARM builds of `magiskboot`, `magiskpolicy` and `busybox` by default to keep the basic package small. Builds for other architectures and optional binaries (see below) are available from the latest Magisk zip, or my latest AIK-mobile and FlashIt packages, respectively, here: https://forum.xda-developers.com/showthread.php?t=2073775 (Android Image Kitchen thread) https://forum.xda-developers.com/showthread.php?t=2239421 (Odds and Ends thread) @@ -93,39 +123,61 @@ https://forum.xda-developers.com/showthread.php?t=2239421 (Odds and Ends thread) Optional supported binaries which may be placed in /tools to enable built-in expanded functionality are as follows: * `mkbootfs` - for broken recoveries, or, booted flash support for a script/app via bind mount to /tmp (deprecated/use with caution) * `flash_erase`, `nanddump`, `nandwrite` - MTD block device support for devices where the `dd` command is not sufficient -* `pxa-unpackbootimg`, `pxa-mkbootimg` - Samsung/Marvell PXA1088/PXA1908 boot.img format variant support * `dumpimage`, `mkimage` - DENX U-Boot uImage format support -* `unpackelf` - Sony ELF kernel.elf format support, repacking as AOSP standard boot.img for unlocked bootloaders -* `elftool`, `unpackelf` - Sony ELF kernel.elf format support, repacking as ELF for older Sony devices -* `mkmtkhdr` - MTK device boot image section headers support +* `mboot` - Intel OSIP Android image format support +* `unpackelf`, `mkbootimg` - Sony ELF kernel.elf format support, repacking as AOSP standard boot.img for unlocked bootloaders +* `elftool` (with `unpackelf`) - Sony ELF kernel.elf format support, repacking as ELF for older Sony devices +* `mkmtkhdr` (with `unpackelf`) - MTK device boot image section headers support for Sony devices * `futility` + `chromeos` test keys directory - Google ChromeOS signature support * `BootSignature_Android.jar` + `avb` keys directory - Google Android Verified Boot (AVB) signature support -* `blobpack` - Asus SignBlob signature support -* `dhtbsign` - Samsung/Spreadtrum DHTB signature support * `rkcrc` - Rockchip KRNL ramdisk image support +Optionally moving ARM builds to tools/arm and putting x86 builds in tools/x86 will enable architecture detection for use with broad, device non-specific zips. + ## // Instructions ## -1. Place zImage in the root (dtb and/or dtbo should also go here for devices that require custom ones, each will fallback to the original if not included) +1. Place final kernel build product, e.g. Image.gz-dtb or zImage to name a couple, in the zip root (any separate dt, dtb or recovery_dtbo, and/or dtbo should also go here for devices that require custom ones, each will fallback to the original if not included) -2. Place any required ramdisk files in /ramdisk and modules in /modules (with the full path like /modules/system/lib/modules) +2. Place any required ramdisk files in /ramdisk and module files in /modules (with the full path like /modules/system/lib/modules) -3. Place any required patch files (generally partial files which go with commands) in /patch +3. Place any required patch files (generally partial files which go with AK3 file editing commands) in /patch -4. Modify the anykernel.sh to add your kernel's name, boot partition location, permissions for included ramdisk files, and use methods for any required ramdisk modifications (optionally, also place banner and/or version files in the root to have these displayed during flash) +4. Modify the anykernel.sh to add your kernel's name, boot partition location, permissions for any added ramdisk files, and use methods for any required ramdisk modifications (optionally, also place banner and/or version files in the root to have these displayed during flash) -5. `zip -r9 UPDATE-AnyKernel2.zip * -x .git README.md *placeholder` +5. `zip -r9 UPDATE-AnyKernel3.zip * -x .git README.md *placeholder` + +_The LICENSE file must remain in the final zip to comply with licenses for binary redistribution and the license of the AK3 scripts._ If supporting a recovery that forces zip signature verification (like Cyanogen Recovery) then you will need to also sign your zip using the method I describe here: http://forum.xda-developers.com/android/software-hacking/dev-complete-shell-script-flashable-zip-t2934449 -Not required, but any tweaks you can't hardcode into the source (best practice) should be added with an additional init.tweaks.rc or bootscript.sh to minimize the necessary ramdisk changes. +Not required, but any tweaks you can't hardcode into the source (best practice) should be added with an additional init.tweaks.rc or bootscript.sh to minimize the necessary ramdisk changes. On newer devices Magisk allows these within /overlay.d - see examples. + +It is also extremely important to note that for the broadest AK3 compatibility it is always better to modify a ramdisk file rather than replace it. + +___If running into trouble when flashing an AK3 zip, the suffix -debugging may be added to the zip's filename to enable creation of a debug .tgz of /tmp for later examination while booted or on desktop.___ + +## // Staying Up-To-Date ## + +Now that you've got a ready zip for your device, you might be wondering how to keep it up-to-date with the latest AnyKernel commits. AnyKernel2 and AnyKernel3 have been painstakingly developed to allow you to just drop in the latest update-binary and tools directory and have everything "just work" for beginners not overly git or script savvy, but the best practice way is as follows: + +1. Fork my AnyKernel3 repo on GitHub + +2. `git clone https://github.com//AnyKernel3` + +3. `git remote add upstream https://github.com/osm0sis/AnyKernel3` + +4. `git checkout -b ` + +5. Set it up like your zip (i.e. remove any folders you don't use like ramdisk or patch, delete README.md, and add your anykernel.sh and optionally your Image.*-dtb if you want it up there) then commit all those changes + +6. `git push --set-upstream origin ` -It is also extremely important to note that for the broadest AK2 compatibility it is always better to modify a ramdisk file rather than replace it. +7. `git checkout master` then repeat steps 4-6 for any other devices you support -If running into trouble when flashing an AK2 zip, the suffix -debugging may be added to the zip's filename to enable creation of a debug .tgz of /tmp for later examination while booted or on desktop. +Then you should be able to `git pull upstream master` from your master branch and either merge or cherry-pick the new AK3 commits into your device branches as needed. -For further support and usage examples please see the AnyKernel2 XDA thread: https://forum.xda-developers.com/showthread.php?t=2670512 +___For further support and usage examples please see the AnyKernel3 XDA thread:___ _https://forum.xda-developers.com/showthread.php?t=2670512_ -Have fun! +__Have fun!__ diff --git a/anykernel_Ares/anykernel.sh b/anykernel_Ares/anykernel.sh index 4cfe6c06..56ca344f 100755 --- a/anykernel_Ares/anykernel.sh +++ b/anykernel_Ares/anykernel.sh @@ -3,13 +3,15 @@ # # Credits: osm0sis @ xda-developers # -# Modified by The~Skater~187@xda-developers.com +# Modified by The~Skater~187 @ xda-developers +# +# Repacked to AnyKernel3 by SmgKhOaRn @ xda-developers # ## AnyKernel setup # begin properties properties() { ' -kernel.string=Ares Kernel by The~Skater~187@xda-developers.com +kernel.string=Ares Kernel by @The~Skater~187, repacked to AK3 by @SmgKhOaRn do.devicecheck=1 do.modules=0 do.cleanup=1 @@ -39,63 +41,87 @@ ramdisk_compression=auto; ## AnyKernel methods (DO NOT CHANGE) # import patching functions/variables - see for reference -. /tmp/anykernel/tools/ak2-core.sh; - +. /tmp/anykernel/tools/ak3-core.sh; ## AnyKernel file attributes # set permissions/ownership for included ramdisk files +set_perm_recursive 0 0 755 755 $ramdisk/*; +set_perm_recursive 0 0 750 750 $ramdisk/init* $ramdisk/sbin; chmod -R 750 $ramdisk/*; chown -R root:root $ramdisk/*; -chmod 775 $ramdisk/sbin -chmod 755 $ramdisk/sbin/busybox +chmod 775 $ramdisk/sbin; +chmod 755 $ramdisk/sbin/busybox; ## AnyKernel install +dump_boot; # Check Android version ui_print " "; -ui_print "Checking android version..."; -android_ver=$(file_getprop /system/build.prop "ro.build.version.release"); -ui_print " "; -ui_print "Android $android_ver detected..."; -case "$android_ver" in -8.1.0|9) support_status="supported";; + +android_sdk=$(cat /system/build.prop | grep ro.build.version.sdk | cut -d "=" -f 2) +case "$android_sdk" in +26|27|28|29) support_status="supported";; *) support_status="unsupported";; esac; -ui_print " "; -if [ ! "$support_status" == "supported" ]; then - ui_print "This version of Ares-Kernel is only compatible with android versions 8.1.0 & 9!"; - exit 1; + +if [ "$support_status" == "supported" ]; then + ui_print "Android 8.0/8.1/9.0/10 detected!"; +else + ui_print "This version of Ares-Kernel is only compatible with android versions 8 & 8.1 & 9 & 10!"; + exit 1; fi; dump_boot; # begin ramdisk changes +mount -o rw,remount /system; +mount -o rw,remount /system_root; + +# sysinit +backup_file /system/bin/sysinit; +backup_file /system/xbin/sysinit; +replace_file /system/bin/sysinit 755 aressysinit +replace_file /system/xbin/sysinit 755 aressysinit # init.rc backup_file init.rc; -grep "import /init.Ares.rc" init.rc >/dev/null || sed -i '1,/.*import.*/s/.*import.*/import \/init.Ares.rc\n&/' init.rc - -# init.qcom.rc -backup_file init.qcom.rc; -remove_line init.qcom.rc "start mpdecision"; -insert_line init.qcom.rc "u:r:supersu:s0 root root -- /init.Ares.sh" after "Post boot services" " exec u:r:supersu:s0 root root -- /init.Ares.sh" -insert_line init.qcom.rc "u:r:magisk:s0 root root -- /init.Ares.sh" after "Post boot services" " exec u:r:magisk:s0 root root -- /init.Ares.sh" -insert_line init.qcom.rc "u:r:su:s0 root root -- /init.Ares.sh" after "Post boot services" " exec u:r:su:s0 root root -- /init.Ares.sh" -insert_line init.qcom.rc "u:r:init:s0 root root -- /init.Ares.sh" after "Post boot services" " exec u:r:init:s0 root root -- /init.Ares.sh" -insert_line init.qcom.rc "u:r:supersu:s0 root root -- /init.Ares.sh" after "Post boot services" " exec u:r:supersu:s0 root root -- /init.Ares.sh" -insert_line init.qcom.rc "root root -- /init.Ares.sh" after "Post boot services" " exec u:r:supersu:s0 root root -- /init.Ares.sh" -insert_line init.qcom.rc "Execute Ares boot script..." after "Post boot services" " # Execute Ares boot script..." -replace_string init.qcom.rc "setprop sys.io.scheduler zen" "setprop sys.io.scheduler bfq" "setprop sys.io.scheduler zen"; +grep "import /init.Ares.rc" init.rc >/dev/null || sed -i '1,/.*import.*/s/.*import.*/import \/init.Ares.rc\n&/' init.rc; -# init.tuna.rc +# init_d.rc +backup_file /system/etc/init/init_d.rc; +replace_file /system/etc/init/init_d.rc 755 init_d.rc -# fstab.tuna +# init.qcom.rc +if [ -d /system_root ]; then + ui_print "Use System-On-Root..."; + cp sbin/busybox /system_root/sbin + chmod 755 /system_root/sbin/busybox + backup_file /system/vendor/etc/init/hw/init.qcom.rc; + remove_line /system/vendor/etc/init/hw/init.qcom.rc "start mpdecision"; + insert_line /system/vendor/etc/init/hw/init.qcom.rc "u:r:supersu:s0 root root -- /init.Ares.sh" after "Post boot services" " exec u:r:supersu:s0 root root -- /init.Ares.sh" + insert_line /system/vendor/etc/init/hw/init.qcom.rc "u:r:magisk:s0 root root -- /init.Ares.sh" after "Post boot services" " exec u:r:magisk:s0 root root -- /init.Ares.sh" + insert_line /system/vendor/etc/init/hw/init.qcom.rc "u:r:su:s0 root root -- /init.Ares.sh" after "Post boot services" " exec u:r:su:s0 root root -- /init.Ares.sh" + insert_line /system/vendor/etc/init/hw/init.qcom.rc "u:r:init:s0 root root -- /init.Ares.sh" after "Post boot services" " exec u:r:init:s0 root root -- /init.Ares.sh" + insert_line /system/vendor/etc/init/hw/init.qcom.rc "u:r:supersu:s0 root root -- /init.Ares.sh" after "Post boot services" " exec u:r:supersu:s0 root root -- /init.Ares.sh" + insert_line /system/vendor/etc/init/hw/init.qcom.rc "root root -- /init.Ares.sh" after "Post boot services" " exec u:r:supersu:s0 root root -- /init.Ares.sh" + insert_line /system/vendor/etc/init/hw/init.qcom.rc "Execute Ares boot script..." after "Post boot services" " # Execute Ares boot script..." + replace_string /system/vendor/etc/init/hw/init.qcom.rc "setprop sys.io.scheduler zen" "setprop sys.io.scheduler bfq" "setprop sys.io.scheduler zen"; +else + backup_file init.qcom.rc; + remove_line init.qcom.rc "start mpdecision"; + insert_line init.qcom.rc "u:r:supersu:s0 root root -- /init.Ares.sh" after "Post boot services" " exec u:r:supersu:s0 root root -- /init.Ares.sh" + insert_line init.qcom.rc "u:r:magisk:s0 root root -- /init.Ares.sh" after "Post boot services" " exec u:r:magisk:s0 root root -- /init.Ares.sh" + insert_line init.qcom.rc "u:r:su:s0 root root -- /init.Ares.sh" after "Post boot services" " exec u:r:su:s0 root root -- /init.Ares.sh" + insert_line init.qcom.rc "u:r:init:s0 root root -- /init.Ares.sh" after "Post boot services" " exec u:r:init:s0 root root -- /init.Ares.sh" + insert_line init.qcom.rc "u:r:supersu:s0 root root -- /init.Ares.sh" after "Post boot services" " exec u:r:supersu:s0 root root -- /init.Ares.sh" + insert_line init.qcom.rc "root root -- /init.Ares.sh" after "Post boot services" " exec u:r:supersu:s0 root root -- /init.Ares.sh" + insert_line init.qcom.rc "Execute Ares boot script..." after "Post boot services" " # Execute Ares boot script..." + replace_string init.qcom.rc "setprop sys.io.scheduler zen" "setprop sys.io.scheduler bfq" "setprop sys.io.scheduler zen"; +fi; # end ramdisk changes - write_boot; ## end install - diff --git a/anykernel_Ares/tools/ak2-core.sh b/anykernel_Ares/tools/ak2-core.sh deleted file mode 100755 index e8466bd3..00000000 --- a/anykernel_Ares/tools/ak2-core.sh +++ /dev/null @@ -1,614 +0,0 @@ -## AnyKernel methods (DO NOT CHANGE) -# set up extracted files and directories -ramdisk=/tmp/anykernel/ramdisk; -bin=/tmp/anykernel/tools; -split_img=/tmp/anykernel/split_img; -patch=/tmp/anykernel/patch; - -chmod -R 755 $bin; -mkdir -p $split_img; - -FD=$1; -OUTFD=/proc/self/fd/$FD; - -# ui_print -ui_print() { echo -e "ui_print $1\nui_print" > $OUTFD; } - -# contains -contains() { test "${1#*$2}" != "$1" && return 0 || return 1; } - -# file_getprop -file_getprop() { grep "^$2=" "$1" | cut -d= -f2; } - -# reset anykernel directory -reset_ak() { - local i; - rm -rf $(dirname /tmp/anykernel/*-files/current)/ramdisk; - for i in $ramdisk $split_img /tmp/anykernel/rdtmp /tmp/anykernel/boot.img /tmp/anykernel/*-new*; do - cp -af $i $(dirname /tmp/anykernel/*-files/current); - done; - rm -rf $ramdisk $split_img $patch /tmp/anykernel/rdtmp /tmp/anykernel/boot.img /tmp/anykernel/*-new* /tmp/anykernel/*-files/current; - . /tmp/anykernel/tools/ak2-core.sh $FD; -} - -# dump boot and extract ramdisk -split_boot() { - local nooktest nookoff dumpfail; - if [ ! -e "$(echo $block | cut -d\ -f1)" ]; then - ui_print " "; ui_print "Invalid partition. Aborting..."; exit 1; - fi; - if [ -f "$bin/nanddump" ]; then - $bin/nanddump -f /tmp/anykernel/boot.img $block; - else - dd if=$block of=/tmp/anykernel/boot.img; - fi; - nooktest=$(strings /tmp/anykernel/boot.img | grep -E 'Red Loader|Green Loader|Green Recovery|eMMC boot.img|eMMC recovery.img|BauwksBoot'); - if [ "$nooktest" ]; then - case $nooktest in - *BauwksBoot*) nookoff=262144;; - *) nookoff=1048576;; - esac; - mv -f /tmp/anykernel/boot.img /tmp/anykernel/boot-orig.img; - dd bs=$nookoff count=1 conv=notrunc if=/tmp/anykernel/boot-orig.img of=$split_img/boot.img-master_boot.key; - dd bs=$nookoff skip=1 conv=notrunc if=/tmp/anykernel/boot-orig.img of=/tmp/anykernel/boot.img; - fi; - if [ -f "$bin/unpackelf" -a "$($bin/unpackelf -i /tmp/anykernel/boot.img -h -q 2>/dev/null; echo $?)" == 0 ]; then - if [ -f "$bin/elftool" ]; then - mkdir $split_img/elftool_out; - $bin/elftool unpack -i /tmp/anykernel/boot.img -o $split_img/elftool_out; - cp -f $split_img/elftool_out/header $split_img/boot.img-header; - fi; - $bin/unpackelf -i /tmp/anykernel/boot.img -o $split_img; - mv -f $split_img/boot.img-ramdisk.cpio.gz $split_img/boot.img-ramdisk.gz; - elif [ -f "$bin/dumpimage" ]; then - $bin/dumpimage -l /tmp/anykernel/boot.img; - $bin/dumpimage -l /tmp/anykernel/boot.img > $split_img/boot.img-header; - grep "Name:" $split_img/boot.img-header | cut -c15- > $split_img/boot.img-name; - grep "Type:" $split_img/boot.img-header | cut -c15- | cut -d\ -f1 > $split_img/boot.img-arch; - grep "Type:" $split_img/boot.img-header | cut -c15- | cut -d\ -f2 > $split_img/boot.img-os; - grep "Type:" $split_img/boot.img-header | cut -c15- | cut -d\ -f3 | cut -d- -f1 > $split_img/boot.img-type; - grep "Type:" $split_img/boot.img-header | cut -d\( -f2 | cut -d\) -f1 | cut -d\ -f1 | cut -d- -f1 > $split_img/boot.img-comp; - grep "Address:" $split_img/boot.img-header | cut -c15- > $split_img/boot.img-addr; - grep "Point:" $split_img/boot.img-header | cut -c15- > $split_img/boot.img-ep; - $bin/dumpimage -i /tmp/anykernel/boot.img -p 0 $split_img/boot.img-zImage; - test $? != 0 && dumpfail=1; - if [ "$(cat $split_img/boot.img-type)" == "Multi" ]; then - $bin/dumpimage -i /tmp/anykernel/boot.img -p 1 $split_img/boot.img-ramdisk.gz; - fi; - test $? != 0 && dumpfail=1; - elif [ -f "$bin/rkcrc" ]; then - dd bs=4096 skip=8 iflag=skip_bytes conv=notrunc if=/tmp/anykernel/boot.img of=$split_img/boot.img-ramdisk.gz; - elif [ -f "$bin/pxa-unpackbootimg" ]; then - $bin/pxa-unpackbootimg -i /tmp/anykernel/boot.img -o $split_img; - else - $bin/unpackbootimg -i /tmp/anykernel/boot.img -o $split_img; - fi; - if [ $? != 0 -o "$dumpfail" ]; then - ui_print " "; ui_print "Dumping/splitting image failed. Aborting..."; exit 1; - fi; - if [ -f "$bin/unpackelf" -a -f "$split_img/boot.img-dtb" ]; then - case $(od -ta -An -N4 $split_img/boot.img-dtb | sed -e 's/del //' -e 's/ //g') in - QCDT|ELF) ;; - *) gzip $split_img/boot.img-zImage; - mv -f $split_img/boot.img-zImage.gz $split_img/boot.img-zImage; - cat $split_img/boot.img-dtb >> $split_img/boot.img-zImage; - rm -f $split_img/boot.img-dtb;; - esac; - fi; -} -unpack_ramdisk() { - local compext unpackcmd; - if [ -f "$bin/mkmtkhdr" ]; then - dd bs=512 skip=1 conv=notrunc if=$split_img/boot.img-ramdisk.gz of=$split_img/temprd; - mv -f $split_img/temprd $split_img/boot.img-ramdisk.gz; - fi; - mv -f $ramdisk /tmp/anykernel/rdtmp; - case $(od -ta -An -N4 $split_img/boot.img-ramdisk.gz) in - ' us vt'*|' us rs'*) compext="gz"; unpackcmd="gzip";; - ' ht L Z O') compext="lzo"; unpackcmd="lzop";; - ' ] nul nul nul') compext="lzma"; unpackcmd="$bin/xz";; - ' } 7 z X') compext="xz"; unpackcmd="$bin/xz";; - ' B Z h'*) compext="bz2"; unpackcmd="bzip2";; - ' stx ! L can') compext="lz4-l"; unpackcmd="$bin/lz4";; - ' etx ! L can'|' eot " M can') compext="lz4"; unpackcmd="$bin/lz4";; - *) ui_print " "; ui_print "Unknown ramdisk compression. Aborting..."; exit 1;; - esac; - mv -f $split_img/boot.img-ramdisk.gz $split_img/boot.img-ramdisk.cpio.$compext; - mkdir -p $ramdisk; - chmod 755 $ramdisk; - cd $ramdisk; - $unpackcmd -dc $split_img/boot.img-ramdisk.cpio.$compext | EXTRACT_UNSAFE_SYMLINKS=1 cpio -i -d; - if [ $? != 0 -o -z "$(ls $ramdisk)" ]; then - ui_print " "; ui_print "Unpacking ramdisk failed. Aborting..."; exit 1; - fi; - - if [ -f $ramdisk/version ]; then - ui_print "Updating over $(cat $ramdisk/version)..."; - ui_print " "; - else - ui_print "Installing Ares-Kernel..."; - ui_print " "; - fi - - test ! -z "$(ls /tmp/anykernel/rdtmp)" && cp -af /tmp/anykernel/rdtmp/* $ramdisk; -} -dump_boot() { - split_boot; - unpack_ramdisk; -} - -# repack ramdisk then build and write image -repack_ramdisk() { - local compext repackcmd; - case $ramdisk_compression in - auto|"") compext=`echo $split_img/*-ramdisk.cpio.* | rev | cut -d. -f1 | rev`;; - *) compext=$ramdisk_compression;; - esac; - case $compext in - gz) repackcmd="gzip";; - lzo) repackcmd="lzo";; - lzma) repackcmd="$bin/xz -Flzma";; - xz) repackcmd="$bin/xz -Ccrc32";; - bz2) repackcmd="bzip2";; - lz4-l) repackcmd="$bin/lz4 -l";; - lz4) repackcmd="$bin/lz4";; - esac; - if [ -f "$bin/mkbootfs" ]; then - $bin/mkbootfs $ramdisk | $repackcmd -9c > /tmp/anykernel/ramdisk-new.cpio.$compext; - else - cd $ramdisk; - find . | cpio -H newc -o | $repackcmd -9c > /tmp/anykernel/ramdisk-new.cpio.$compext; - fi; - if [ $? != 0 ]; then - ui_print " "; ui_print "Repacking ramdisk failed. Aborting..."; exit 1; - fi; - cd /tmp/anykernel; - if [ -f "$bin/mkmtkhdr" ]; then - $bin/mkmtkhdr --rootfs ramdisk-new.cpio.$compext; - mv -f ramdisk-new.cpio.$compext-mtk ramdisk-new.cpio.$compext; - fi; -} -flash_dtbo() { - for i in dtbo dtbo.img; do - if [ -f /tmp/anykernel/$i ]; then - dtbo=$i; - break; - fi; - done; - if [ "$dtbo" ]; then - dtbo_block=/dev/block/bootdevice/by-name/dtbo$slot; - if [ ! -e "$(echo $dtbo_block)" ]; then - ui_print " "; ui_print "dtbo partition could not be found. Aborting..."; exit 1; - fi; - if [ -f "$bin/flash_erase" -a -f "$bin/nandwrite" ]; then - $bin/flash_erase $dtbo_block 0 0; - $bin/nandwrite -p $dtbo_block /tmp/anykernel/$dtbo; - else - dd if=/dev/zero of=$dtbo_block 2>/dev/null; - dd if=/tmp/anykernel/$dtbo of=$dtbo_block; - fi; - fi; -} -flash_boot() { - local name arch os type comp addr ep cmdline cmd board base pagesize kerneloff ramdiskoff tagsoff osver oslvl second secondoff hash unknown i kernel rd dtb rpm pk8 cert avbtype dtbo dtbo_block; - cd $split_img; - if [ -f "$bin/mkimage" ]; then - name=`cat *-name`; - arch=`cat *-arch`; - os=`cat *-os`; - type=`cat *-type`; - comp=`cat *-comp`; - test "$comp" == "uncompressed" && comp=none; - addr=`cat *-addr`; - ep=`cat *-ep`; - else - if [ -f *-cmdline ]; then - cmdline=`cat *-cmdline`; - cmd="$split_img/boot.img-cmdline@cmdline"; - fi; - if [ -f *-board ]; then - board=`cat *-board`; - fi; - base=`cat *-base`; - pagesize=`cat *-pagesize`; - kerneloff=`cat *-kerneloff`; - ramdiskoff=`cat *-ramdiskoff`; - if [ -f *-tagsoff ]; then - tagsoff=`cat *-tagsoff`; - fi; - if [ -f *-osversion ]; then - osver=`cat *-osversion`; - fi; - if [ -f *-oslevel ]; then - oslvl=`cat *-oslevel`; - fi; - if [ -f *-headerversion ]; then - hdrver=`cat *-headerversion`; - fi; - if [ -f *-second ]; then - second=`ls *-second`; - second="--second $split_img/$second"; - secondoff=`cat *-secondoff`; - secondoff="--second_offset $secondoff"; - fi; - if [ -f *-recoverydtbo ]; then - recoverydtbo=`ls *-recoverydtbo`; - recoverydtbo="--recovery_dtbo $split_img/$recoverydtbo"; - fi; - if [ -f *-hash ]; then - hash=`cat *-hash`; - test "$hash" == "unknown" && hash=sha1; - hash="--hash $hash"; - fi; - if [ -f *-unknown ]; then - unknown=`cat *-unknown`; - fi; - fi; - for i in zImage zImage-dtb Image.gz Image Image-dtb Image.gz-dtb Image.bz2 Image.bz2-dtb Image.lzo Image.lzo-dtb Image.lzma Image.lzma-dtb Image.xz Image.xz-dtb Image.lz4 Image.lz4-dtb Image.fit; do - if [ -f /tmp/anykernel/$i ]; then - kernel=/tmp/anykernel/$i; - break; - fi; - done; - if [ ! "$kernel" ]; then - kernel=`ls *-zImage`; - kernel=$split_img/$kernel; - fi; - if [ -f /tmp/anykernel/ramdisk-new.cpio.* ]; then - rd=`echo /tmp/anykernel/ramdisk-new.cpio.*`; - else - rd=`ls *-ramdisk.*`; - rd="$split_img/$rd"; - fi; - for i in dtb dt.img; do - if [ -f /tmp/anykernel/$i ]; then - dtb="--dt /tmp/anykernel/$i"; - rpm="/tmp/anykernel/$i,rpm"; - break; - fi; - done; - if [ ! "$dtb" -a -f *-dtb ]; then - dtb=`ls *-dtb`; - rpm="$split_img/$dtb,rpm"; - dtb="--dt $split_img/$dtb"; - fi; - cd /tmp/anykernel; - if [ -f "$bin/mkmtkhdr" ]; then - case $kernel in - $split_img/*) ;; - *) $bin/mkmtkhdr --kernel $kernel; kernel=$kernel-mtk;; - esac; - fi; - if [ -f "$bin/mkimage" ]; then - test "$type" == "Multi" && uramdisk=":$rd"; - $bin/mkimage -A $arch -O $os -T $type -C $comp -a $addr -e $ep -n "$name" -d $kernel$uramdisk boot-new.img; - elif [ -f "$bin/elftool" ]; then - $bin/elftool pack -o boot-new.img header=$split_img/boot.img-header $kernel $rd,ramdisk $rpm $cmd; - elif [ -f "$bin/rkcrc" ]; then - $bin/rkcrc -k $rd boot-new.img; - elif [ -f "$bin/pxa-mkbootimg" ]; then - $bin/pxa-mkbootimg --kernel $kernel --ramdisk $rd $second --cmdline "$cmdline" --board "$board" --base $base --pagesize $pagesize --kernel_offset $kerneloff --ramdisk_offset $ramdiskoff $secondoff --tags_offset "$tagsoff" --unknown $unknown $dtb --output boot-new.img; - else - $bin/mkbootimg --kernel $kernel --ramdisk $rd $second $recoverydtbo --cmdline "$cmdline" --board "$board" --base $base --pagesize $pagesize --kernel_offset $kerneloff --ramdisk_offset $ramdiskoff $secondoff --tags_offset "$tagsoff" --os_version "$osver" --os_patch_level "$oslvl" --header_version "$hdrver" $hash $dtb --output boot-new.img; - fi; - if [ $? != 0 ]; then - ui_print " "; ui_print "Repacking image failed. Aborting..."; exit 1; - fi; - if [ -f "$bin/futility" -a -d "$bin/chromeos" ]; then - $bin/futility vbutil_kernel --pack boot-new-signed.img --keyblock $bin/chromeos/kernel.keyblock --signprivate $bin/chromeos/kernel_data_key.vbprivk --version 1 --vmlinuz boot-new.img --bootloader $bin/chromeos/empty --config $bin/chromeos/empty --arch arm --flags 0x1; - if [ $? != 0 ]; then - ui_print " "; ui_print "Signing image failed. Aborting..."; exit 1; - fi; - mv -f boot-new-signed.img boot-new.img; - fi; - if [ -f "$bin/BootSignature_Android.jar" -a -d "$bin/avb" ]; then - pk8=`ls $bin/avb/*.pk8`; - cert=`ls $bin/avb/*.x509.*`; - case $block in - *recovery*|*SOS*) avbtype=recovery;; - *) avbtype=boot;; - esac; - if [ "$(/system/bin/dalvikvm -Xbootclasspath:/system/framework/core-oj.jar:/system/framework/core-libart.jar:/system/framework/conscrypt.jar:/system/framework/bouncycastle.jar -Xnodex2oat -Xnoimage-dex2oat -cp $bin/BootSignature_Android.jar com.android.verity.BootSignature -verify boot.img 2>&1 | grep VALID)" ]; then - /system/bin/dalvikvm -Xbootclasspath:/system/framework/core-oj.jar:/system/framework/core-libart.jar:/system/framework/conscrypt.jar:/system/framework/bouncycastle.jar -Xnodex2oat -Xnoimage-dex2oat -cp $bin/BootSignature_Android.jar com.android.verity.BootSignature /$avbtype boot-new.img $pk8 $cert boot-new-signed.img; - if [ $? != 0 ]; then - ui_print " "; ui_print "Signing image failed. Aborting..."; exit 1; - fi; - fi; - mv -f boot-new-signed.img boot-new.img; - fi; - if [ -f "$bin/blobpack" ]; then - printf '-SIGNED-BY-SIGNBLOB-\00\00\00\00\00\00\00\00' > boot-new-signed.img; - $bin/blobpack tempblob LNX boot-new.img; - cat tempblob >> boot-new-signed.img; - mv -f boot-new-signed.img boot-new.img; - fi; - if [ -f "/data/custom_boot_image_patch.sh" ]; then - ash /data/custom_boot_image_patch.sh /tmp/anykernel/boot-new.img; - if [ $? != 0 ]; then - ui_print " "; ui_print "User script execution failed. Aborting..."; exit 1; - fi; - fi; - if [ "$(strings /tmp/anykernel/boot.img | grep SEANDROIDENFORCE )" ]; then - printf 'SEANDROIDENFORCE' >> boot-new.img; - fi; - if [ -f "$bin/dhtbsign" ]; then - $bin/dhtbsign -i boot-new.img -o boot-new-signed.img; - mv -f boot-new-signed.img boot-new.img; - fi; - if [ -f "$split_img/boot.img-master_boot.key" ]; then - cat $split_img/boot.img-master_boot.key boot-new.img > boot-new-signed.img; - mv -f boot-new-signed.img boot-new.img; - fi; - if [ ! -f /tmp/anykernel/boot-new.img ]; then - ui_print " "; ui_print "Repacked image could not be found. Aborting..."; exit 1; - elif [ "$(wc -c < boot-new.img)" -gt "$(wc -c < boot.img)" ]; then - ui_print " "; ui_print "New image larger than boot partition. Aborting..."; exit 1; - fi; - if [ -f "$bin/flash_erase" -a -f "$bin/nandwrite" ]; then - $bin/flash_erase $block 0 0; - $bin/nandwrite -p $block /tmp/anykernel/boot-new.img; - else - dd if=/dev/zero of=$block 2>/dev/null; - dd if=/tmp/anykernel/boot-new.img of=$block; - fi; -} -write_boot() { - repack_ramdisk; - flash_boot; - flash_dtbo; -} - -# backup_file -backup_file() { test ! -f $1~ && cp $1 $1~; } - -# restore_file -restore_file() { test -f $1~ && mv -f $1~ $1; } - -# replace_string -replace_string() { - if [ -z "$(grep "$2" $1)" ]; then - sed -i "s;${3};${4};" $1; - fi; -} - -# replace_section -replace_section() { - local begin endstr last end; - begin=`grep -n "$2" $1 | head -n1 | cut -d: -f1`; - if [ "$begin" ]; then - if [ "$3" == " " -o -z "$3" ]; then - endstr='^[[:space:]]*$'; - last=$(wc -l $1 | cut -d\ -f1); - else - endstr="$3"; - fi; - for end in $(grep -n "$endstr" $1 | cut -d: -f1) $last; do - if [ "$end" ] && [ "$begin" -lt "$end" ]; then - sed -i "${begin},${end}d" $1; - test "$end" == "$last" && echo >> $1; - sed -i "${begin}s;^;${4}\n;" $1; - break; - fi; - done; - fi; -} - -# remove_section -remove_section() { - local begin endstr last end; - begin=`grep -n "$2" $1 | head -n1 | cut -d: -f1`; - if [ "$begin" ]; then - if [ "$3" == " " -o -z "$3" ]; then - endstr='^[[:space:]]*$'; - last=$(wc -l $1 | cut -d\ -f1); - else - endstr="$3"; - fi; - for end in $(grep -n "$endstr" $1 | cut -d: -f1) $last; do - if [ "$end" ] && [ "$begin" -lt "$end" ]; then - sed -i "${begin},${end}d" $1; - break; - fi; - done; - fi; -} - -# insert_line -insert_line() { - local offset line; - if [ -z "$(grep "$2" $1)" ]; then - case $3 in - before) offset=0;; - after) offset=1;; - esac; - line=$((`grep -n "$4" $1 | head -n1 | cut -d: -f1` + offset)); - if [ -f $1 -a "$line" ] && [ "$(wc -l $1 | cut -d\ -f1)" -lt "$line" ]; then - echo "$5" >> $1; - else - sed -i "${line}s;^;${5}\n;" $1; - fi; - fi; -} - -# replace_line -replace_line() { - if [ ! -z "$(grep "$2" $1)" ]; then - local line=`grep -n "$2" $1 | head -n1 | cut -d: -f1`; - sed -i "${line}s;.*;${3};" $1; - fi; -} - -# remove_line -remove_line() { - if [ ! -z "$(grep "$2" $1)" ]; then - local line=`grep -n "$2" $1 | head -n1 | cut -d: -f1`; - sed -i "${line}d" $1; - fi; -} - -# prepend_file -prepend_file() { - if [ -z "$(grep "$2" $1)" ]; then - echo "$(cat $patch/$3 $1)" > $1; - fi; -} - -# insert_file -insert_file() { - local offset line; - if [ -z "$(grep "$2" $1)" ]; then - case $3 in - before) offset=0;; - after) offset=1;; - esac; - line=$((`grep -n "$4" $1 | head -n1 | cut -d: -f1` + offset)); - sed -i "${line}s;^;\n;" $1; - sed -i "$((line - 1))r $patch/$5" $1; - fi; -} - -# append_file -append_file() { - if [ -z "$(grep "$2" $1)" ]; then - echo -ne "\n" >> $1; - cat $patch/$3 >> $1; - echo -ne "\n" >> $1; - fi; -} - -# replace_file -replace_file() { - cp -pf $patch/$3 $1; - chmod $2 $1; -} - -# patch_fstab -patch_fstab() { - local entry part newpart newentry; - entry=$(grep "$2" $1 | grep "$3"); - if [ -z "$(echo "$entry" | grep "$6")" -o "$6" == " " -o -z "$6" ]; then - case $4 in - block) part=$(echo "$entry" | awk '{ print $1 }');; - mount) part=$(echo "$entry" | awk '{ print $2 }');; - fstype) part=$(echo "$entry" | awk '{ print $3 }');; - options) part=$(echo "$entry" | awk '{ print $4 }');; - flags) part=$(echo "$entry" | awk '{ print $5 }');; - esac; - newpart=$(echo "$part" | sed -e "s;${5};${6};" -e "s; ;;g" -e 's;,\{2,\};,;g' -e 's;,*$;;g' -e 's;^,;;g'); - newentry=$(echo "$entry" | sed "s;${part};${newpart};"); - sed -i "s;${entry};${newentry};" $1; - fi; -} - -# patch_cmdline -patch_cmdline() { - local cmdfile cmdtmp match; - cmdfile=`ls $split_img/*-cmdline`; - if [ -z "$(grep "$1" $cmdfile)" ]; then - cmdtmp=`cat $cmdfile`; - echo "$cmdtmp $2" > $cmdfile; - sed -i -e 's; *; ;g' -e 's;[ \t]*$;;' $cmdfile; - else - match=$(grep -o "$1.*$" $cmdfile | cut -d\ -f1); - sed -i -e "s;${match};${2};" -e 's; *; ;g' -e 's;[ \t]*$;;' $cmdfile; - fi; -} - -# patch_prop -patch_prop() { - if [ -z "$(grep "^$2=" $1)" ]; then - echo -ne "\n$2=$3\n" >> $1; - else - local line=`grep -n "^$2=" $1 | head -n1 | cut -d: -f1`; - sed -i "${line}s;.*;${2}=${3};" $1; - fi; -} - -# patch_ueventd -patch_ueventd() { - local file dev perm user group newentry line; - file=$1; dev=$2; perm=$3; user=$4; - shift 4; - group="$@"; - newentry=$(printf "%-23s %-4s %-8s %s\n" "$dev" "$perm" "$user" "$group"); - line=`grep -n "$dev" $file | head -n1 | cut -d: -f1`; - if [ "$line" ]; then - sed -i "${line}s;.*;${newentry};" $file; - else - echo -ne "\n$newentry\n" >> $file; - fi; -} - -# allow multi-partition ramdisk modifying configurations (using reset_ak) -if [ ! -d "$ramdisk" -a ! -d "$patch" ]; then - if [ -d "$(basename $block)-files" ]; then - cp -af /tmp/anykernel/$(basename $block)-files/* /tmp/anykernel; - else - mkdir -p /tmp/anykernel/$(basename $block)-files; - fi; - touch /tmp/anykernel/$(basename $block)-files/current; -fi; -test ! -d "$ramdisk" && mkdir -p $ramdisk; - -# slot detection enabled by is_slot_device=1 or auto (from anykernel.sh) -case $is_slot_device in - 1|auto) - slot=$(getprop ro.boot.slot_suffix 2>/dev/null); - test ! "$slot" && slot=$(grep -o 'androidboot.slot_suffix=.*$' /proc/cmdline | cut -d\ -f1 | cut -d= -f2); - if [ ! "$slot" ]; then - slot=$(getprop ro.boot.slot 2>/dev/null); - test ! "$slot" && slot=$(grep -o 'androidboot.slot=.*$' /proc/cmdline | cut -d\ -f1 | cut -d= -f2); - test "$slot" && slot=_$slot; - fi; - if [ ! "$slot" -a "$is_slot_device" == 1 ]; then - ui_print " "; ui_print "Unable to determine active boot slot. Aborting..."; exit 1; - fi; - ;; -esac; - -# target block partition detection enabled by block=boot recovery or auto (from anykernel.sh) -test "$block" == "auto" && block=boot; -case $block in - boot|recovery) - case $block in - boot) parttype="ramdisk boot BOOT LNX android_boot KERN-A kernel KERNEL";; - recovery) parttype="ramdisk_recovey recovery RECOVERY SOS android_recovery";; - esac; - for name in $parttype; do - for part in $name $name$slot; do - if [ "$(grep -w "$part" /proc/mtd 2> /dev/null)" ]; then - mtdmount=$(grep -w "$part" /proc/mtd); - mtdpart=$(echo $mtdmount | cut -d\" -f2); - if [ "$mtdpart" == "$part" ]; then - mtd=$(echo $mtdmount | cut -d: -f1); - else - ui_print " "; ui_print "Unable to determine mtd $block partition. Aborting..."; exit 1; - fi; - target=/dev/mtd/$mtd; - elif [ -e /dev/block/by-name/$part ]; then - target=/dev/block/by-name/$part; - elif [ -e /dev/block/bootdevice/by-name/$part ]; then - target=/dev/block/bootdevice/by-name/$part; - elif [ -e /dev/block/platform/*/by-name/$part ]; then - target=/dev/block/platform/*/by-name/$part; - elif [ -e /dev/block/platform/*/*/by-name/$part ]; then - target=/dev/block/platform/*/*/by-name/$part; - fi; - test -e "$target" && break 2; - done; - done; - if [ "$target" ]; then - block=$(echo -n $target); - else - ui_print " "; ui_print "Unable to determine $block partition. Aborting..."; exit 1; - fi; - ;; - *) - if [ "$slot" ]; then - test -e "$block$slot" && block=$block$slot; - fi; - ;; -esac; - -## end methods - diff --git a/anykernel_Ares/tools/ak3-core.sh b/anykernel_Ares/tools/ak3-core.sh new file mode 100644 index 00000000..9c93125c --- /dev/null +++ b/anykernel_Ares/tools/ak3-core.sh @@ -0,0 +1,761 @@ +### AnyKernel methods (DO NOT CHANGE) +## osm0sis@xda-developers.com + +OUTFD=$1; + +# set up working directory variables +test "$home" || home=$PWD; +bootimg=$home/boot.img; +bin=$home/tools; +patch=$home/patch; +ramdisk=$home/ramdisk; +split_img=$home/split_img; + +### output/testing functions: +# ui_print "" [...] +ui_print() { + until [ ! "$1" ]; do + echo -e "ui_print $1 + ui_print" >> /proc/self/fd/$OUTFD; + shift; + done; +} + +# abort ["" [...]] +abort() { + ui_print " " "$@"; + exit 1; +} + +# contains +contains() { + test "${1#*$2}" != "$1"; +} + +# file_getprop +file_getprop() { + grep "^$2=" "$1" | cut -d= -f2-; +} +### + +### file/directory attributes functions: +# set_perm [ ...] +set_perm() { + local uid gid mod; + uid=$1; gid=$2; mod=$3; + shift 3; + chown $uid:$gid "$@" || chown $uid.$gid "$@"; + chmod $mod "$@"; +} + +# set_perm_recursive [ ...] +set_perm_recursive() { + local uid gid dmod fmod; + uid=$1; gid=$2; dmod=$3; fmod=$4; + shift 4; + while [ "$1" ]; do + chown -R $uid:$gid "$1" || chown -R $uid.$gid "$1"; + find "$1" -type d -exec chmod $dmod {} +; + find "$1" -type f -exec chmod $fmod {} +; + shift; + done; +} +### + +### dump_boot functions: +# split_boot (dump and split image only) +split_boot() { + local dumpfail; + + if [ ! -e "$(echo $block | cut -d\ -f1)" ]; then + abort "Invalid partition. Aborting..."; + fi; + if [ "$(echo $block | grep ' ')" ]; then + block=$(echo $block | cut -d\ -f1); + customdd=$(echo $block | cut -d\ -f2-); + elif [ ! "$customdd" ]; then + local customdd="bs=1048576"; + fi; + if [ -f "$bin/nanddump" ]; then + $bin/nanddump -f $bootimg $block; + else + dd if=$block of=$bootimg $customdd; + fi; + test $? != 0 && dumpfail=1; + + mkdir -p $split_img; + cd $split_img; + if [ -f "$bin/unpackelf" ] && $bin/unpackelf -i $bootimg -h -q 2>/dev/null; then + if [ -f "$bin/elftool" ]; then + mkdir elftool_out; + $bin/elftool unpack -i $bootimg -o elftool_out; + fi; + $bin/unpackelf -i $bootimg; + test $? != 0 && dumpfail=1; + mv -f boot.img-zImage kernel.gz; + mv -f boot.img-ramdisk.cpio.gz ramdisk.cpio.gz; + mv -f boot.img-cmdline cmdline.txt 2>/dev/null; + if [ -f boot.img-dt -a ! -f "$bin/elftool" ]; then + case $(od -ta -An -N4 boot.img-dt | sed -e 's/ del//' -e 's/ //g') in + QCDT|ELF) mv -f boot.img-dt dt;; + *) + gzip -c kernel.gz > kernel.gz-dtb; + cat boot.img-dt >> kernel.gz-dtb; + rm -f boot.img-dt kernel.gz; + ;; + esac; + fi; + elif [ -f "$bin/mboot" ]; then + $bin/mboot -u -f $bootimg; + elif [ -f "$bin/dumpimage" ]; then + dd bs=$(($(printf '%d\n' 0x$(hexdump -n 4 -s 12 -e '16/1 "%02x""\n"' $bootimg)) + 64)) count=1 conv=notrunc if=$bootimg of=boot-trimmed.img; + $bin/dumpimage -l boot-trimmed.img > header; + grep "Name:" header | cut -c15- > boot.img-name; + grep "Type:" header | cut -c15- | cut -d\ -f1 > boot.img-arch; + grep "Type:" header | cut -c15- | cut -d\ -f2 > boot.img-os; + grep "Type:" header | cut -c15- | cut -d\ -f3 | cut -d- -f1 > boot.img-type; + grep "Type:" header | cut -d\( -f2 | cut -d\) -f1 | cut -d\ -f1 | cut -d- -f1 > boot.img-comp; + grep "Address:" header | cut -c15- > boot.img-addr; + grep "Point:" header | cut -c15- > boot.img-ep; + $bin/dumpimage -p 0 -o kernel.gz boot-trimmed.img; + test $? != 0 && dumpfail=1; + case $(cat boot.img-type) in + Multi) $bin/dumpimage -p 1 -o ramdisk.cpio.gz boot-trimmed.img;; + RAMDisk) mv -f kernel.gz ramdisk.cpio.gz;; + esac; + elif [ -f "$bin/rkcrc" ]; then + dd bs=4096 skip=8 iflag=skip_bytes conv=notrunc if=$bootimg of=ramdisk.cpio.gz; + else + $bin/magiskboot unpack -h $bootimg; + case $? in + 1) dumpfail=1;; + 2) touch chromeos;; + esac; + fi; + + if [ $? != 0 -o "$dumpfail" ]; then + abort "Dumping/splitting image failed. Aborting..."; + fi; + cd $home; +} + +# unpack_ramdisk (extract ramdisk only) +unpack_ramdisk() { + local comp; + + cd $split_img; + if [ -f ramdisk.cpio.gz ]; then + if [ -f "$bin/mkmtkhdr" ]; then + mv -f ramdisk.cpio.gz ramdisk.cpio.gz-mtk; + dd bs=512 skip=1 conv=notrunc if=ramdisk.cpio.gz-mtk of=ramdisk.cpio.gz; + fi; + mv -f ramdisk.cpio.gz ramdisk.cpio; + fi; + + if [ -f ramdisk.cpio ]; then + comp=$($bin/magiskboot decompress ramdisk.cpio 2>&1 | grep -v 'raw' | sed -n 's;.*\[\(.*\)\];\1;p'); + else + abort "No ramdisk found to unpack. Aborting..."; + fi; + if [ "$comp" ]; then + mv -f ramdisk.cpio ramdisk.cpio.$comp; + $bin/magiskboot decompress ramdisk.cpio.$comp ramdisk.cpio; + if [ $? != 0 ]; then + echo "Attempting ramdisk unpack with busybox $comp..." >&2; + $comp -dc ramdisk.cpio.$comp > ramdisk.cpio; + fi; + fi; + + test -d $ramdisk && mv -f $ramdisk $home/rdtmp; + mkdir -p $ramdisk; + chmod 755 $ramdisk; + + cd $ramdisk; + EXTRACT_UNSAFE_SYMLINKS=1 cpio -d -F $split_img/ramdisk.cpio -i; + if [ $? != 0 -o ! "$(ls)" ]; then + abort "Unpacking ramdisk failed. Aborting..."; + fi; + if [ -d "$home/rdtmp" ]; then + cp -af $home/rdtmp/* .; + fi; +} +### dump_boot (dump and split image, then extract ramdisk) +dump_boot() { + split_boot; + unpack_ramdisk; +} +### + +### write_boot functions: +# repack_ramdisk (repack ramdisk only) +repack_ramdisk() { + local comp packfail mtktype; + + cd $home; + case $ramdisk_compression in + auto|"") comp=$(ls $split_img/ramdisk.cpio.* 2>/dev/null | grep -v 'mtk' | rev | cut -d. -f1 | rev);; + none|cpio) comp="";; + gz) comp=gzip;; + lzo) comp=lzop;; + bz2) comp=bzip2;; + lz4-l) comp=lz4_legacy;; + *) comp=$ramdisk_compression;; + esac; + + if [ -f "$bin/mkbootfs" ]; then + $bin/mkbootfs $ramdisk > ramdisk-new.cpio; + else + cd $ramdisk; + find . | cpio -H newc -o > $home/ramdisk-new.cpio; + fi; + test $? != 0 && packfail=1; + + cd $home; + $bin/magiskboot cpio ramdisk-new.cpio test; + magisk_patched=$?; + test $((magisk_patched & 3)) -eq 1 && $bin/magiskboot cpio ramdisk-new.cpio "extract .backup/.magisk $split_img/.magisk"; + if [ "$comp" ]; then + $bin/magiskboot compress=$comp ramdisk-new.cpio; + if [ $? != 0 ]; then + echo "Attempting ramdisk repack with busybox $comp..." >&2; + $comp -9c ramdisk-new.cpio > ramdisk-new.cpio.$comp; + test $? != 0 && packfail=1; + rm -f ramdisk-new.cpio; + fi; + fi; + if [ "$packfail" ]; then + abort "Repacking ramdisk failed. Aborting..."; + fi; + + if [ -f "$bin/mkmtkhdr" -a -f "$split_img/boot.img-base" ]; then + mtktype=$(od -ta -An -N8 -j8 $split_img/ramdisk.cpio.gz-mtk | sed -e 's/ nul//g' -e 's/ //g' | tr '[:upper:]' '[:lower:]'); + case $mtktype in + rootfs|recovery) $bin/mkmtkhdr --$mtktype ramdisk-new.cpio*;; + esac; + fi; +} + +# flash_boot (build, sign and write image only) +flash_boot() { + local varlist i kernel ramdisk fdt cmdline comp part0 part1 nocompflag signfail pk8 cert avbtype; + + cd $split_img; + if [ -f "$bin/mkimage" ]; then + varlist="name arch os type comp addr ep"; + elif [ -f "$bin/mkbootimg" -a -f "$bin/unpackelf" -a -f boot.img-base ]; then + mv -f cmdline.txt boot.img-cmdline 2>/dev/null; + varlist="cmdline base pagesize kerneloff ramdiskoff tagsoff"; + fi; + for i in $varlist; do + if [ -f boot.img-$i ]; then + eval local $i=\"$(cat boot.img-$i)\"; + fi; + done; + + cd $home; + for i in zImage zImage-dtb Image Image-dtb Image.gz Image.gz-dtb Image.bz2 Image.bz2-dtb Image.lzo Image.lzo-dtb Image.lzma Image.lzma-dtb Image.xz Image.xz-dtb Image.lz4 Image.lz4-dtb Image.fit; do + if [ -f $i ]; then + kernel=$home/$i; + break; + fi; + done; + if [ "$kernel" ]; then + if [ -f "$bin/mkmtkhdr" -a -f "$split_img/boot.img-base" ]; then + $bin/mkmtkhdr --kernel $kernel; + kernel=$kernel-mtk; + fi; + elif [ "$(ls $split_img/kernel* 2>/dev/null)" ]; then + kernel=$(ls $split_img/kernel* | grep -v 'kernel_dtb' | tail -n1); + fi; + if [ "$(ls ramdisk-new.cpio* 2>/dev/null)" ]; then + ramdisk=$home/$(ls ramdisk-new.cpio* | tail -n1); + elif [ -f "$bin/mkmtkhdr" -a -f "$split_img/boot.img-base" ]; then + ramdisk=$split_img/ramdisk.cpio.gz-mtk; + else + ramdisk=$(ls $split_img/ramdisk.cpio* 2>/dev/null | tail -n1); + fi; + for fdt in dt recovery_dtbo dtb; do + for i in $home/$fdt $home/$fdt.img $split_img/$fdt; do + if [ -f $i ]; then + eval local $fdt=$i; + break; + fi; + done; + done; + + cd $split_img; + if [ -f "$bin/mkimage" ]; then + test "$comp" == "uncompressed" && comp=none; + part0=$kernel; + case $type in + Multi) part1=":$ramdisk";; + RAMDisk) part0=$ramdisk;; + esac; + $bin/mkimage -A $arch -O $os -T $type -C $comp -a $addr -e $ep -n "$name" -d $part0$part1 $home/boot-new.img; + elif [ -f "$bin/elftool" ]; then + test "$dt" && dt="$dt,rpm"; + test -f cmdline.txt && cmdline="cmdline.txt@cmdline"; + $bin/elftool pack -o $home/boot-new.img header=elftool_out/header $kernel $ramdisk,ramdisk $dt $cmdline; + elif [ -f "$bin/mboot" ]; then + cp -f $kernel kernel; + cp -f $ramdisk ramdisk.cpio.gz; + $bin/mboot -d $split_img -f $home/boot-new.img; + elif [ -f "$bin/rkcrc" ]; then + $bin/rkcrc -k $ramdisk $home/boot-new.img; + elif [ -f "$bin/mkbootimg" -a -f "$bin/unpackelf" -a -f boot.img-base ]; then + test "$dt" && dt="--dt $dt"; + $bin/mkbootimg --kernel $kernel --ramdisk $ramdisk --cmdline "$cmdline" --base $home --pagesize $pagesize --kernel_offset $kerneloff --ramdisk_offset $ramdiskoff --tags_offset "$tagsoff" $dt --output $home/boot-new.img; + else + test "$kernel" && cp -f $kernel kernel; + test "$ramdisk" && cp -f $ramdisk ramdisk.cpio; + test "$dt" -a -f extra && cp -f $dt extra; + for i in dtb recovery_dtbo; do + test "$(eval echo \$$i)" -a -f $i && cp -f $(eval echo \$$i) $i; + done; + case $kernel in + *Image*) + if [ ! "$magisk_patched" ]; then + $bin/magiskboot cpio ramdisk.cpio test; + magisk_patched=$?; + fi; + if [ $((magisk_patched & 3)) -eq 1 ]; then + ui_print " " "Magisk detected! Patching kernel so reflashing Magisk is not necessary..."; + comp=$($bin/magiskboot decompress kernel 2>&1 | grep -v 'raw' | sed -n 's;.*\[\(.*\)\];\1;p'); + ($bin/magiskboot split $kernel || $bin/magiskboot decompress $kernel kernel) 2>/dev/null; + if [ $? != 0 -a "$comp" ]; then + echo "Attempting kernel unpack with busybox $comp..." >&2; + $comp -dc $kernel > kernel; + fi; + $bin/magiskboot hexpatch kernel 736B69705F696E697472616D667300 77616E745F696E697472616D667300; + if [ "$(file_getprop $home/anykernel.sh do.systemless)" == 1 ]; then + strings kernel | grep -E 'Linux version.*#' > $home/vertmp; + fi; + if [ "$comp" ]; then + $bin/magiskboot compress=$comp kernel kernel.$comp; + if [ $? != 0 ]; then + echo "Attempting kernel repack with busybox $comp..." >&2; + $comp -9c kernel > kernel.$comp; + fi; + mv -f kernel.$comp kernel; + fi; + test ! -f .magisk && $bin/magiskboot cpio ramdisk.cpio "extract .backup/.magisk .magisk"; + export $(cat .magisk); + test $((magisk_patched & 8)) -ne 0 && export TWOSTAGEINIT=true; + for fdt in dtb extra kernel_dtb recovery_dtbo; do + test -f $fdt && $bin/magiskboot dtb $fdt patch; + done; + else + case $kernel in + *-dtb) rm -f kernel_dtb;; + esac; + fi; + unset magisk_patched KEEPFORCEENCRYPT KEEPVERITY SHA1 TWOSTAGEINIT; + ;; + esac; + case $ramdisk_compression in + none|cpio) nocompflag="-n";; + esac; + $bin/magiskboot repack $nocompflag $bootimg $home/boot-new.img; + fi; + if [ $? != 0 ]; then + abort "Repacking image failed. Aborting..."; + fi; + + cd $home; + if [ -f "$bin/futility" -a -d "$bin/chromeos" ]; then + if [ -f "$split_img/chromeos" ]; then + echo "Signing with CHROMEOS..." >&2; + $bin/futility vbutil_kernel --pack boot-new-signed.img --keyblock $bin/chromeos/kernel.keyblock --signprivate $bin/chromeos/kernel_data_key.vbprivk --version 1 --vmlinuz boot-new.img --bootloader $bin/chromeos/empty --config $bin/chromeos/empty --arch arm --flags 0x1; + fi; + test $? != 0 && signfail=1; + fi; + if [ -f "$bin/BootSignature_Android.jar" -a -d "$bin/avb" ]; then + pk8=$(ls $bin/avb/*.pk8); + cert=$(ls $bin/avb/*.x509.*); + case $block in + *recovery*|*SOS*) avbtype=recovery;; + *) avbtype=boot;; + esac; + if [ "$(/system/bin/dalvikvm -Xnoimage-dex2oat -cp $bin/BootSignature_Android.jar com.android.verity.BootSignature -verify boot.img 2>&1 | grep VALID)" ]; then + echo "Signing with AVBv1..." >&2; + /system/bin/dalvikvm -Xnoimage-dex2oat -cp $bin/BootSignature_Android.jar com.android.verity.BootSignature /$avbtype boot-new.img $pk8 $cert boot-new-signed.img; + fi; + fi; + if [ $? != 0 -o "$signfail" ]; then + abort "Signing image failed. Aborting..."; + fi; + mv -f boot-new-signed.img boot-new.img 2>/dev/null; + + if [ ! -f boot-new.img ]; then + abort "No repacked image found to flash. Aborting..."; + elif [ "$(wc -c < boot-new.img)" -gt "$(wc -c < boot.img)" ]; then + abort "New image larger than boot partition. Aborting..."; + fi; + if [ -f "$bin/flash_erase" -a -f "$bin/nandwrite" ]; then + $bin/flash_erase $block 0 0; + $bin/nandwrite -p $block boot-new.img; + elif [ "$customdd" ]; then + dd if=/dev/zero of=$block $customdd 2>/dev/null; + dd if=boot-new.img of=$block $customdd; + else + cat boot-new.img /dev/zero > $block 2>/dev/null || true; + fi; + if [ $? != 0 ]; then + abort "Flashing image failed. Aborting..."; + fi; +} + +# flash_dtbo (flash dtbo only) +flash_dtbo() { + local i dtbo dtboblock; + + cd $home; + for i in dtbo dtbo.img; do + if [ -f $i ]; then + dtbo=$i; + break; + fi; + done; + + if [ "$dtbo" ]; then + dtboblock=/dev/block/bootdevice/by-name/dtbo$slot; + if [ ! -e "$dtboblock" ]; then + abort "dtbo partition could not be found. Aborting..."; + fi; + if [ -f "$bin/flash_erase" -a -f "$bin/nandwrite" ]; then + $bin/flash_erase $dtboblock 0 0; + $bin/nandwrite -p $dtboblock $dtbo; + elif [ "$customdd" ]; then + dd if=/dev/zero of=$dtboblock 2>/dev/null; + dd if=$dtbo of=$dtboblock; + else + cat $dtbo /dev/zero > $dtboblock 2>/dev/null || true; + fi; + if [ $? != 0 ]; then + abort "Flashing dtbo failed. Aborting..."; + fi; + fi; +} +### write_boot (repack ramdisk then build, sign and write image and dtbo) +write_boot() { + repack_ramdisk; + flash_boot; + flash_dtbo; +} +### + +### file editing functions: +# backup_file +backup_file() { test ! -f $1~ && cp -fp $1 $1~; } + +# restore_file +restore_file() { test -f $1~ && cp -fp $1~ $1; rm -f $1~; } + +# replace_string +replace_string() { + test "$5" == "global" && local scope=g; + if ! grep -q "$2" $1; then + sed -i "s;${3};${4};${scope}" $1; + fi; +} + +# replace_section +replace_section() { + local begin endstr last end; + begin=$(grep -n "$2" $1 | head -n1 | cut -d: -f1); + if [ "$begin" ]; then + if [ "$3" == " " -o ! "$3" ]; then + endstr='^[[:space:]]*$'; + last=$(wc -l $1 | cut -d\ -f1); + else + endstr="$3"; + fi; + for end in $(grep -n "$endstr" $1 | cut -d: -f1) $last; do + if [ "$end" ] && [ "$begin" -lt "$end" ]; then + sed -i "${begin},${end}d" $1; + test "$end" == "$last" && echo >> $1; + sed -i "${begin}s;^;${4}\n;" $1; + break; + fi; + done; + fi; +} + +# remove_section +remove_section() { + local begin endstr last end; + begin=$(grep -n "$2" $1 | head -n1 | cut -d: -f1); + if [ "$begin" ]; then + if [ "$3" == " " -o ! "$3" ]; then + endstr='^[[:space:]]*$'; + last=$(wc -l $1 | cut -d\ -f1); + else + endstr="$3"; + fi; + for end in $(grep -n "$endstr" $1 | cut -d: -f1) $last; do + if [ "$end" ] && [ "$begin" -lt "$end" ]; then + sed -i "${begin},${end}d" $1; + break; + fi; + done; + fi; +} + +# insert_line +insert_line() { + local offset line; + if ! grep -q "$2" $1; then + case $3 in + before) offset=0;; + after) offset=1;; + esac; + line=$((`grep -n "$4" $1 | head -n1 | cut -d: -f1` + offset)); + if [ -f $1 -a "$line" ] && [ "$(wc -l $1 | cut -d\ -f1)" -lt "$line" ]; then + echo "$5" >> $1; + else + sed -i "${line}s;^;${5}\n;" $1; + fi; + fi; +} + +# replace_line +replace_line() { + if grep -q "$2" $1; then + local line=$(grep -n "$2" $1 | head -n1 | cut -d: -f1); + sed -i "${line}s;.*;${3};" $1; + fi; +} + +# remove_line +remove_line() { + if grep -q "$2" $1; then + local line=$(grep -n "$2" $1 | head -n1 | cut -d: -f1); + sed -i "${line}d" $1; + fi; +} + +# prepend_file +prepend_file() { + if ! grep -q "$2" $1; then + echo "$(cat $patch/$3 $1)" > $1; + fi; +} + +# insert_file +insert_file() { + local offset line; + if ! grep -q "$2" $1; then + case $3 in + before) offset=0;; + after) offset=1;; + esac; + line=$((`grep -n "$4" $1 | head -n1 | cut -d: -f1` + offset)); + sed -i "${line}s;^;\n;" $1; + sed -i "$((line - 1))r $patch/$5" $1; + fi; +} + +# append_file +append_file() { + if ! grep -q "$2" $1; then + echo -ne "\n" >> $1; + cat $patch/$3 >> $1; + echo -ne "\n" >> $1; + fi; +} + +# replace_file +replace_file() { + cp -pf $patch/$3 $1; + chmod $2 $1; +} + +# patch_fstab block|mount|fstype|options|flags +patch_fstab() { + local entry part newpart newentry; + entry=$(grep "$2" $1 | grep "$3"); + if [ ! "$(echo "$entry" | grep "$6")" -o "$6" == " " -o ! "$6" ]; then + case $4 in + block) part=$(echo "$entry" | awk '{ print $1 }');; + mount) part=$(echo "$entry" | awk '{ print $2 }');; + fstype) part=$(echo "$entry" | awk '{ print $3 }');; + options) part=$(echo "$entry" | awk '{ print $4 }');; + flags) part=$(echo "$entry" | awk '{ print $5 }');; + esac; + newpart=$(echo "$part" | sed -e "s;${5};${6};" -e "s; ;;g" -e 's;,\{2,\};,;g' -e 's;,*$;;g' -e 's;^,;;g'); + newentry=$(echo "$entry" | sed "s;${part};${newpart};"); + sed -i "s;${entry};${newentry};" $1; + fi; +} + +# patch_cmdline +patch_cmdline() { + local cmdfile cmdtmp match; + if [ -f "$split_img/cmdline.txt" ]; then + cmdfile=$split_img/cmdline.txt; + else + cmdfile=$home/cmdtmp; + grep "^cmdline=" $split_img/header | cut -d= -f2- > $cmdfile; + fi; + if ! grep -q "$1" $cmdfile; then + cmdtmp=$(cat $cmdfile); + echo "$cmdtmp $2" > $cmdfile; + sed -i -e 's; *; ;g' -e 's;[ \t]*$;;' $cmdfile; + else + match=$(grep -o "$1.*$" $cmdfile | cut -d\ -f1); + sed -i -e "s;${match};${2};" -e 's; *; ;g' -e 's;[ \t]*$;;' $cmdfile; + fi; + if [ -f "$home/cmdtmp" ]; then + sed -i "s|^cmdline=.*|cmdline=$(cat $cmdfile)|" $split_img/header; + rm -f $cmdfile; + fi; +} + +# patch_prop +patch_prop() { + if ! grep -q "^$2=" $1; then + echo -ne "\n$2=$3\n" >> $1; + else + local line=$(grep -n "^$2=" $1 | head -n1 | cut -d: -f1); + sed -i "${line}s;.*;${2}=${3};" $1; + fi; +} + +# patch_ueventd +patch_ueventd() { + local file dev perm user group newentry line; + file=$1; dev=$2; perm=$3; user=$4; + shift 4; + group="$@"; + newentry=$(printf "%-23s %-4s %-8s %s\n" "$dev" "$perm" "$user" "$group"); + line=$(grep -n "$dev" $file | head -n1 | cut -d: -f1); + if [ "$line" ]; then + sed -i "${line}s;.*;${newentry};" $file; + else + echo -ne "\n$newentry\n" >> $file; + fi; +} +### + +### configuration/setup functions: +# reset_ak [keep] +reset_ak() { + local current i; + + current=$(dirname $home/*-files/current); + if [ -d "$current" ]; then + rm -rf $current/ramdisk; + for i in $bootimg boot-new.img; do + test -e $i && cp -af $i $current; + done; + fi; + test -d $split_img && rm -rf $ramdisk; + rm -rf $bootimg $split_img $home/*-new* $home/*-files/current; + + if [ "$1" == "keep" ]; then + test -d $home/rdtmp && mv -f $home/rdtmp $ramdisk; + else + rm -rf $patch $home/rdtmp; + fi; + setup_ak; +} + +# setup_ak +setup_ak() { + local blockfiles parttype name part mtdmount mtdpart mtdname target; + + # allow multi-partition ramdisk modifying configurations (using reset_ak) + if [ "$block" ] && [ ! -d "$ramdisk" -a ! -d "$patch" ]; then + blockfiles=$home/$(basename $block)-files; + if [ "$(ls $blockfiles 2>/dev/null)" ]; then + cp -af $blockfiles/* $home; + else + mkdir -p $blockfiles; + fi; + touch $blockfiles/current; + fi; + + # slot detection enabled by is_slot_device=1 or auto (from anykernel.sh) + case $is_slot_device in + 1|auto) + slot=$(getprop ro.boot.slot_suffix 2>/dev/null); + test "$slot" || slot=$(grep -o 'androidboot.slot_suffix=.*$' /proc/cmdline | cut -d\ -f1 | cut -d= -f2); + if [ ! "$slot" ]; then + slot=$(getprop ro.boot.slot 2>/dev/null); + test "$slot" || slot=$(grep -o 'androidboot.slot=.*$' /proc/cmdline | cut -d\ -f1 | cut -d= -f2); + test "$slot" && slot=_$slot; + fi; + if [ "$slot" ]; then + if [ -d /postinstall/tmp -a ! "$slot_select" ]; then + slot_select=inactive; + fi; + case $slot_select in + inactive) + case $slot in + _a) slot=_b;; + _b) slot=_a;; + esac; + ;; + esac; + fi; + if [ ! "$slot" -a "$is_slot_device" == 1 ]; then + abort "Unable to determine active boot slot. Aborting..."; + fi; + ;; + esac; + + # target block partition detection enabled by block=boot recovery or auto (from anykernel.sh) + case $block in + auto|"") block=boot;; + esac; + case $block in + boot|recovery) + case $block in + boot) parttype="ramdisk boot BOOT LNX android_boot bootimg KERN-A kernel KERNEL";; + recovery) parttype="ramdisk_recovery recovery RECOVERY SOS android_recovery";; + esac; + for name in $parttype; do + for part in $name$slot $name; do + if [ "$(grep -w "$part" /proc/mtd 2> /dev/null)" ]; then + mtdmount=$(grep -w "$part" /proc/mtd); + mtdpart=$(echo $mtdmount | cut -d\" -f2); + if [ "$mtdpart" == "$part" ]; then + mtdname=$(echo $mtdmount | cut -d: -f1); + else + abort "Unable to determine mtd $block partition. Aborting..."; + fi; + if [ -e /dev/mtd/$mtdname ]; then + target=/dev/mtd/$mtdname; + fi; + elif [ -e /dev/block/by-name/$part ]; then + target=/dev/block/by-name/$part; + elif [ -e /dev/block/bootdevice/by-name/$part ]; then + target=/dev/block/bootdevice/by-name/$part; + elif [ -e /dev/block/platform/*/by-name/$part ]; then + target=/dev/block/platform/*/by-name/$part; + elif [ -e /dev/block/platform/*/*/by-name/$part ]; then + target=/dev/block/platform/*/*/by-name/$part; + elif [ -e /dev/$part ]; then + target=/dev/$part; + fi; + test "$target" && break 2; + done; + done; + if [ "$target" ]; then + block=$(ls $target 2>/dev/null); + else + abort "Unable to determine $block partition. Aborting..."; + fi; + ;; + *) + if [ "$slot" ]; then + test -e "$block$slot" && block=$block$slot; + fi; + ;; + esac; +} +### + +### end methods + +setup_ak; diff --git a/anykernel_Ares/tools/busybox b/anykernel_Ares/tools/busybox index 67a60869..f6db6c0b 100755 Binary files a/anykernel_Ares/tools/busybox and b/anykernel_Ares/tools/busybox differ diff --git a/anykernel_Ares/tools/magiskboot b/anykernel_Ares/tools/magiskboot new file mode 100644 index 00000000..4d3e37a7 Binary files /dev/null and b/anykernel_Ares/tools/magiskboot differ diff --git a/anykernel_Ares/tools/magiskpolicy b/anykernel_Ares/tools/magiskpolicy new file mode 100644 index 00000000..2f37075e Binary files /dev/null and b/anykernel_Ares/tools/magiskpolicy differ diff --git a/arch/alpha/include/uapi/asm/Kbuild b/arch/alpha/include/uapi/asm/Kbuild new file mode 100644 index 00000000..baebb3da --- /dev/null +++ b/arch/alpha/include/uapi/asm/Kbuild @@ -0,0 +1,3 @@ +# UAPI Header export list +include include/uapi/asm-generic/Kbuild.asm + diff --git a/arch/arm/boot/dts/msm8974/msm8974-v2.dtsi b/arch/arm/boot/dts/msm8974/msm8974-v2.dtsi index 91844c3a..decd7001 100644 --- a/arch/arm/boot/dts/msm8974/msm8974-v2.dtsi +++ b/arch/arm/boot/dts/msm8974/msm8974-v2.dtsi @@ -104,7 +104,7 @@ &msm_vidc { qcom,vidc-ns-map = <0x40000000 0x40000000>; - qcom,load-freq-tbl = <979200 465000000>, + qcom,load-freq-tbl = <1036800 465000000>, <783360 465000000>, <489600 266670000>, <244800 133330000>; @@ -139,7 +139,7 @@ <1608000 604000>, <2576000 967000>, <4680000 1404000>, - <49880000 1496000>; + <4988000 1496000>; qcom,dec-ddr-ab-ib = <0 0>, <208000 303000>, <536000 1600000>, diff --git a/arch/arm/configs/Ares_@klte@_defconfig b/arch/arm/configs/Ares_@klte@_defconfig index 0f285890..c32ceca2 100644 --- a/arch/arm/configs/Ares_@klte@_defconfig +++ b/arch/arm/configs/Ares_@klte@_defconfig @@ -4135,24 +4135,7 @@ CONFIG_SENSORS_VFS61XX_KO=y # CONFIG_YAS532_FACTORY is not set # CONFIG_FELICA is not set # CONFIG_NFC_FELICA is not set -CONFIG_EXTCON=y - -# -# Extcon Device Drivers -# -# CONFIG_EXTCON_GPIO is not set -# CONFIG_EXTCON_ADC_JACK is not set -# CONFIG_EXTCON_FSA9485 is not set -# CONFIG_EXTCON_TSU6721 is not set -CONFIG_EXTCON_MAX77804K=y -# CONFIG_ADC_ONESHOT is not set -# CONFIG_MUIC_SUPPORT_AUDIO_DOCK is not set -# CONFIG_MUIC_SUPPORT_DESK_DOCK is not set -# CONFIG_MUIC_SUPPORT_SMART_DOCK is not set -# CONFIG_MUIC_SUPPORT_MMD_CTL is not set -# CONFIG_MUIC_SUPPORT_INCOMPATIBLE_CHARGER is not set -# CONFIG_MUIC_MAX77804K_SUPPORT_LANHUB is not set -# CONFIG_USBID_STANDARD is not set +# CONFIG_EXTCON is not set # # IRDA devices diff --git a/arch/arm/configs/Ares_@klteactivexx@_defconfig b/arch/arm/configs/Ares_@klteactivexx@_defconfig index abfab3dd..20dfa99a 100644 --- a/arch/arm/configs/Ares_@klteactivexx@_defconfig +++ b/arch/arm/configs/Ares_@klteactivexx@_defconfig @@ -4100,24 +4100,7 @@ CONFIG_SENSORS_SSP_MOBEAM=y # CONFIG_YAS532_FACTORY is not set # CONFIG_FELICA is not set # CONFIG_NFC_FELICA is not set -CONFIG_EXTCON=y - -# -# Extcon Device Drivers -# -# CONFIG_EXTCON_GPIO is not set -# CONFIG_EXTCON_ADC_JACK is not set -# CONFIG_EXTCON_FSA9485 is not set -# CONFIG_EXTCON_TSU6721 is not set -CONFIG_EXTCON_MAX77804K=y -# CONFIG_ADC_ONESHOT is not set -# CONFIG_MUIC_SUPPORT_AUDIO_DOCK is not set -# CONFIG_MUIC_SUPPORT_DESK_DOCK is not set -# CONFIG_MUIC_SUPPORT_SMART_DOCK is not set -# CONFIG_MUIC_SUPPORT_MMD_CTL is not set -# CONFIG_MUIC_SUPPORT_INCOMPATIBLE_CHARGER is not set -# CONFIG_MUIC_MAX77804K_SUPPORT_LANHUB is not set -# CONFIG_USBID_STANDARD is not set +# CONFIG_EXTCON is not set # # IRDA devices diff --git a/arch/arm/configs/Ares_@kltechn@_defconfig b/arch/arm/configs/Ares_@kltechn@_defconfig index 35966e1a..4d274d10 100644 --- a/arch/arm/configs/Ares_@kltechn@_defconfig +++ b/arch/arm/configs/Ares_@kltechn@_defconfig @@ -4104,24 +4104,7 @@ CONFIG_SENSORS_FPRINT_SECURE=y # CONFIG_YAS532_FACTORY is not set # CONFIG_FELICA is not set # CONFIG_NFC_FELICA is not set -CONFIG_EXTCON=y - -# -# Extcon Device Drivers -# -# CONFIG_EXTCON_GPIO is not set -# CONFIG_EXTCON_ADC_JACK is not set -# CONFIG_EXTCON_FSA9485 is not set -# CONFIG_EXTCON_TSU6721 is not set -CONFIG_EXTCON_MAX77804K=y -# CONFIG_ADC_ONESHOT is not set -# CONFIG_MUIC_SUPPORT_AUDIO_DOCK is not set -# CONFIG_MUIC_SUPPORT_DESK_DOCK is not set -# CONFIG_MUIC_SUPPORT_SMART_DOCK is not set -# CONFIG_MUIC_SUPPORT_MMD_CTL is not set -# CONFIG_MUIC_SUPPORT_INCOMPATIBLE_CHARGER is not set -# CONFIG_MUIC_MAX77804K_SUPPORT_LANHUB is not set -# CONFIG_USBID_STANDARD is not set +# CONFIG_EXTCON is not set # # IRDA devices diff --git a/arch/arm/configs/Ares_@kltechnduo@_defconfig b/arch/arm/configs/Ares_@kltechnduo@_defconfig index 17dd8150..fdec8375 100644 --- a/arch/arm/configs/Ares_@kltechnduo@_defconfig +++ b/arch/arm/configs/Ares_@kltechnduo@_defconfig @@ -4104,24 +4104,7 @@ CONFIG_SENSORS_FPRINT_SECURE=y # CONFIG_YAS532_FACTORY is not set # CONFIG_FELICA is not set # CONFIG_NFC_FELICA is not set -CONFIG_EXTCON=y - -# -# Extcon Device Drivers -# -# CONFIG_EXTCON_GPIO is not set -# CONFIG_EXTCON_ADC_JACK is not set -# CONFIG_EXTCON_FSA9485 is not set -# CONFIG_EXTCON_TSU6721 is not set -CONFIG_EXTCON_MAX77804K=y -# CONFIG_ADC_ONESHOT is not set -# CONFIG_MUIC_SUPPORT_AUDIO_DOCK is not set -# CONFIG_MUIC_SUPPORT_DESK_DOCK is not set -# CONFIG_MUIC_SUPPORT_SMART_DOCK is not set -# CONFIG_MUIC_SUPPORT_MMD_CTL is not set -# CONFIG_MUIC_SUPPORT_INCOMPATIBLE_CHARGER is not set -# CONFIG_MUIC_MAX77804K_SUPPORT_LANHUB is not set -# CONFIG_USBID_STANDARD is not set +# CONFIG_EXTCON is not set # # IRDA devices diff --git a/arch/arm/configs/Ares_@klteduos@_defconfig b/arch/arm/configs/Ares_@klteduos@_defconfig index 3acd90b1..d1d512ca 100644 --- a/arch/arm/configs/Ares_@klteduos@_defconfig +++ b/arch/arm/configs/Ares_@klteduos@_defconfig @@ -4135,24 +4135,7 @@ CONFIG_SENSORS_VFS61XX_KO=y # CONFIG_YAS532_FACTORY is not set # CONFIG_FELICA is not set # CONFIG_NFC_FELICA is not set -CONFIG_EXTCON=y - -# -# Extcon Device Drivers -# -# CONFIG_EXTCON_GPIO is not set -# CONFIG_EXTCON_ADC_JACK is not set -# CONFIG_EXTCON_FSA9485 is not set -# CONFIG_EXTCON_TSU6721 is not set -CONFIG_EXTCON_MAX77804K=y -# CONFIG_ADC_ONESHOT is not set -# CONFIG_MUIC_SUPPORT_AUDIO_DOCK is not set -# CONFIG_MUIC_SUPPORT_DESK_DOCK is not set -# CONFIG_MUIC_SUPPORT_SMART_DOCK is not set -# CONFIG_MUIC_SUPPORT_MMD_CTL is not set -# CONFIG_MUIC_SUPPORT_INCOMPATIBLE_CHARGER is not set -# CONFIG_MUIC_MAX77804K_SUPPORT_LANHUB is not set -# CONFIG_USBID_STANDARD is not set +# CONFIG_EXTCON is not set # # IRDA devices diff --git a/arch/arm/configs/Ares_@kltedv@_defconfig b/arch/arm/configs/Ares_@kltedv@_defconfig index edfbb2f8..bfb00f17 100644 --- a/arch/arm/configs/Ares_@kltedv@_defconfig +++ b/arch/arm/configs/Ares_@kltedv@_defconfig @@ -4136,24 +4136,7 @@ CONFIG_SENSORS_VFS61XX_KO=y # CONFIG_YAS532_FACTORY is not set # CONFIG_FELICA is not set # CONFIG_NFC_FELICA is not set -CONFIG_EXTCON=y - -# -# Extcon Device Drivers -# -# CONFIG_EXTCON_GPIO is not set -# CONFIG_EXTCON_ADC_JACK is not set -# CONFIG_EXTCON_FSA9485 is not set -# CONFIG_EXTCON_TSU6721 is not set -CONFIG_EXTCON_MAX77804K=y -# CONFIG_ADC_ONESHOT is not set -# CONFIG_MUIC_SUPPORT_AUDIO_DOCK is not set -# CONFIG_MUIC_SUPPORT_DESK_DOCK is not set -# CONFIG_MUIC_SUPPORT_SMART_DOCK is not set -# CONFIG_MUIC_SUPPORT_MMD_CTL is not set -# CONFIG_MUIC_SUPPORT_INCOMPATIBLE_CHARGER is not set -# CONFIG_MUIC_MAX77804K_SUPPORT_LANHUB is not set -# CONFIG_USBID_STANDARD is not set +# CONFIG_EXTCON is not set # # IRDA devices diff --git a/arch/arm/configs/Ares_@kltekdi@_defconfig b/arch/arm/configs/Ares_@kltekdi@_defconfig index 6bcde510..87c1b8be 100644 --- a/arch/arm/configs/Ares_@kltekdi@_defconfig +++ b/arch/arm/configs/Ares_@kltekdi@_defconfig @@ -4104,24 +4104,7 @@ CONFIG_SENSORS_VFS61XX_KO=y # CONFIG_YAS532_FACTORY is not set CONFIG_FELICA=y CONFIG_NFC_FELICA=y -CONFIG_EXTCON=y - -# -# Extcon Device Drivers -# -# CONFIG_EXTCON_GPIO is not set -# CONFIG_EXTCON_ADC_JACK is not set -# CONFIG_EXTCON_FSA9485 is not set -# CONFIG_EXTCON_TSU6721 is not set -CONFIG_EXTCON_MAX77804K=y -# CONFIG_ADC_ONESHOT is not set -# CONFIG_MUIC_SUPPORT_AUDIO_DOCK is not set -# CONFIG_MUIC_SUPPORT_DESK_DOCK is not set -# CONFIG_MUIC_SUPPORT_SMART_DOCK is not set -# CONFIG_MUIC_SUPPORT_MMD_CTL is not set -# CONFIG_MUIC_SUPPORT_INCOMPATIBLE_CHARGER is not set -# CONFIG_MUIC_MAX77804K_SUPPORT_LANHUB is not set -# CONFIG_USBID_STANDARD is not set +# CONFIG_EXTCON is not set # # IRDA devices diff --git a/arch/arm/configs/Ares_@kltekor@_defconfig b/arch/arm/configs/Ares_@kltekor@_defconfig index 5abe7031..2789f0a7 100644 --- a/arch/arm/configs/Ares_@kltekor@_defconfig +++ b/arch/arm/configs/Ares_@kltekor@_defconfig @@ -4133,24 +4133,7 @@ CONFIG_SENSORS_VFS61XX_KO=y # CONFIG_YAS532_FACTORY is not set # CONFIG_FELICA is not set # CONFIG_NFC_FELICA is not set -CONFIG_EXTCON=y - -# -# Extcon Device Drivers -# -# CONFIG_EXTCON_GPIO is not set -# CONFIG_EXTCON_ADC_JACK is not set -# CONFIG_EXTCON_FSA9485 is not set -# CONFIG_EXTCON_TSU6721 is not set -CONFIG_EXTCON_MAX77804K=y -# CONFIG_ADC_ONESHOT is not set -# CONFIG_MUIC_SUPPORT_AUDIO_DOCK is not set -# CONFIG_MUIC_SUPPORT_DESK_DOCK is not set -# CONFIG_MUIC_SUPPORT_SMART_DOCK is not set -# CONFIG_MUIC_SUPPORT_MMD_CTL is not set -# CONFIG_MUIC_SUPPORT_INCOMPATIBLE_CHARGER is not set -# CONFIG_MUIC_MAX77804K_SUPPORT_LANHUB is not set -# CONFIG_USBID_STANDARD is not set +# CONFIG_EXTCON is not set # # IRDA devices diff --git a/arch/arm/configs/Ares_@kltesprsports@_defconfig b/arch/arm/configs/Ares_@kltesprsports@_defconfig index 44059281..6ac867e6 100644 --- a/arch/arm/configs/Ares_@kltesprsports@_defconfig +++ b/arch/arm/configs/Ares_@kltesprsports@_defconfig @@ -4106,24 +4106,7 @@ CONFIG_SENSORS_SSP_MOBEAM=y # CONFIG_YAS532_FACTORY is not set # CONFIG_FELICA is not set # CONFIG_NFC_FELICA is not set -CONFIG_EXTCON=y - -# -# Extcon Device Drivers -# -# CONFIG_EXTCON_GPIO is not set -# CONFIG_EXTCON_ADC_JACK is not set -# CONFIG_EXTCON_FSA9485 is not set -# CONFIG_EXTCON_TSU6721 is not set -CONFIG_EXTCON_MAX77804K=y -# CONFIG_ADC_ONESHOT is not set -# CONFIG_MUIC_SUPPORT_AUDIO_DOCK is not set -# CONFIG_MUIC_SUPPORT_DESK_DOCK is not set -# CONFIG_MUIC_SUPPORT_SMART_DOCK is not set -# CONFIG_MUIC_SUPPORT_MMD_CTL is not set -# CONFIG_MUIC_SUPPORT_INCOMPATIBLE_CHARGER is not set -# CONFIG_MUIC_MAX77804K_SUPPORT_LANHUB is not set -# CONFIG_USBID_STANDARD is not set +# CONFIG_EXTCON is not set # # IRDA devices diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h index 21911d42..1d2edabc 100644 --- a/arch/arm/include/asm/unistd.h +++ b/arch/arm/include/asm/unistd.h @@ -406,6 +406,7 @@ #define __NR_process_vm_writev (__NR_SYSCALL_BASE+377) #define __NR_seccomp (__NR_SYSCALL_BASE+383) #define __NR_getrandom (__NR_SYSCALL_BASE+384) +#define __NR_memfd_create (__NR_SYSCALL_BASE+385) /* * The following SWIs are ARM private. diff --git a/arch/arm/include/uapi/asm/Kbuild b/arch/arm/include/uapi/asm/Kbuild new file mode 100644 index 00000000..baebb3da --- /dev/null +++ b/arch/arm/include/uapi/asm/Kbuild @@ -0,0 +1,3 @@ +# UAPI Header export list +include include/uapi/asm-generic/Kbuild.asm + diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index d76242b9..03f3c47f 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S @@ -394,6 +394,7 @@ CALL(sys_ni_syscall) CALL(sys_seccomp) CALL(sys_getrandom) +/* 385 */ CALL(sys_memfd_create) #ifndef syscalls_counted .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls #define syscalls_counted diff --git a/arch/arm/mach-msm/ipc_socket.c b/arch/arm/mach-msm/ipc_socket.c index f23f6083..c01736f9 100644 --- a/arch/arm/mach-msm/ipc_socket.c +++ b/arch/arm/mach-msm/ipc_socket.c @@ -518,13 +518,18 @@ static int msm_ipc_router_ioctl(struct socket *sock, ret = copy_to_user((void *)arg, &server_arg, sizeof(server_arg)); - if (srv_info_sz) { + + n = min(server_arg.num_entries_found, + server_arg.num_entries_in_array); + + if (ret == 0 && n) { ret = copy_to_user((void *)(arg + sizeof(server_arg)), - srv_info, srv_info_sz); - if (ret) - ret = -EFAULT; - kfree(srv_info); + srv_info, n * sizeof(*srv_info)); } + + if (ret) + ret = -EFAULT; + kfree(srv_info); break; case IPC_ROUTER_IOCTL_BIND_CONTROL_PORT: diff --git a/arch/arm/mach-msm/qdsp6v2/apr_tal.c b/arch/arm/mach-msm/qdsp6v2/apr_tal.c index 4443d64e..17bcec5a 100644 --- a/arch/arm/mach-msm/qdsp6v2/apr_tal.c +++ b/arch/arm/mach-msm/qdsp6v2/apr_tal.c @@ -280,7 +280,7 @@ static int __init apr_tal_init(void) ret = platform_driver_register(&apr_q6_driver); if (ret) goto err; - ret = platform_driver_register(&apr_modem_driver); + ret = platform_driver_register(&apr_modem_driver); if (ret) goto err_register; diff --git a/arch/arm64/include/uapi/asm/Kbuild b/arch/arm64/include/uapi/asm/Kbuild new file mode 100644 index 00000000..baebb3da --- /dev/null +++ b/arch/arm64/include/uapi/asm/Kbuild @@ -0,0 +1,3 @@ +# UAPI Header export list +include include/uapi/asm-generic/Kbuild.asm + diff --git a/arch/avr32/include/uapi/asm/Kbuild b/arch/avr32/include/uapi/asm/Kbuild new file mode 100644 index 00000000..baebb3da --- /dev/null +++ b/arch/avr32/include/uapi/asm/Kbuild @@ -0,0 +1,3 @@ +# UAPI Header export list +include include/uapi/asm-generic/Kbuild.asm + diff --git a/arch/blackfin/include/uapi/asm/Kbuild b/arch/blackfin/include/uapi/asm/Kbuild new file mode 100644 index 00000000..baebb3da --- /dev/null +++ b/arch/blackfin/include/uapi/asm/Kbuild @@ -0,0 +1,3 @@ +# UAPI Header export list +include include/uapi/asm-generic/Kbuild.asm + diff --git a/arch/c6x/include/uapi/asm/Kbuild b/arch/c6x/include/uapi/asm/Kbuild new file mode 100644 index 00000000..baebb3da --- /dev/null +++ b/arch/c6x/include/uapi/asm/Kbuild @@ -0,0 +1,3 @@ +# UAPI Header export list +include include/uapi/asm-generic/Kbuild.asm + diff --git a/arch/cris/include/uapi/arch-v10/arch/Kbuild b/arch/cris/include/uapi/arch-v10/arch/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/arch/cris/include/uapi/arch-v10/arch/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/arch/cris/include/uapi/arch-v32/arch/Kbuild b/arch/cris/include/uapi/arch-v32/arch/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/arch/cris/include/uapi/arch-v32/arch/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/arch/cris/include/uapi/asm/Kbuild b/arch/cris/include/uapi/asm/Kbuild new file mode 100644 index 00000000..f50236ae --- /dev/null +++ b/arch/cris/include/uapi/asm/Kbuild @@ -0,0 +1,5 @@ +# UAPI Header export list +include include/uapi/asm-generic/Kbuild.asm + +header-y += arch-v10/ +header-y += arch-v32/ diff --git a/arch/frv/include/uapi/asm/Kbuild b/arch/frv/include/uapi/asm/Kbuild new file mode 100644 index 00000000..baebb3da --- /dev/null +++ b/arch/frv/include/uapi/asm/Kbuild @@ -0,0 +1,3 @@ +# UAPI Header export list +include include/uapi/asm-generic/Kbuild.asm + diff --git a/arch/h8300/include/uapi/asm/Kbuild b/arch/h8300/include/uapi/asm/Kbuild new file mode 100644 index 00000000..baebb3da --- /dev/null +++ b/arch/h8300/include/uapi/asm/Kbuild @@ -0,0 +1,3 @@ +# UAPI Header export list +include include/uapi/asm-generic/Kbuild.asm + diff --git a/arch/hexagon/include/uapi/asm/Kbuild b/arch/hexagon/include/uapi/asm/Kbuild new file mode 100644 index 00000000..baebb3da --- /dev/null +++ b/arch/hexagon/include/uapi/asm/Kbuild @@ -0,0 +1,3 @@ +# UAPI Header export list +include include/uapi/asm-generic/Kbuild.asm + diff --git a/arch/ia64/include/uapi/asm/Kbuild b/arch/ia64/include/uapi/asm/Kbuild new file mode 100644 index 00000000..baebb3da --- /dev/null +++ b/arch/ia64/include/uapi/asm/Kbuild @@ -0,0 +1,3 @@ +# UAPI Header export list +include include/uapi/asm-generic/Kbuild.asm + diff --git a/arch/m32r/include/uapi/asm/Kbuild b/arch/m32r/include/uapi/asm/Kbuild new file mode 100644 index 00000000..baebb3da --- /dev/null +++ b/arch/m32r/include/uapi/asm/Kbuild @@ -0,0 +1,3 @@ +# UAPI Header export list +include include/uapi/asm-generic/Kbuild.asm + diff --git a/arch/m68k/include/uapi/asm/Kbuild b/arch/m68k/include/uapi/asm/Kbuild new file mode 100644 index 00000000..baebb3da --- /dev/null +++ b/arch/m68k/include/uapi/asm/Kbuild @@ -0,0 +1,3 @@ +# UAPI Header export list +include include/uapi/asm-generic/Kbuild.asm + diff --git a/arch/microblaze/include/uapi/asm/Kbuild b/arch/microblaze/include/uapi/asm/Kbuild new file mode 100644 index 00000000..baebb3da --- /dev/null +++ b/arch/microblaze/include/uapi/asm/Kbuild @@ -0,0 +1,3 @@ +# UAPI Header export list +include include/uapi/asm-generic/Kbuild.asm + diff --git a/arch/mips/include/uapi/asm/Kbuild b/arch/mips/include/uapi/asm/Kbuild new file mode 100644 index 00000000..baebb3da --- /dev/null +++ b/arch/mips/include/uapi/asm/Kbuild @@ -0,0 +1,3 @@ +# UAPI Header export list +include include/uapi/asm-generic/Kbuild.asm + diff --git a/arch/mn10300/include/uapi/asm/Kbuild b/arch/mn10300/include/uapi/asm/Kbuild new file mode 100644 index 00000000..baebb3da --- /dev/null +++ b/arch/mn10300/include/uapi/asm/Kbuild @@ -0,0 +1,3 @@ +# UAPI Header export list +include include/uapi/asm-generic/Kbuild.asm + diff --git a/arch/openrisc/include/uapi/asm/Kbuild b/arch/openrisc/include/uapi/asm/Kbuild new file mode 100644 index 00000000..baebb3da --- /dev/null +++ b/arch/openrisc/include/uapi/asm/Kbuild @@ -0,0 +1,3 @@ +# UAPI Header export list +include include/uapi/asm-generic/Kbuild.asm + diff --git a/arch/parisc/include/uapi/asm/Kbuild b/arch/parisc/include/uapi/asm/Kbuild new file mode 100644 index 00000000..baebb3da --- /dev/null +++ b/arch/parisc/include/uapi/asm/Kbuild @@ -0,0 +1,3 @@ +# UAPI Header export list +include include/uapi/asm-generic/Kbuild.asm + diff --git a/arch/powerpc/include/uapi/asm/Kbuild b/arch/powerpc/include/uapi/asm/Kbuild new file mode 100644 index 00000000..baebb3da --- /dev/null +++ b/arch/powerpc/include/uapi/asm/Kbuild @@ -0,0 +1,3 @@ +# UAPI Header export list +include include/uapi/asm-generic/Kbuild.asm + diff --git a/arch/s390/include/uapi/asm/Kbuild b/arch/s390/include/uapi/asm/Kbuild new file mode 100644 index 00000000..baebb3da --- /dev/null +++ b/arch/s390/include/uapi/asm/Kbuild @@ -0,0 +1,3 @@ +# UAPI Header export list +include include/uapi/asm-generic/Kbuild.asm + diff --git a/arch/score/include/uapi/asm/Kbuild b/arch/score/include/uapi/asm/Kbuild new file mode 100644 index 00000000..baebb3da --- /dev/null +++ b/arch/score/include/uapi/asm/Kbuild @@ -0,0 +1,3 @@ +# UAPI Header export list +include include/uapi/asm-generic/Kbuild.asm + diff --git a/arch/sh/include/uapi/asm/Kbuild b/arch/sh/include/uapi/asm/Kbuild new file mode 100644 index 00000000..baebb3da --- /dev/null +++ b/arch/sh/include/uapi/asm/Kbuild @@ -0,0 +1,3 @@ +# UAPI Header export list +include include/uapi/asm-generic/Kbuild.asm + diff --git a/arch/sparc/include/uapi/asm/Kbuild b/arch/sparc/include/uapi/asm/Kbuild new file mode 100644 index 00000000..7518ad28 --- /dev/null +++ b/arch/sparc/include/uapi/asm/Kbuild @@ -0,0 +1,5 @@ +# UAPI Header export list +# User exported sparc header files + +include include/uapi/asm-generic/Kbuild.asm + diff --git a/arch/tile/include/uapi/arch/Kbuild b/arch/tile/include/uapi/arch/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/arch/tile/include/uapi/arch/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/arch/tile/include/uapi/asm/Kbuild b/arch/tile/include/uapi/asm/Kbuild new file mode 100644 index 00000000..baebb3da --- /dev/null +++ b/arch/tile/include/uapi/asm/Kbuild @@ -0,0 +1,3 @@ +# UAPI Header export list +include include/uapi/asm-generic/Kbuild.asm + diff --git a/arch/unicore32/include/uapi/asm/Kbuild b/arch/unicore32/include/uapi/asm/Kbuild new file mode 100644 index 00000000..baebb3da --- /dev/null +++ b/arch/unicore32/include/uapi/asm/Kbuild @@ -0,0 +1,3 @@ +# UAPI Header export list +include include/uapi/asm-generic/Kbuild.asm + diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild index f9c0d3ba..1595d681 100644 --- a/arch/x86/include/asm/Kbuild +++ b/arch/x86/include/asm/Kbuild @@ -22,7 +22,3 @@ header-y += sigcontext32.h header-y += ucontext.h header-y += vm86.h header-y += vsyscall.h - -genhdr-y += unistd_32.h -genhdr-y += unistd_64.h -genhdr-y += unistd_x32.h diff --git a/arch/x86/include/uapi/asm/Kbuild b/arch/x86/include/uapi/asm/Kbuild new file mode 100644 index 00000000..83b6e9a0 --- /dev/null +++ b/arch/x86/include/uapi/asm/Kbuild @@ -0,0 +1,6 @@ +# UAPI Header export list +include include/uapi/asm-generic/Kbuild.asm + +genhdr-y += unistd_32.h +genhdr-y += unistd_64.h +genhdr-y += unistd_x32.h diff --git a/arch/x86/syscalls/Makefile b/arch/x86/syscalls/Makefile index 3236aebc..f325af26 100644 --- a/arch/x86/syscalls/Makefile +++ b/arch/x86/syscalls/Makefile @@ -1,7 +1,9 @@ out := $(obj)/../include/generated/asm +uapi := $(obj)/../include/generated/uapi/asm # Create output directory if not already present -_dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)') +_dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)') \ + $(shell [ -d '$(uapi)' ] || mkdir -p '$(uapi)') syscall32 := $(srctree)/$(src)/syscall_32.tbl syscall64 := $(srctree)/$(src)/syscall_64.tbl @@ -18,7 +20,7 @@ quiet_cmd_systbl = SYSTBL $@ cmd_systbl = $(CONFIG_SHELL) '$(systbl)' $< $@ syshdr_abi_unistd_32 := i386 -$(out)/unistd_32.h: $(syscall32) $(syshdr) +$(uapi)/unistd_32.h: $(syscall32) $(syshdr) $(call if_changed,syshdr) syshdr_abi_unistd_32_ia32 := i386 @@ -28,11 +30,11 @@ $(out)/unistd_32_ia32.h: $(syscall32) $(syshdr) syshdr_abi_unistd_x32 := common,x32 syshdr_offset_unistd_x32 := __X32_SYSCALL_BIT -$(out)/unistd_x32.h: $(syscall64) $(syshdr) +$(uapi)/unistd_x32.h: $(syscall64) $(syshdr) $(call if_changed,syshdr) syshdr_abi_unistd_64 := common,64 -$(out)/unistd_64.h: $(syscall64) $(syshdr) +$(uapi)/unistd_64.h: $(syscall64) $(syshdr) $(call if_changed,syshdr) syshdr_abi_unistd_64_x32 := x32 @@ -45,11 +47,12 @@ $(out)/syscalls_32.h: $(syscall32) $(systbl) $(out)/syscalls_64.h: $(syscall64) $(systbl) $(call if_changed,systbl) -syshdr-y += unistd_32.h unistd_64.h unistd_x32.h +uapisyshdr-y += unistd_32.h unistd_64.h unistd_x32.h syshdr-y += syscalls_32.h syshdr-$(CONFIG_X86_64) += unistd_32_ia32.h unistd_64_x32.h syshdr-$(CONFIG_X86_64) += syscalls_64.h -targets += $(syshdr-y) +targets += $(uapisyshdr-y) $(syshdr-y) -all: $(addprefix $(out)/,$(targets)) +all: $(addprefix $(uapi)/,$(uapisyshdr-y)) +all: $(addprefix $(out)/,$(syshdr-y)) diff --git a/arch/xtensa/include/uapi/asm/Kbuild b/arch/xtensa/include/uapi/asm/Kbuild new file mode 100644 index 00000000..baebb3da --- /dev/null +++ b/arch/xtensa/include/uapi/asm/Kbuild @@ -0,0 +1,3 @@ +# UAPI Header export list +include include/uapi/asm-generic/Kbuild.asm + diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 5fbf85d9..b102b2f4 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -475,7 +475,7 @@ static int test_aead(struct crypto_aead *tfm, int enc, ret = crypto_aead_setkey(tfm, key, template[i].klen); - if (!ret == template[i].fail) { + if (ret != template[i].fail) { printk(KERN_ERR "alg: aead: setkey failed on " "test %d for %s: flags=%x\n", j, algo, crypto_aead_get_flags(tfm)); @@ -565,7 +565,7 @@ static int test_aead(struct crypto_aead *tfm, int enc, key = template[i].key; ret = crypto_aead_setkey(tfm, key, template[i].klen); - if (!ret == template[i].fail) { + if (ret != template[i].fail) { printk(KERN_ERR "alg: aead: setkey failed on " "chunk test %d for %s: flags=%x\n", j, algo, crypto_aead_get_flags(tfm)); @@ -769,7 +769,7 @@ static int test_cipher(struct crypto_cipher *tfm, int enc, ret = crypto_cipher_setkey(tfm, template[i].key, template[i].klen); - if (!ret == template[i].fail) { + if (ret != template[i].fail) { printk(KERN_ERR "alg: cipher: setkey failed " "on test %d for %s: flags=%x\n", j, algo, crypto_cipher_get_flags(tfm)); @@ -865,7 +865,7 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc, ret = crypto_ablkcipher_setkey(tfm, template[i].key, template[i].klen); - if (!ret == template[i].fail) { + if (ret != template[i].fail) { printk(KERN_ERR "alg: skcipher: setkey failed " "on test %d for %s: flags=%x\n", j, algo, crypto_ablkcipher_get_flags(tfm)); @@ -929,7 +929,7 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc, ret = crypto_ablkcipher_setkey(tfm, template[i].key, template[i].klen); - if (!ret == template[i].fail) { + if (ret != template[i].fail) { printk(KERN_ERR "alg: skcipher: setkey failed " "on chunk test %d for %s: flags=%x\n", j, algo, diff --git a/crypto/testmgr.h b/crypto/testmgr.h index 16baa2c1..a07ab54c 100644 --- a/crypto/testmgr.h +++ b/crypto/testmgr.h @@ -45,7 +45,7 @@ struct hash_testvec { char *plaintext; char *digest; unsigned char tap[MAX_TAP]; - unsigned char psize; + unsigned short psize; unsigned char np; unsigned char ksize; }; diff --git a/drivers/base/power/boeffla_wl_blocker.h b/drivers/base/power/boeffla_wl_blocker.h index db20c4be..75f6a60e 100644 --- a/drivers/base/power/boeffla_wl_blocker.h +++ b/drivers/base/power/boeffla_wl_blocker.h @@ -18,5 +18,5 @@ #define LIST_WL_DEFAULT "qcom_rx_wakelock;wlan;wlan_wow_wl;wlan_extscan_wl;netmgr_wl;NETLINK;IPA_WS;[timerfd];wlan_ipa;wlan_pno_wl;wcnss_filter_lock" #define LENGTH_LIST_WL 255 -#define LENGTH_LIST_WL_DEFAULT 123 +#define LENGTH_LIST_WL_DEFAULT 124 #define LENGTH_LIST_WL_SEARCH LENGTH_LIST_WL + LENGTH_LIST_WL_DEFAULT + 5 diff --git a/drivers/battery/max77804k_charger.c b/drivers/battery/max77804k_charger.c index a44662a9..7b542977 100644 --- a/drivers/battery/max77804k_charger.c +++ b/drivers/battery/max77804k_charger.c @@ -1081,8 +1081,8 @@ static int sec_chg_set_property(struct power_supply *psy, set_charging_current < usb_charging_current) set_charging_current = usb_charging_current; - set_charging_current_max = - charger->charging_current_max; + set_charging_current_max = + charger->charging_current_max; #ifdef WPC_CHECK_CVPRM_FEATURE if (val->intval == POWER_SUPPLY_TYPE_WIRELESS) max77804k_check_cvprm(charger, 0x1C); diff --git a/drivers/extcon/extcon-max77804k.c b/drivers/extcon/extcon-max77804k.c index 9ecdf5c6..7fbd0184 100644 --- a/drivers/extcon/extcon-max77804k.c +++ b/drivers/extcon/extcon-max77804k.c @@ -194,7 +194,7 @@ static struct switch_dev switch_earjackkey = { }; #endif -static const char const *max77804k_path_name[] = { +static const char *max77804k_path_name[] = { [PATH_OPEN] = "OPEN", [PATH_USB_AP] = "USB-AP", [PATH_AUDIO] = "AUDIO", diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c index 325365f6..ee5419f3 100644 --- a/drivers/gpu/drm/drm_context.c +++ b/drivers/gpu/drm/drm_context.c @@ -321,19 +321,22 @@ int drm_addctx(struct drm_device *dev, void *data, { struct drm_ctx_list *ctx_entry; struct drm_ctx *ctx = data; + int tmp_handle; - ctx->handle = drm_ctxbitmap_next(dev); - if (ctx->handle == DRM_KERNEL_CONTEXT) { + tmp_handle = drm_ctxbitmap_next(dev); + if (tmp_handle == DRM_KERNEL_CONTEXT) { /* Skip kernel's context and get a new one. */ - ctx->handle = drm_ctxbitmap_next(dev); + tmp_handle = drm_ctxbitmap_next(dev); } - DRM_DEBUG("%d\n", ctx->handle); - if (ctx->handle == -1) { + DRM_DEBUG("%d\n", tmp_handle); + if (tmp_handle < 0) { DRM_DEBUG("Not enough free contexts.\n"); /* Should this return -EBUSY instead? */ - return -ENOMEM; + return tmp_handle; } + ctx->handle = tmp_handle; + ctx_entry = kmalloc(sizeof(*ctx_entry), GFP_KERNEL); if (!ctx_entry) { DRM_DEBUG("out of memory\n"); diff --git a/drivers/gpu/ion/ion_chunk_heap.c b/drivers/gpu/ion/ion_chunk_heap.c index b76f8982..e130d523 100644 --- a/drivers/gpu/ion/ion_chunk_heap.c +++ b/drivers/gpu/ion/ion_chunk_heap.c @@ -47,15 +47,15 @@ static int ion_chunk_heap_allocate(struct ion_heap *heap, struct scatterlist *sg; int ret, i; unsigned long num_chunks; + unsigned long allocated_size; if (ion_buffer_fault_user_mappings(buffer)) return -ENOMEM; - num_chunks = ALIGN(size, chunk_heap->chunk_size) / - chunk_heap->chunk_size; - buffer->size = num_chunks * chunk_heap->chunk_size; + allocated_size = ALIGN(size, chunk_heap->chunk_size); + num_chunks = allocated_size / chunk_heap->chunk_size; - if (buffer->size > chunk_heap->size - chunk_heap->allocated) + if (allocated_size > chunk_heap->size - chunk_heap->allocated) return -ENOMEM; table = kzalloc(sizeof(struct sg_table), GFP_KERNEL); @@ -78,7 +78,7 @@ static int ion_chunk_heap_allocate(struct ion_heap *heap, } buffer->priv_virt = table; - chunk_heap->allocated += buffer->size; + chunk_heap->allocated += allocated_size; return 0; err: sg = table->sgl; @@ -100,6 +100,9 @@ static void ion_chunk_heap_free(struct ion_buffer *buffer) struct sg_table *table = buffer->priv_virt; struct scatterlist *sg; int i; + unsigned long allocated_size; + + allocated_size = ALIGN(buffer->size, chunk_heap->chunk_size); ion_heap_buffer_zero(buffer); @@ -109,7 +112,7 @@ static void ion_chunk_heap_free(struct ion_buffer *buffer) gen_pool_free(chunk_heap->pool, page_to_phys(sg_page(sg)), sg_dma_len(sg)); } - chunk_heap->allocated -= buffer->size; + chunk_heap->allocated -= allocated_size; sg_free_table(table); kfree(table); } diff --git a/drivers/gpu/msm/z180.c b/drivers/gpu/msm/z180.c index ccd1eda5..6348e502 100644 --- a/drivers/gpu/msm/z180.c +++ b/drivers/gpu/msm/z180.c @@ -452,7 +452,7 @@ z180_cmdstream_issueibcmds(struct kgsl_device_private *dev_priv, "Cannot make kernel mapping for gpuaddr 0x%x\n", cmd); result = -EINVAL; - goto error; + goto error_put; } KGSL_CMD_INFO(device, "ctxt %d ibaddr 0x%08x sizedwords %d\n", @@ -481,7 +481,7 @@ z180_cmdstream_issueibcmds(struct kgsl_device_private *dev_priv, if (result < 0) { KGSL_CMD_ERR(device, "wait_event_interruptible_timeout " "failed: %ld\n", result); - goto error; + goto error_put; } result = 0; @@ -513,6 +513,8 @@ z180_cmdstream_issueibcmds(struct kgsl_device_private *dev_priv, z180_cmdwindow_write(device, ADDR_VGV3_CONTROL, cmd); z180_cmdwindow_write(device, ADDR_VGV3_CONTROL, 0); +error_put: + kgsl_mem_entry_put(entry); error: kgsl_trace_issueibcmds(device, context->id, cmdbatch, numibs, *timestamp, cmdbatch ? cmdbatch->flags : 0, result, 0); diff --git a/drivers/input/touchscreen/synaptics/synaptics_i2c_rmi.c b/drivers/input/touchscreen/synaptics/synaptics_i2c_rmi.c index 8816236f..43d10306 100644 --- a/drivers/input/touchscreen/synaptics/synaptics_i2c_rmi.c +++ b/drivers/input/touchscreen/synaptics/synaptics_i2c_rmi.c @@ -4108,9 +4108,10 @@ static void synaptics_rmi4_release_support_fn(struct synaptics_rmi4_data *rmi4_d dev_err(&rmi4_data->i2c_client->dev, "%s: support_fn_list is empty\n", __func__); #ifdef PROXIMITY - if (rmi4_data->f51_handle) + if (rmi4_data->f51_handle) { kfree(rmi4_data->f51_handle); rmi4_data->f51_handle = NULL; + } #endif return; } diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c index ade1bcfb..5f23bda2 100644 --- a/drivers/isdn/mISDN/socket.c +++ b/drivers/isdn/mISDN/socket.c @@ -764,6 +764,8 @@ base_sock_create(struct net *net, struct socket *sock, int protocol) if (sock->type != SOCK_RAW) return -ESOCKTNOSUPPORT; + if (!capable(CAP_NET_RAW)) + return -EPERM; sk = sk_alloc(net, PF_ISDN, GFP_KERNEL, &mISDN_proto); if (!sk) diff --git a/drivers/media/platform/msm/camera_ll/isp/msm_buf_mgr.c b/drivers/media/platform/msm/camera_ll/isp/msm_buf_mgr.c index 84a3e447..c2d3a7cf 100644 --- a/drivers/media/platform/msm/camera_ll/isp/msm_buf_mgr.c +++ b/drivers/media/platform/msm/camera_ll/isp/msm_buf_mgr.c @@ -462,11 +462,9 @@ static int msm_isp_buf_done(struct msm_isp_buf_mgr *buf_mgr, return rc; } } else { - buf_info->vb2_buf->v4l2_buf.timestamp = *tv; - buf_info->vb2_buf->v4l2_buf.sequence = frame_id; - buf_info->vb2_buf->v4l2_buf.reserved = output_format; buf_mgr->vb2_ops->buf_done(buf_info->vb2_buf, - bufq->session_id, bufq->stream_id); + bufq->session_id, bufq->stream_id, + frame_id, tv, output_format); } } diff --git a/drivers/media/platform/msm/camera_ll/msm.c b/drivers/media/platform/msm/camera_ll/msm.c index fa126c63..9c46baa8 100644 --- a/drivers/media/platform/msm/camera_ll/msm.c +++ b/drivers/media/platform/msm/camera_ll/msm.c @@ -136,7 +136,7 @@ typedef int (*msm_queue_find_func)(void *d1, void *d2); #define msm_queue_find(queue, type, member, func, data) ({\ unsigned long flags; \ struct msm_queue_head *__q = (queue); \ - type *node = 0; \ + type *node = NULL; \ typeof(node) __ret = NULL; \ msm_queue_find_func __f = (func); \ spin_lock_irqsave(&__q->lock, flags); \ @@ -234,21 +234,49 @@ void msm_delete_stream(unsigned int session_id, unsigned int stream_id) struct msm_session *session = NULL; struct msm_stream *stream = NULL; unsigned long flags; + int try_count = 0; session = msm_queue_find(msm_session_q, struct msm_session, list, __msm_queue_find_session, &session_id); + if (!session) return; - stream = msm_queue_find(&session->stream_q, struct msm_stream, - list, __msm_queue_find_stream, &stream_id); - if (!stream) - return; - spin_lock_irqsave(&(session->stream_q.lock), flags); - list_del_init(&stream->list); - session->stream_q.len--; - spin_unlock_irqrestore(&(session->stream_q.lock), flags); - kzfree(stream); + while (1) { + unsigned long wl_flags; + + if (try_count > 5) { + pr_err("%s : not able to delete stream %d\n", + __func__, __LINE__); + break; + } + + write_lock_irqsave(&session->stream_rwlock, wl_flags); + try_count++; + stream = msm_queue_find(&session->stream_q, struct msm_stream, + list, __msm_queue_find_stream, &stream_id); + + if (!stream) { + write_unlock_irqrestore(&session->stream_rwlock, + wl_flags); + return; + } + + if (msm_vb2_get_stream_state(stream) != 1) { + write_unlock_irqrestore(&session->stream_rwlock, + wl_flags); + continue; + } + + spin_lock_irqsave(&(session->stream_q.lock), flags); + list_del_init(&stream->list); + session->stream_q.len--; + kzfree(stream); + stream = NULL; + spin_unlock_irqrestore(&(session->stream_q.lock), flags); + write_unlock_irqrestore(&session->stream_rwlock, wl_flags); + break; + } } static void msm_sd_unregister_subdev(struct video_device *vdev) @@ -399,6 +427,7 @@ int msm_create_session(unsigned int session_id, struct video_device *vdev) msm_init_queue(&session->stream_q); msm_enqueue(msm_session_q, &session->list); mutex_init(&session->lock); + rwlock_init(&session->stream_rwlock); pr_warn("msm_create_session : Succeed!, session_id %d", session_id); return 0; @@ -895,11 +924,9 @@ static struct v4l2_file_operations msm_fops = { .ioctl = video_ioctl2, }; -struct msm_stream *msm_get_stream(unsigned int session_id, - unsigned int stream_id) +struct msm_session *msm_get_session(unsigned int session_id) { struct msm_session *session; - struct msm_stream *stream; session = msm_queue_find(msm_session_q, struct msm_session, list, __msm_queue_find_session, &session_id); @@ -908,6 +935,16 @@ struct msm_stream *msm_get_stream(unsigned int session_id, return ERR_PTR(-EINVAL); } + return session; +} +EXPORT_SYMBOL(msm_get_session); + + +struct msm_stream *msm_get_stream(struct msm_session *session, + unsigned int stream_id) +{ + struct msm_stream *stream; + stream = msm_queue_find(&session->stream_q, struct msm_stream, list, __msm_queue_find_stream, &stream_id); @@ -942,6 +979,33 @@ struct vb2_queue *msm_get_stream_vb2q(unsigned int session_id, return stream->vb2_q; } +struct msm_session *msm_get_session_from_vb2q(struct vb2_queue *q) +{ + struct msm_session *session; + struct msm_stream *stream; + unsigned long flags1; + unsigned long flags2; + + spin_lock_irqsave(&msm_session_q->lock, flags1); + list_for_each_entry(session, &(msm_session_q->list), list) { + spin_lock_irqsave(&(session->stream_q.lock), flags2); + list_for_each_entry( + stream, &(session->stream_q.list), list) { + if (stream->vb2_q == q) { + spin_unlock_irqrestore + (&(session->stream_q.lock), flags2); + spin_unlock_irqrestore + (&msm_session_q->lock, flags1); + return session; + } + } + spin_unlock_irqrestore(&(session->stream_q.lock), flags2); + } + spin_unlock_irqrestore(&msm_session_q->lock, flags1); + return NULL; +} +EXPORT_SYMBOL(msm_get_session_from_vb2q); + struct msm_stream *msm_get_stream_from_vb2q(struct vb2_queue *q) { struct msm_session *session; diff --git a/drivers/media/platform/msm/camera_ll/msm.h b/drivers/media/platform/msm/camera_ll/msm.h index 63c1a11e..fd393d38 100644 --- a/drivers/media/platform/msm/camera_ll/msm.h +++ b/drivers/media/platform/msm/camera_ll/msm.h @@ -100,6 +100,7 @@ struct msm_session { * session struct msm_stream */ struct msm_queue_head stream_q; struct mutex lock; + rwlock_t stream_rwlock; }; int msm_cam_get_module_init_status(void); @@ -113,10 +114,12 @@ int msm_create_stream(unsigned int session_id, void msm_delete_stream(unsigned int session_id, unsigned int stream_id); int msm_create_command_ack_q(unsigned int session_id, unsigned int stream_id); void msm_delete_command_ack_q(unsigned int session_id, unsigned int stream_id); -struct msm_stream *msm_get_stream(unsigned int session_id, +struct msm_session *msm_get_session(unsigned int session_id); +struct msm_stream *msm_get_stream(struct msm_session *session, unsigned int stream_id); struct vb2_queue *msm_get_stream_vb2q(unsigned int session_id, unsigned int stream_id); struct msm_stream *msm_get_stream_from_vb2q(struct vb2_queue *q); +struct msm_session *msm_get_session_from_vb2q(struct vb2_queue *q); struct msm_session *msm_session_find(unsigned int session_id); #endif /*_MSM_H */ diff --git a/drivers/media/platform/msm/camera_ll/msm_buf_mgr/msm_generic_buf_mgr.c b/drivers/media/platform/msm/camera_ll/msm_buf_mgr/msm_generic_buf_mgr.c index 7a7e4658..142e02ad 100644 --- a/drivers/media/platform/msm/camera_ll/msm_buf_mgr/msm_generic_buf_mgr.c +++ b/drivers/media/platform/msm/camera_ll/msm_buf_mgr/msm_generic_buf_mgr.c @@ -41,6 +41,7 @@ static int msm_buf_mngr_get_buf(struct msm_buf_mngr_device *buf_mngr_dev, } new_entry->session_id = buf_info->session_id; new_entry->stream_id = buf_info->stream_id; + new_entry->index = new_entry->vb2_buf->v4l2_buf.index; spin_lock_irqsave(&buf_mngr_dev->buf_q_spinlock, flags); list_add_tail(&new_entry->entry, &buf_mngr_dev->buf_qhead); spin_unlock_irqrestore(&buf_mngr_dev->buf_q_spinlock, flags); @@ -64,14 +65,14 @@ static int msm_buf_mngr_buf_done(struct msm_buf_mngr_device *buf_mngr_dev, list_for_each_entry_safe(bufs, save, &buf_mngr_dev->buf_qhead, entry) { if ((bufs->session_id == buf_info->session_id) && (bufs->stream_id == buf_info->stream_id) && - (bufs->vb2_buf->v4l2_buf.index == buf_info->index)) { - bufs->vb2_buf->v4l2_buf.sequence = buf_info->frame_id; - bufs->vb2_buf->v4l2_buf.timestamp = buf_info->timestamp; - bufs->vb2_buf->v4l2_buf.reserved = 0; + (bufs->index == buf_info->index)) { ret = buf_mngr_dev->vb2_ops.buf_done (bufs->vb2_buf, buf_info->session_id, - buf_info->stream_id); + buf_info->stream_id, + buf_info->frame_id, + &buf_info->timestamp, + 0); list_del_init(&bufs->entry); kfree(bufs); break; @@ -93,7 +94,7 @@ static int msm_buf_mngr_put_buf(struct msm_buf_mngr_device *buf_mngr_dev, list_for_each_entry_safe(bufs, save, &buf_mngr_dev->buf_qhead, entry) { if ((bufs->session_id == buf_info->session_id) && (bufs->stream_id == buf_info->stream_id) && - (bufs->vb2_buf->v4l2_buf.index == buf_info->index)) { + (bufs->index == buf_info->index)) { ret = buf_mngr_dev->vb2_ops.put_buf(bufs->vb2_buf, buf_info->session_id, buf_info->stream_id); list_del_init(&bufs->entry); diff --git a/drivers/media/platform/msm/camera_ll/msm_buf_mgr/msm_generic_buf_mgr.h b/drivers/media/platform/msm/camera_ll/msm_buf_mgr/msm_generic_buf_mgr.h index 49fad229..9d4ebcfc 100644 --- a/drivers/media/platform/msm/camera_ll/msm_buf_mgr/msm_generic_buf_mgr.h +++ b/drivers/media/platform/msm/camera_ll/msm_buf_mgr/msm_generic_buf_mgr.h @@ -29,6 +29,7 @@ struct msm_get_bufs { struct vb2_buffer *vb2_buf; uint32_t session_id; uint32_t stream_id; + uint32_t index; }; struct msm_buf_mngr_device { diff --git a/drivers/media/platform/msm/camera_ll/msm_sd.h b/drivers/media/platform/msm/camera_ll/msm_sd.h index 7c1519dd..72793a67 100644 --- a/drivers/media/platform/msm/camera_ll/msm_sd.h +++ b/drivers/media/platform/msm/camera_ll/msm_sd.h @@ -70,7 +70,8 @@ struct msm_sd_req_vb2_q { int (*put_buf)(struct vb2_buffer *vb2_buf, int session_id, unsigned int stream_id); int (*buf_done)(struct vb2_buffer *vb2_buf, int session_id, - unsigned int stream_id); + unsigned int stream_id, uint32_t sequence, struct timeval *ts, + uint32_t reserved); }; #define MSM_SD_NOTIFY_GET_SD 0x00000001 diff --git a/drivers/media/platform/msm/camera_ll/msm_vb2/msm_vb2.c b/drivers/media/platform/msm/camera_ll/msm_vb2/msm_vb2.c index 67ce4ca7..c1e0da22 100644 --- a/drivers/media/platform/msm/camera_ll/msm_vb2/msm_vb2.c +++ b/drivers/media/platform/msm/camera_ll/msm_vb2/msm_vb2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -10,6 +10,7 @@ * GNU General Public License for more details. */ +#define pr_fmt(fmt) "CAM-VB2 %s:%d " fmt, __func__, __LINE__ #include "msm_vb2.h" static int msm_vb2_queue_setup(struct vb2_queue *q, @@ -39,16 +40,25 @@ static int msm_vb2_queue_setup(struct vb2_queue *q, int msm_vb2_buf_init(struct vb2_buffer *vb) { struct msm_stream *stream; + struct msm_session *session; struct msm_vb2_buffer *msm_vb2_buf; + unsigned long rl_flags; + + session = msm_get_session_from_vb2q(vb->vb2_queue); + if (IS_ERR_OR_NULL(session)) + return -EINVAL; + + read_lock_irqsave(&session->stream_rwlock, rl_flags); stream = msm_get_stream_from_vb2q(vb->vb2_queue); if (!stream) { pr_err("%s: Couldn't find stream\n", __func__); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return -EINVAL; } msm_vb2_buf = container_of(vb, struct msm_vb2_buffer, vb2_buf); msm_vb2_buf->in_freeq = 0; - + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return 0; } @@ -56,7 +66,8 @@ static void msm_vb2_buf_queue(struct vb2_buffer *vb) { struct msm_vb2_buffer *msm_vb2; struct msm_stream *stream; - unsigned long flags; + struct msm_session *session; + unsigned long flags, rl_flags; msm_vb2 = container_of(vb, struct msm_vb2_buffer, vb2_buf); @@ -65,22 +76,31 @@ static void msm_vb2_buf_queue(struct vb2_buffer *vb) return; } + session = msm_get_session_from_vb2q(vb->vb2_queue); + if (IS_ERR_OR_NULL(session)) + return; + + read_lock_irqsave(&session->stream_rwlock, rl_flags); + stream = msm_get_stream_from_vb2q(vb->vb2_queue); if (!stream) { pr_err("%s:%d] NULL stream", __func__, __LINE__); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return; } spin_lock_irqsave(&stream->stream_lock, flags); list_add_tail(&msm_vb2->list, &stream->queued_list); spin_unlock_irqrestore(&stream->stream_lock, flags); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); } static int msm_vb2_buf_finish(struct vb2_buffer *vb) { struct msm_vb2_buffer *msm_vb2; struct msm_stream *stream; - unsigned long flags; + struct msm_session *session; + unsigned long flags, rl_flags; struct msm_vb2_buffer *msm_vb2_entry, *temp; msm_vb2 = container_of(vb, struct msm_vb2_buffer, vb2_buf); @@ -90,9 +110,16 @@ static int msm_vb2_buf_finish(struct vb2_buffer *vb) return -EINVAL; } + session = msm_get_session_from_vb2q(vb->vb2_queue); + if (IS_ERR_OR_NULL(session)) + return -EINVAL; + + read_lock_irqsave(&session->stream_rwlock, rl_flags); + stream = msm_get_stream_from_vb2q(vb->vb2_queue); if (!stream) { pr_err("%s:%d] NULL stream", __func__, __LINE__); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return -EINVAL; } @@ -105,6 +132,7 @@ static int msm_vb2_buf_finish(struct vb2_buffer *vb) } } spin_unlock_irqrestore(&stream->stream_lock, flags); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return 0; } @@ -123,7 +151,7 @@ static void msm_vb2_buf_cleanup(struct vb2_buffer *vb) stream = msm_get_stream_from_vb2q(vb->vb2_queue); if (!stream) { - pr_err("%s:%d] NULL stream", __func__, __LINE__); + pr_err_ratelimited("%s:%d] NULL stream", __func__, __LINE__); return; } @@ -132,6 +160,24 @@ static void msm_vb2_buf_cleanup(struct vb2_buffer *vb) spin_unlock_irqrestore(&stream->stream_lock, flags); } +int msm_vb2_get_stream_state(struct msm_stream *stream) +{ + struct msm_vb2_buffer *msm_vb2, *temp; + unsigned long flags; + int rc = 1; + + spin_lock_irqsave(&stream->stream_lock, flags); + list_for_each_entry_safe(msm_vb2, temp, &(stream->queued_list), list) { + if (msm_vb2->in_freeq != 0) { + rc = 0; + break; + } + } + spin_unlock_irqrestore(&stream->stream_lock, flags); + return rc; +} + + static struct vb2_ops msm_vb2_get_q_op = { .queue_setup = msm_vb2_queue_setup, .buf_init = msm_vb2_buf_init, @@ -185,13 +231,22 @@ static struct vb2_buffer *msm_vb2_get_buf(int session_id, { struct msm_stream *stream; struct vb2_buffer *vb2_buf = NULL; + struct msm_session *session; struct msm_vb2_buffer *msm_vb2 = NULL; - unsigned long flags; + unsigned long flags, rl_flags; - stream = msm_get_stream(session_id, stream_id); - if (IS_ERR_OR_NULL(stream)) + session = msm_get_session(session_id); + if (IS_ERR_OR_NULL(session)) return NULL; + read_lock_irqsave(&session->stream_rwlock, rl_flags); + + stream = msm_get_stream(session, stream_id); + if (IS_ERR_OR_NULL(stream)) { + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); + return NULL; + } + spin_lock_irqsave(&stream->stream_lock, flags); if (!stream->vb2_q) { @@ -214,6 +269,7 @@ static struct vb2_buffer *msm_vb2_get_buf(int session_id, vb2_buf = NULL; end: spin_unlock_irqrestore(&stream->stream_lock, flags); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return vb2_buf; } @@ -221,12 +277,22 @@ static int msm_vb2_put_buf(struct vb2_buffer *vb, int session_id, unsigned int stream_id) { struct msm_stream *stream; + struct msm_session *session; struct msm_vb2_buffer *msm_vb2; int rc = 0; - unsigned long flags; - stream = msm_get_stream(session_id, stream_id); - if (IS_ERR_OR_NULL(stream)) + unsigned long flags, rl_flags; + + session = msm_get_session(session_id); + if (IS_ERR_OR_NULL(session)) + return -EINVAL; + + read_lock_irqsave(&session->stream_rwlock, rl_flags); + + stream = msm_get_stream(session, stream_id); + if (IS_ERR_OR_NULL(stream)) { + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return -EINVAL; + } spin_lock_irqsave(&stream->stream_lock, flags); if (vb) { @@ -242,21 +308,33 @@ static int msm_vb2_put_buf(struct vb2_buffer *vb, int session_id, rc = -EINVAL; } spin_unlock_irqrestore(&stream->stream_lock, flags); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return rc; } static int msm_vb2_buf_done(struct vb2_buffer *vb, int session_id, - unsigned int stream_id) + unsigned int stream_id, uint32_t sequence, + struct timeval *ts, uint32_t reserved) { - unsigned long flags; + unsigned long flags, rl_flags; struct msm_vb2_buffer *msm_vb2; struct msm_stream *stream; + struct msm_session *session; struct vb2_buffer *vb2_buf = NULL; int rc = 0; - stream = msm_get_stream(session_id, stream_id); - if (IS_ERR_OR_NULL(stream)) - return 0; + session = msm_get_session(session_id); + if (IS_ERR_OR_NULL(session)) + return -EINVAL; + + read_lock_irqsave(&session->stream_rwlock, rl_flags); + + stream = msm_get_stream(session, stream_id); + if (IS_ERR_OR_NULL(stream)) { + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); + return -EINVAL; + } + spin_lock_irqsave(&stream->stream_lock, flags); if (vb) { list_for_each_entry(msm_vb2, &(stream->queued_list), list) { @@ -273,6 +351,9 @@ static int msm_vb2_buf_done(struct vb2_buffer *vb, int session_id, container_of(vb, struct msm_vb2_buffer, vb2_buf); /* put buf before buf done */ if (msm_vb2->in_freeq) { + vb->v4l2_buf.sequence = sequence; + vb->v4l2_buf.timestamp = *ts; + vb->v4l2_buf.reserved = reserved; vb2_buffer_done(vb, VB2_BUF_STATE_DONE); msm_vb2->in_freeq = 0; rc = 0; @@ -284,6 +365,7 @@ static int msm_vb2_buf_done(struct vb2_buffer *vb, int session_id, } out: spin_unlock_irqrestore(&stream->stream_lock, flags); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return rc; } diff --git a/drivers/media/platform/msm/camera_ll/msm_vb2/msm_vb2.h b/drivers/media/platform/msm/camera_ll/msm_vb2/msm_vb2.h index 7082f858..ff1a0004 100644 --- a/drivers/media/platform/msm/camera_ll/msm_vb2/msm_vb2.h +++ b/drivers/media/platform/msm/camera_ll/msm_vb2/msm_vb2.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -66,5 +66,6 @@ struct msm_stream { struct vb2_ops *msm_vb2_get_q_ops(void); struct vb2_mem_ops *msm_vb2_get_q_mem_ops(void); int msm_vb2_request_cb(struct msm_sd_req_vb2_q *req_sd); +int msm_vb2_get_stream_state(struct msm_stream *stream); #endif /*_MSM_VB_H */ diff --git a/drivers/media/platform/msm/camera_ll/sensor/io/msm_camera_io_util.c b/drivers/media/platform/msm/camera_ll/sensor/io/msm_camera_io_util.c index 77ab397e..9ab34751 100644 --- a/drivers/media/platform/msm/camera_ll/sensor/io/msm_camera_io_util.c +++ b/drivers/media/platform/msm/camera_ll/sensor/io/msm_camera_io_util.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2013, The Linux Foundataion. All rights reserved. +/* Copyright (c) 2011-2013, 2019 The Linux Foundataion. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -125,12 +125,8 @@ int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info, { int i; int rc = 0; - int qctkd = 0; long clk_rate; - if (num_clk == 8) //CPP use case - qctkd = 1; - if (enable) { for (i = 0; i < num_clk; i++) { CDBG("%s enable %s\n", __func__, @@ -187,18 +183,17 @@ int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info, usleep_range(clk_info[i].delay * 1000, (clk_info[i].delay * 1000) + 1000); } - if (qctkd) printk (KERN_ERR "QCTKD: %s[%d:%d] Enable \n", clk_info[i].clk_name, clk_ptr[i]->prepare_count, clk_ptr[i]->count); } } else { for (i = num_clk - 1; i >= 0; i--) { - if (clk_ptr[i] != NULL) { + if (!IS_ERR_OR_NULL(clk_ptr[i])) { CDBG("%s disable %s\n", __func__, clk_info[i].clk_name); clk_disable(clk_ptr[i]); clk_unprepare(clk_ptr[i]); clk_put(clk_ptr[i]); + clk_ptr[i] = NULL; } - if (qctkd) printk (KERN_ERR "QCTKD: %s[%d:%d] Disable\n", clk_info[i].clk_name, clk_ptr[i]->prepare_count, clk_ptr[i]->count); } } return rc; @@ -211,10 +206,11 @@ int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info, clk_put(clk_ptr[i]); cam_clk_get_err: for (i--; i >= 0; i--) { - if (clk_ptr[i] != NULL) { + if (!IS_ERR_OR_NULL(clk_ptr[i])) { clk_disable(clk_ptr[i]); clk_unprepare(clk_ptr[i]); clk_put(clk_ptr[i]); + clk_ptr[i] = NULL; } } return rc; diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c index f3681520..e579ca30 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c @@ -528,11 +528,9 @@ static int msm_isp_buf_done(struct msm_isp_buf_mgr *buf_mgr, return rc; } } else { - buf_info->vb2_buf->v4l2_buf.timestamp = *tv; - buf_info->vb2_buf->v4l2_buf.sequence = frame_id; - buf_info->vb2_buf->v4l2_buf.reserved = output_format; buf_mgr->vb2_ops->buf_done(buf_info->vb2_buf, - bufq->session_id, bufq->stream_id); + bufq->session_id, bufq->stream_id, + frame_id, tv, output_format); } } diff --git a/drivers/media/platform/msm/camera_v2/msm.c b/drivers/media/platform/msm/camera_v2/msm.c index a1fa384d..312090f7 100644 --- a/drivers/media/platform/msm/camera_v2/msm.c +++ b/drivers/media/platform/msm/camera_v2/msm.c @@ -137,7 +137,7 @@ typedef int (*msm_queue_find_func)(void *d1, void *d2); #define msm_queue_find(queue, type, member, func, data) ({\ unsigned long flags; \ struct msm_queue_head *__q = (queue); \ - type *node = 0; \ + type *node = NULL; \ typeof(node) __ret = NULL; \ msm_queue_find_func __f = (func); \ spin_lock_irqsave(&__q->lock, flags); \ @@ -240,21 +240,50 @@ void msm_delete_stream(unsigned int session_id, unsigned int stream_id) struct msm_session *session = NULL; struct msm_stream *stream = NULL; unsigned long flags; + int try_count = 0; session = msm_queue_find(msm_session_q, struct msm_session, list, __msm_queue_find_session, &session_id); + if (!session) return; - stream = msm_queue_find(&session->stream_q, struct msm_stream, - list, __msm_queue_find_stream, &stream_id); - if (!stream) - return; - spin_lock_irqsave(&(session->stream_q.lock), flags); - list_del_init(&stream->list); - session->stream_q.len--; - spin_unlock_irqrestore(&(session->stream_q.lock), flags); - kzfree(stream); + while (1) { + unsigned long wl_flags; + + if (try_count > 5) { + pr_err("%s : not able to delete stream %d\n", + __func__, __LINE__); + break; + } + + write_lock_irqsave(&session->stream_rwlock, wl_flags); + try_count++; + stream = msm_queue_find(&session->stream_q, struct msm_stream, + list, __msm_queue_find_stream, &stream_id); + + if (!stream) { + write_unlock_irqrestore(&session->stream_rwlock, + wl_flags); + return; + } + + if (msm_vb2_get_stream_state(stream) != 1) { + write_unlock_irqrestore(&session->stream_rwlock, + wl_flags); + continue; + } + + spin_lock_irqsave(&(session->stream_q.lock), flags); + list_del_init(&stream->list); + session->stream_q.len--; + kzfree(stream); + stream = NULL; + spin_unlock_irqrestore(&(session->stream_q.lock), flags); + write_unlock_irqrestore(&session->stream_rwlock, wl_flags); + break; + } + } static void msm_sd_unregister_subdev(struct video_device *vdev) @@ -407,6 +436,7 @@ int msm_create_session(unsigned int session_id, struct video_device *vdev) msm_init_queue(&session->stream_q); msm_enqueue(msm_session_q, &session->list); mutex_init(&session->lock); + rwlock_init(&session->stream_rwlock); pr_warn("msm_create_session : Succeed!, session_id %d", session_id); return 0; @@ -914,11 +944,9 @@ static struct v4l2_file_operations msm_fops = { .ioctl = video_ioctl2, }; -struct msm_stream *msm_get_stream(unsigned int session_id, - unsigned int stream_id) +struct msm_session *msm_get_session(unsigned int session_id) { struct msm_session *session; - struct msm_stream *stream; session = msm_queue_find(msm_session_q, struct msm_session, list, __msm_queue_find_session, &session_id); @@ -927,6 +955,16 @@ struct msm_stream *msm_get_stream(unsigned int session_id, return ERR_PTR(-EINVAL); } + return session; +} +EXPORT_SYMBOL(msm_get_session); + + +struct msm_stream *msm_get_stream(struct msm_session *session, + unsigned int stream_id) +{ + struct msm_stream *stream; + stream = msm_queue_find(&session->stream_q, struct msm_stream, list, __msm_queue_find_stream, &stream_id); @@ -961,6 +999,33 @@ struct vb2_queue *msm_get_stream_vb2q(unsigned int session_id, return stream->vb2_q; } +struct msm_session *msm_get_session_from_vb2q(struct vb2_queue *q) +{ + struct msm_session *session; + struct msm_stream *stream; + unsigned long flags1; + unsigned long flags2; + + spin_lock_irqsave(&msm_session_q->lock, flags1); + list_for_each_entry(session, &(msm_session_q->list), list) { + spin_lock_irqsave(&(session->stream_q.lock), flags2); + list_for_each_entry( + stream, &(session->stream_q.list), list) { + if (stream->vb2_q == q) { + spin_unlock_irqrestore + (&(session->stream_q.lock), flags2); + spin_unlock_irqrestore + (&msm_session_q->lock, flags1); + return session; + } + } + spin_unlock_irqrestore(&(session->stream_q.lock), flags2); + } + spin_unlock_irqrestore(&msm_session_q->lock, flags1); + return NULL; +} +EXPORT_SYMBOL(msm_get_session_from_vb2q); + struct msm_stream *msm_get_stream_from_vb2q(struct vb2_queue *q) { struct msm_session *session; diff --git a/drivers/media/platform/msm/camera_v2/msm.h b/drivers/media/platform/msm/camera_v2/msm.h index 3944d452..b5009957 100644 --- a/drivers/media/platform/msm/camera_v2/msm.h +++ b/drivers/media/platform/msm/camera_v2/msm.h @@ -100,6 +100,7 @@ struct msm_session { * session struct msm_stream */ struct msm_queue_head stream_q; struct mutex lock; + rwlock_t stream_rwlock; }; int msm_cam_get_module_init_status(void); @@ -113,10 +114,12 @@ int msm_create_stream(unsigned int session_id, void msm_delete_stream(unsigned int session_id, unsigned int stream_id); int msm_create_command_ack_q(unsigned int session_id, unsigned int stream_id); void msm_delete_command_ack_q(unsigned int session_id, unsigned int stream_id); -struct msm_stream *msm_get_stream(unsigned int session_id, +struct msm_session *msm_get_session(unsigned int session_id); +struct msm_stream *msm_get_stream(struct msm_session *session, unsigned int stream_id); struct vb2_queue *msm_get_stream_vb2q(unsigned int session_id, unsigned int stream_id); struct msm_stream *msm_get_stream_from_vb2q(struct vb2_queue *q); +struct msm_session *msm_get_session_from_vb2q(struct vb2_queue *q); struct msm_session *msm_session_find(unsigned int session_id); #endif /*_MSM_H */ diff --git a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c index 2aac8be4..844c0f83 100644 --- a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c +++ b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c @@ -41,6 +41,7 @@ static int msm_buf_mngr_get_buf(struct msm_buf_mngr_device *buf_mngr_dev, } new_entry->session_id = buf_info->session_id; new_entry->stream_id = buf_info->stream_id; + new_entry->index = new_entry->vb2_buf->v4l2_buf.index; spin_lock_irqsave(&buf_mngr_dev->buf_q_spinlock, flags); list_add_tail(&new_entry->entry, &buf_mngr_dev->buf_qhead); spin_unlock_irqrestore(&buf_mngr_dev->buf_q_spinlock, flags); @@ -59,14 +60,14 @@ static int msm_buf_mngr_buf_done(struct msm_buf_mngr_device *buf_mngr_dev, list_for_each_entry_safe(bufs, save, &buf_mngr_dev->buf_qhead, entry) { if ((bufs->session_id == buf_info->session_id) && (bufs->stream_id == buf_info->stream_id) && - (bufs->vb2_buf->v4l2_buf.index == buf_info->index)) { - bufs->vb2_buf->v4l2_buf.sequence = buf_info->frame_id; - bufs->vb2_buf->v4l2_buf.timestamp = buf_info->timestamp; - bufs->vb2_buf->v4l2_buf.reserved = 0; + (bufs->index == buf_info->index)) { ret = buf_mngr_dev->vb2_ops.buf_done (bufs->vb2_buf, buf_info->session_id, - buf_info->stream_id); + buf_info->stream_id, + buf_info->frame_id, + &buf_info->timestamp, + 0); list_del_init(&bufs->entry); kfree(bufs); break; @@ -104,7 +105,7 @@ static int msm_buf_mngr_put_buf(struct msm_buf_mngr_device *buf_mngr_dev, list_for_each_entry_safe(bufs, save, &buf_mngr_dev->buf_qhead, entry) { if ((bufs->session_id == buf_info->session_id) && (bufs->stream_id == buf_info->stream_id) && - (bufs->vb2_buf->v4l2_buf.index == buf_info->index)) { + (bufs->index == buf_info->index)) { ret = buf_mngr_dev->vb2_ops.put_buf(bufs->vb2_buf, buf_info->session_id, buf_info->stream_id); list_del_init(&bufs->entry); diff --git a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.h b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.h index 56886cd9..9866cde2 100644 --- a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.h +++ b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.h @@ -29,6 +29,7 @@ struct msm_get_bufs { struct vb2_buffer *vb2_buf; uint32_t session_id; uint32_t stream_id; + uint32_t index; }; struct msm_buf_mngr_device { diff --git a/drivers/media/platform/msm/camera_v2/msm_sd.h b/drivers/media/platform/msm/camera_v2/msm_sd.h index 195c45a1..20391405 100644 --- a/drivers/media/platform/msm/camera_v2/msm_sd.h +++ b/drivers/media/platform/msm/camera_v2/msm_sd.h @@ -70,7 +70,8 @@ struct msm_sd_req_vb2_q { int (*put_buf)(struct vb2_buffer *vb2_buf, int session_id, unsigned int stream_id); int (*buf_done)(struct vb2_buffer *vb2_buf, int session_id, - unsigned int stream_id); + unsigned int stream_id, uint32_t sequence, struct timeval *ts, + uint32_t reserved); }; #define MSM_SD_NOTIFY_GET_SD 0x00000001 diff --git a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c index 55147017..f5cd4bc8 100644 --- a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c +++ b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -10,6 +10,7 @@ * GNU General Public License for more details. */ +#define pr_fmt(fmt) "CAM-VB2 %s:%d " fmt, __func__, __LINE__ #include "msm_vb2.h" static int msm_vb2_queue_setup(struct vb2_queue *q, @@ -39,16 +40,25 @@ static int msm_vb2_queue_setup(struct vb2_queue *q, int msm_vb2_buf_init(struct vb2_buffer *vb) { struct msm_stream *stream; + struct msm_session *session; struct msm_vb2_buffer *msm_vb2_buf; + unsigned long rl_flags; + + session = msm_get_session_from_vb2q(vb->vb2_queue); + if (IS_ERR_OR_NULL(session)) + return -EINVAL; + + read_lock_irqsave(&session->stream_rwlock, rl_flags); stream = msm_get_stream_from_vb2q(vb->vb2_queue); if (!stream) { pr_err("%s: Couldn't find stream\n", __func__); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return -EINVAL; } msm_vb2_buf = container_of(vb, struct msm_vb2_buffer, vb2_buf); msm_vb2_buf->in_freeq = 0; - + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return 0; } @@ -56,7 +66,8 @@ static void msm_vb2_buf_queue(struct vb2_buffer *vb) { struct msm_vb2_buffer *msm_vb2; struct msm_stream *stream; - unsigned long flags; + struct msm_session *session; + unsigned long flags, rl_flags; msm_vb2 = container_of(vb, struct msm_vb2_buffer, vb2_buf); @@ -65,22 +76,31 @@ static void msm_vb2_buf_queue(struct vb2_buffer *vb) return; } + session = msm_get_session_from_vb2q(vb->vb2_queue); + if (IS_ERR_OR_NULL(session)) + return; + + read_lock_irqsave(&session->stream_rwlock, rl_flags); + stream = msm_get_stream_from_vb2q(vb->vb2_queue); if (!stream) { pr_err("%s:%d] NULL stream", __func__, __LINE__); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return; } spin_lock_irqsave(&stream->stream_lock, flags); list_add_tail(&msm_vb2->list, &stream->queued_list); spin_unlock_irqrestore(&stream->stream_lock, flags); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); } static int msm_vb2_buf_finish(struct vb2_buffer *vb) { struct msm_vb2_buffer *msm_vb2; struct msm_stream *stream; - unsigned long flags; + struct msm_session *session; + unsigned long flags, rl_flags; struct msm_vb2_buffer *msm_vb2_entry, *temp; msm_vb2 = container_of(vb, struct msm_vb2_buffer, vb2_buf); @@ -90,9 +110,16 @@ static int msm_vb2_buf_finish(struct vb2_buffer *vb) return -EINVAL; } + session = msm_get_session_from_vb2q(vb->vb2_queue); + if (IS_ERR_OR_NULL(session)) + return -EINVAL; + + read_lock_irqsave(&session->stream_rwlock, rl_flags); + stream = msm_get_stream_from_vb2q(vb->vb2_queue); if (!stream) { pr_err("%s:%d] NULL stream", __func__, __LINE__); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return -EINVAL; } @@ -105,6 +132,7 @@ static int msm_vb2_buf_finish(struct vb2_buffer *vb) } } spin_unlock_irqrestore(&stream->stream_lock, flags); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return 0; } @@ -123,7 +151,7 @@ static void msm_vb2_buf_cleanup(struct vb2_buffer *vb) stream = msm_get_stream_from_vb2q(vb->vb2_queue); if (!stream) { - pr_err("%s:%d] NULL stream", __func__, __LINE__); + pr_err_ratelimited("%s:%d] NULL stream", __func__, __LINE__); return; } @@ -132,6 +160,24 @@ static void msm_vb2_buf_cleanup(struct vb2_buffer *vb) spin_unlock_irqrestore(&stream->stream_lock, flags); } +int msm_vb2_get_stream_state(struct msm_stream *stream) +{ + struct msm_vb2_buffer *msm_vb2, *temp; + unsigned long flags; + int rc = 1; + + spin_lock_irqsave(&stream->stream_lock, flags); + list_for_each_entry_safe(msm_vb2, temp, &(stream->queued_list), list) { + if (msm_vb2->in_freeq != 0) { + rc = 0; + break; + } + } + spin_unlock_irqrestore(&stream->stream_lock, flags); + return rc; +} + + static struct vb2_ops msm_vb2_get_q_op = { .queue_setup = msm_vb2_queue_setup, .buf_init = msm_vb2_buf_init, @@ -186,13 +232,22 @@ static struct vb2_buffer *msm_vb2_get_buf(int session_id, { struct msm_stream *stream; struct vb2_buffer *vb2_buf = NULL; + struct msm_session *session; struct msm_vb2_buffer *msm_vb2 = NULL; - unsigned long flags; + unsigned long flags, rl_flags; - stream = msm_get_stream(session_id, stream_id); - if (IS_ERR_OR_NULL(stream)) + session = msm_get_session(session_id); + if (IS_ERR_OR_NULL(session)) return NULL; + read_lock_irqsave(&session->stream_rwlock, rl_flags); + + stream = msm_get_stream(session, stream_id); + if (IS_ERR_OR_NULL(stream)) { + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); + return NULL; + } + spin_lock_irqsave(&stream->stream_lock, flags); if (!stream->vb2_q) { @@ -215,6 +270,7 @@ static struct vb2_buffer *msm_vb2_get_buf(int session_id, vb2_buf = NULL; end: spin_unlock_irqrestore(&stream->stream_lock, flags); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return vb2_buf; } @@ -222,14 +278,23 @@ static int msm_vb2_put_buf(struct vb2_buffer *vb, int session_id, unsigned int stream_id) { struct msm_stream *stream; + struct msm_session *session; struct msm_vb2_buffer *msm_vb2; int rc = 0; - unsigned long flags; + unsigned long flags, rl_flags; - stream = msm_get_stream(session_id, stream_id); - if (IS_ERR_OR_NULL(stream)) + session = msm_get_session(session_id); + if (IS_ERR_OR_NULL(session)) return -EINVAL; + read_lock_irqsave(&session->stream_rwlock, rl_flags); + + stream = msm_get_stream(session, stream_id); + if (IS_ERR_OR_NULL(stream)) { + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); + return -EINVAL; + } + spin_lock_irqsave(&stream->stream_lock, flags); if (vb) { msm_vb2 = @@ -244,26 +309,41 @@ static int msm_vb2_put_buf(struct vb2_buffer *vb, int session_id, rc = -EINVAL; } spin_unlock_irqrestore(&stream->stream_lock, flags); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return rc; } static int msm_vb2_buf_done(struct vb2_buffer *vb, int session_id, - unsigned int stream_id) + unsigned int stream_id, uint32_t sequence, + struct timeval *ts, uint32_t reserved) { - unsigned long flags; + unsigned long flags, rl_flags; struct msm_vb2_buffer *msm_vb2; struct msm_stream *stream; + struct msm_session *session; int rc = 0; - stream = msm_get_stream(session_id, stream_id); - if (IS_ERR_OR_NULL(stream)) - return 0; + session = msm_get_session(session_id); + if (IS_ERR_OR_NULL(session)) + return -EINVAL; + + read_lock_irqsave(&session->stream_rwlock, rl_flags); + + stream = msm_get_stream(session, stream_id); + if (IS_ERR_OR_NULL(stream)) { + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); + return -EINVAL; + } + spin_lock_irqsave(&stream->stream_lock, flags); if (vb) { msm_vb2 = container_of(vb, struct msm_vb2_buffer, vb2_buf); /* put buf before buf done */ if (msm_vb2->in_freeq) { + vb->v4l2_buf.sequence = sequence; + vb->v4l2_buf.timestamp = *ts; + vb->v4l2_buf.reserved = reserved; vb2_buffer_done(vb, VB2_BUF_STATE_DONE); msm_vb2->in_freeq = 0; rc = 0; @@ -275,6 +355,7 @@ static int msm_vb2_buf_done(struct vb2_buffer *vb, int session_id, } spin_unlock_irqrestore(&stream->stream_lock, flags); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return rc; } diff --git a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.h b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.h index 7082f858..ff1a0004 100644 --- a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.h +++ b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -66,5 +66,6 @@ struct msm_stream { struct vb2_ops *msm_vb2_get_q_ops(void); struct vb2_mem_ops *msm_vb2_get_q_mem_ops(void); int msm_vb2_request_cb(struct msm_sd_req_vb2_q *req_sd); +int msm_vb2_get_stream_state(struct msm_stream *stream); #endif /*_MSM_VB_H */ diff --git a/drivers/media/platform/msm/camera_v2/sensor/external/msm_companion.c b/drivers/media/platform/msm/camera_v2/sensor/external/msm_companion.c index d42e7545..86d99280 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/external/msm_companion.c +++ b/drivers/media/platform/msm/camera_v2/sensor/external/msm_companion.c @@ -281,8 +281,11 @@ static int msm_companion_fw_binary_set(struct companion_device *companion_dev, s } offset += size; + /* I will use this 'SD' path to point to /vendor, so don't touch it --fbs */ +#if 0 if (fw_p == FW_PATH_SD && fw_n == FW_NAME_ISP) snprintf(fw_name[fw_p][fw_n], 64, "%s", ISP_COMPANION_BINARY_PATH); +#endif // print debug message pr_err("[syscamera][%s::%d] PathIDX = %d, NameIDX = %d, path = %s\n", __FUNCTION__, __LINE__, fw_p, fw_n, fw_name[fw_p][fw_n]); @@ -661,17 +664,17 @@ static int msm_companion_fw_write(struct companion_device *companion_dev) if (companion_version_info == COMP_EVT0) { pr_err("[syscamera][%s::%d][Companion EVT 0]\n", __FUNCTION__, __LINE__); -// fw_name[FW_PATH_SD][FW_NAME_ISP][REV_OFFSET_ISP_SD] = '0'; + fw_name[FW_PATH_SD][FW_NAME_ISP][REV_OFFSET_ISP_CC] = '0'; fw_name[FW_PATH_CC][FW_NAME_ISP][REV_OFFSET_ISP_CC] = '0'; - fw_name[FW_PATH_SD][FW_NAME_MASTER][REV_OFFSET_MASTER_SD] = '0'; + fw_name[FW_PATH_SD][FW_NAME_MASTER][REV_OFFSET_MASTER_CC] = '0'; fw_name[FW_PATH_CC][FW_NAME_MASTER][REV_OFFSET_MASTER_CC] = '0'; } else if (companion_version_info == COMP_EVT1) { pr_err("[syscamera][%s::%d][Companion EVT 1]\n", __FUNCTION__, __LINE__); -// fw_name[FW_PATH_SD][FW_NAME_ISP][REV_OFFSET_ISP_SD] = '1'; + fw_name[FW_PATH_SD][FW_NAME_ISP][REV_OFFSET_ISP_CC] = '1'; fw_name[FW_PATH_CC][FW_NAME_ISP][REV_OFFSET_ISP_CC] = '1'; - fw_name[FW_PATH_SD][FW_NAME_MASTER][REV_OFFSET_MASTER_SD] = '1'; + fw_name[FW_PATH_SD][FW_NAME_MASTER][REV_OFFSET_MASTER_CC] = '1'; fw_name[FW_PATH_CC][FW_NAME_MASTER][REV_OFFSET_MASTER_CC] = '1'; } else { pr_err("[syscamera][%s::%d][Invalid Companion Version : %d]\n", __FUNCTION__, __LINE__, companion_version_info); diff --git a/drivers/media/platform/msm/camera_v2/sensor/external/msm_companion.h b/drivers/media/platform/msm/camera_v2/sensor/external/msm_companion.h index ed200c1e..502217bc 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/external/msm_companion.h +++ b/drivers/media/platform/msm/camera_v2/sensor/external/msm_companion.h @@ -64,8 +64,8 @@ enum { FW_PATH_MAX, }; char *companion_fw_path[] = { + "/system/cameradata/", "/vendor/cameradata/", - "/data/media/0/", }; enum { @@ -84,10 +84,8 @@ char *companion_fw_name[] = { #define FW_EXTENSION ".bin" #define REV_OFFSET_ISP_CC 28 -#define REV_OFFSET_ISP_SD 23 #define REV_OFFSET_MASTER_CC 25 -#define REV_OFFSET_MASTER_SD 20 #endif diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c index b19d3e1c..6951482e 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c +++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c @@ -347,7 +347,7 @@ int32_t msm_camera_cci_i2c_write_table( usleep_range(write_setting->delay * 1000, (write_setting->delay * 1000) + 1000); - client->addr_type = client_addr_type; + client->addr_type = client_addr_type; } diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.c index 7613d4e6..091c562b 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.c +++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2013, The Linux Foundataion. All rights reserved. +/* Copyright (c) 2011-2013, 2019 The Linux Foundataion. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -187,12 +187,13 @@ int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info, } } else { for (i = num_clk - 1; i >= 0; i--) { - if (clk_ptr[i] != NULL) { + if (!IS_ERR_OR_NULL(clk_ptr[i])) { CDBG("%s disable %s\n", __func__, clk_info[i].clk_name); clk_disable(clk_ptr[i]); clk_unprepare(clk_ptr[i]); clk_put(clk_ptr[i]); + clk_ptr[i] = NULL; } } } @@ -206,10 +207,11 @@ int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info, clk_put(clk_ptr[i]); cam_clk_get_err: for (i--; i >= 0; i--) { - if (clk_ptr[i] != NULL) { + if (!IS_ERR_OR_NULL(clk_ptr[i])) { clk_disable(clk_ptr[i]); clk_unprepare(clk_ptr[i]); clk_put(clk_ptr[i]); + clk_ptr[i] = NULL; } } return rc; diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c index 80cbc641..dc59bd2e 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc.c +++ b/drivers/media/platform/msm/vidc/msm_vidc.c @@ -239,9 +239,9 @@ struct buffer_info *get_registered_buf(struct msm_vidc_inst *inst, list_for_each_entry(temp, list, list) { for (i = 0; (i < temp->num_planes) && (i < VIDEO_MAX_PLANES); i++) { - bool ion_hndl_matches = - msm_smem_compare_buffers(inst->mem_client, fd, - temp->handle[i]->smem_priv); + bool ion_hndl_matches = temp->handle[i] ? + msm_smem_compare_buffers(inst->mem_client, fd, + temp->handle[i]->smem_priv) : false; if (temp && (ion_hndl_matches || (device_addr == temp->device_addr[i])) && diff --git a/drivers/misc/ice40xx.c b/drivers/misc/ice40xx.c index 54e6e870..7806d5a3 100644 --- a/drivers/misc/ice40xx.c +++ b/drivers/misc/ice40xx.c @@ -737,7 +737,7 @@ static ssize_t remocon_store(struct device *dev, struct device_attribute *attr, for (i = 0; i < MAX_SIZE; i++) { if (sscanf(buf++, "%u", &_data) == 1) { - if (_data == 0 || buf == '\0') + if (_data == 0 || *buf == '\0') break; if (count == 2) { data->ir_freq = _data; diff --git a/drivers/misc/max77804k-muic.c b/drivers/misc/max77804k-muic.c index aa9b7ca7..ee74a476 100644 --- a/drivers/misc/max77804k-muic.c +++ b/drivers/misc/max77804k-muic.c @@ -937,7 +937,6 @@ int max77804k_muic_get_charging_type(void) return CABLE_TYPE_NONE_MUIC; } -extern int system_rev; static int max77804k_muic_set_charging_type(struct max77804k_muic_info *info, bool force_disable) { diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c index b041223a..6f413e53 100644 --- a/drivers/misc/qseecom.c +++ b/drivers/misc/qseecom.c @@ -2555,6 +2555,7 @@ int qseecom_shutdown_app(struct qseecom_handle **handle) struct qseecom_dev_handle *data; struct qseecom_registered_kclient_list *kclient = NULL; + struct qseecom_registered_kclient_list *kclient_tmp = NULL; unsigned long flags = 0; bool found_handle = false; @@ -2567,8 +2568,8 @@ int qseecom_shutdown_app(struct qseecom_handle **handle) atomic_inc(&data->ioctl_count); spin_lock_irqsave(&qseecom.registered_kclient_list_lock, flags); - list_for_each_entry(kclient, &qseecom.registered_kclient_list_head, - list) { + list_for_each_entry_safe(kclient, kclient_tmp, + &qseecom.registered_kclient_list_head, list) { if (kclient->handle == (*handle)) { list_del(&kclient->list); found_handle = true; @@ -4706,7 +4707,7 @@ static int __devinit qseecom_probe(struct platform_device *pdev) if (qseecom.support_pfe) { if (of_property_read_u32((&pdev->dev)->of_node, "qcom,file-encrypt-pipe-pair", - &qseecom.ce_info.disk_encrypt_pipe)) { + &qseecom.ce_info.file_encrypt_pipe)) { pr_err("Fail to get PFE pipe information.\n"); rc = -EINVAL; goto exit_destroy_ion_client; diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index c19f9447..60fc69c0 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -580,7 +580,7 @@ static int macvtap_skb_from_vnet_hdr(struct sk_buff *skb, case VIRTIO_NET_HDR_GSO_UDP: gso_type = SKB_GSO_UDP; if (skb->protocol == htons(ETH_P_IPV6)) - ipv6_proxy_select_ident(skb); + ipv6_proxy_select_ident(dev_net(skb->dev), skb); break; default: return -EINVAL; diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c index 5a13ad0f..ab7f20fd 100644 --- a/drivers/net/ppp/pptp.c +++ b/drivers/net/ppp/pptp.c @@ -281,7 +281,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) nf_reset(skb); skb->ip_summed = CHECKSUM_NONE; - ip_select_ident(skb, NULL); + ip_select_ident(sock_net(sk), skb, NULL); ip_send_check(iph); ip_local_out(skb); diff --git a/drivers/net/tun.c b/drivers/net/tun.c index d7f53078..3d10c424 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -720,7 +720,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, case VIRTIO_NET_HDR_GSO_UDP: skb_shinfo(skb)->gso_type = SKB_GSO_UDP; if (skb->protocol == htons(ETH_P_IPV6)) - ipv6_proxy_select_ident(skb); + ipv6_proxy_select_ident(dev_net(skb->dev), skb); break; default: tun->dev->stats.rx_frame_errors++; diff --git a/drivers/platform/msm/avtimer.c b/drivers/platform/msm/avtimer.c index 9606ef7c..f9fda018 100644 --- a/drivers/platform/msm/avtimer.c +++ b/drivers/platform/msm/avtimer.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, 2019, The Linux Foundation. All rights reserved. * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -93,6 +93,13 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) } payload1 = data->payload; + + if (data->payload_size < 2 * sizeof(uint32_t)) { + pr_err("%s: payload has invalid size %d\n", + __func__, data->payload_size); + return -EINVAL; + } + switch (payload1[0]) { case AVCS_CMD_REMOTE_AVTIMER_RELEASE_REQUEST: pr_debug("%s: Cmd = TIMER RELEASE status[0x%x]\n", @@ -118,6 +125,11 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) } case AVCS_CMD_RSP_REMOTE_AVTIMER_VOTE_REQUEST: + if (data->payload_size < sizeof(uint32_t)) { + pr_err("%s: payload has invalid size %d\n", + __func__, data->payload_size); + return -EINVAL; + } payload1 = data->payload; pr_debug("%s: RSP_REMOTE_AVTIMER_VOTE_REQUEST handle %x\n", __func__, payload1[0]); diff --git a/drivers/platform/msm/sps/sps.c b/drivers/platform/msm/sps/sps.c index c8790bfe..7f7ba8ba 100644 --- a/drivers/platform/msm/sps/sps.c +++ b/drivers/platform/msm/sps/sps.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1017,8 +1017,6 @@ static void sps_device_de_init(void) SPS_ERR("sps:SPS de-init: BAMs are still registered"); sps_map_de_init(); - - kfree(sps); } sps_mem_de_init(); @@ -2760,6 +2758,7 @@ static struct platform_driver msm_sps_driver = { .name = SPS_DRV_NAME, .owner = THIS_MODULE, .of_match_table = msm_sps_match, + .suppress_bind_attrs = true, }, .remove = __exit_p(msm_sps_remove), }; diff --git a/drivers/regulator/qpnp-regulator.c b/drivers/regulator/qpnp-regulator.c index d8596518..2400d0f1 100644 --- a/drivers/regulator/qpnp-regulator.c +++ b/drivers/regulator/qpnp-regulator.c @@ -857,7 +857,7 @@ static irqreturn_t qpnp_regulator_vs_ocp_isr(int irq, void *data) return IRQ_HANDLED; } -static const char const *qpnp_print_actions[] = { +static const char *qpnp_print_actions[] = { [QPNP_REGULATOR_ACTION_INIT] = "initial ", [QPNP_REGULATOR_ACTION_ENABLE] = "enable ", [QPNP_REGULATOR_ACTION_DISABLE] = "disable ", diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c index cb2edaef..f61326d8 100644 --- a/drivers/rtc/rtc-pm8xxx.c +++ b/drivers/rtc/rtc-pm8xxx.c @@ -311,6 +311,7 @@ static int pm8xxx_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) unsigned long irq_flags; struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev); u8 ctrl_reg; + u8 value[4] = {0}; spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags); ctrl_reg = rtc_dd->ctrl_reg; @@ -325,6 +326,14 @@ static int pm8xxx_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) rtc_dd->ctrl_reg = ctrl_reg; + /* Clear Alarm register */ + if (!enable) { + rc = pm8xxx_write_wrapper(rtc_dd, value, + rtc_dd->alarm_rw_base, NUM_8_BIT_RTC_REGS); + if (rc < 0) + dev_err(dev, "Clear ALARM value reg failed\n"); + } + rtc_rw_fail: spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags); return rc; diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index 887c71ff..1618352d 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c @@ -1101,7 +1101,7 @@ thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz) static void thermal_zone_device_set_polling(struct thermal_zone_device *tz, int delay) { - cancel_delayed_work(&(tz->poll_queue)); + cancel_delayed_work(&tz->poll_queue); if (!delay) return; @@ -1724,7 +1724,7 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) tz->ops->unbind(tz, cdev); mutex_unlock(&thermal_list_lock); - thermal_zone_device_set_polling(tz, 0); + cancel_delayed_work_sync(&tz->poll_queue); if (tz->type[0]) device_remove_file(&tz->device, &dev_attr_type); diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c index 8e9b4be9..a8acdb49 100644 --- a/drivers/tty/vt/selection.c +++ b/drivers/tty/vt/selection.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -39,6 +40,7 @@ static volatile int sel_start = -1; /* cleared by clear_selection */ static int sel_end; static int sel_buffer_lth; static char *sel_buffer; +static DEFINE_MUTEX(sel_lock); /* clear_selection, highlight and highlight_pointer can be called from interrupt (via scrollback/front) */ @@ -155,14 +157,14 @@ static int store_utf8(u16 c, char *p) * The entire selection process is managed under the console_lock. It's * a lot under the lock but its hardly a performance path */ -int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *tty) +static int __set_selection(const struct tiocl_selection __user *sel, struct tty_struct *tty) { struct vc_data *vc = vc_cons[fg_console].d; int sel_mode, new_sel_start, new_sel_end, spc; char *bp, *obp; int i, ps, pe, multiplier; u16 c; - int mode; + int mode, ret = 0; poke_blanked_console(); @@ -323,7 +325,21 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t } } sel_buffer_lth = bp - sel_buffer; - return 0; + + return ret; +} + +int set_selection(const struct tiocl_selection __user *v, struct tty_struct *tty) +{ + int ret; + + mutex_lock(&sel_lock); + console_lock(); + ret = __set_selection(v, tty); + console_unlock(); + mutex_unlock(&sel_lock); + + return ret; } /* Insert the contents of the selection buffer into the @@ -353,10 +369,13 @@ int paste_selection(struct tty_struct *tty) /* FIXME: this is completely unsafe */ add_wait_queue(&vc->paste_wait, &wait); + mutex_lock(&sel_lock); while (sel_buffer && sel_buffer_lth > pasted) { set_current_state(TASK_INTERRUPTIBLE); if (test_bit(TTY_THROTTLED, &tty->flags)) { + mutex_unlock(&sel_lock); schedule(); + mutex_lock(&sel_lock); continue; } count = sel_buffer_lth - pasted; @@ -365,6 +384,7 @@ int paste_selection(struct tty_struct *tty) NULL, count); pasted += count; } + mutex_unlock(&sel_lock); remove_wait_queue(&vc->paste_wait, &wait); __set_current_state(TASK_RUNNING); diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 334a7b27..e2c62036 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -2611,9 +2611,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) switch (type) { case TIOCL_SETSEL: - console_lock(); ret = set_selection((struct tiocl_selection __user *)(p+1), tty); - console_unlock(); break; case TIOCL_PASTESEL: ret = paste_selection(tty); diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c index f94c51bd..e2b69caf 100644 --- a/drivers/usb/gadget/android.c +++ b/drivers/usb/gadget/android.c @@ -569,12 +569,23 @@ static void ffs_function_enable(struct android_usb_function *f) { struct android_dev *dev = f->android_dev; struct functionfs_config *config = f->config; + int ret = 0; config->enabled = true; /* Disable the gadget until the function is ready */ - if (!config->opened) + if (!config->opened) { android_disable(dev); + } else { + /* + * Call functionfs_bind to handle the case where userspace + * passed descriptors before updating enabled functions list + */ + ret = functionfs_bind(config->data, dev->cdev); + if (ret) + pr_err("%s: functionfs_bind failed (%d)\n", __func__, + ret); + } } static void ffs_function_disable(struct android_usb_function *f) diff --git a/drivers/usb/gadget/f_mtp.c b/drivers/usb/gadget/f_mtp.c index 6284c534..15c30a22 100644 --- a/drivers/usb/gadget/f_mtp.c +++ b/drivers/usb/gadget/f_mtp.c @@ -563,11 +563,6 @@ static ssize_t mtp_read(struct file *fp, char __user *buf, DBG(cdev, "mtp_read(%d)\n", count); - len = ALIGN(count, dev->ep_out->maxpacket); - - if (len > mtp_rx_req_len) - return -EINVAL; - /* we will block until we're online */ DBG(cdev, "mtp_read: waiting for online state\n"); ret = wait_event_interruptible(dev->read_wq, @@ -576,6 +571,11 @@ static ssize_t mtp_read(struct file *fp, char __user *buf, r = ret; goto done; } + len = ALIGN(count, dev->ep_out->maxpacket); + + if (len > mtp_rx_req_len) + return -EINVAL; + spin_lock_irq(&dev->lock); if (dev->state == STATE_CANCELED) { /* report cancelation to userspace */ diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c index e7e67810..dbde989e 100644 --- a/drivers/usb/storage/ene_ub6250.c +++ b/drivers/usb/storage/ene_ub6250.c @@ -2066,7 +2066,7 @@ static int ene_ms_init(struct us_data *us) { struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; int result; - u8 buf[0x200]; + u8 buf[0x199]; u16 MSP_BlockSize, MSP_UserAreaBlocks; struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 9d8feac6..08d0805d 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -1311,6 +1311,9 @@ static int vgacon_font_get(struct vc_data *c, struct console_font *font) static int vgacon_resize(struct vc_data *c, unsigned int width, unsigned int height, unsigned int user) { + if ((width << 1) * height > vga_vram_size) + return -EINVAL; + if (width % 2 || width > screen_info.orig_video_cols || height > (screen_info.orig_video_lines * vga_default_font_height)/ c->vc_font.height) diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c index 7a59d510..19965e6a 100644 --- a/drivers/video/msm/mdp.c +++ b/drivers/video/msm/mdp.c @@ -2023,7 +2023,7 @@ irqreturn_t mdp_isr(int irq, void *ptr) /* DMA_E LCD-Out Complete */ if (mdp_interrupt & MDP_DMA_E_DONE) { - dma = &dma_s_data; + dma = &dma_e_data; dma->busy = FALSE; mdp_pipe_ctrl(MDP_DMA_E_BLOCK, MDP_BLOCK_POWER_OFF, TRUE); @@ -2121,9 +2121,11 @@ static void mdp_drv_init(void) dma_s_data.busy = FALSE; dma_s_data.waiting = FALSE; + dma_s_data.dmap_busy = FALSE; init_completion(&dma_s_data.comp); sema_init(&dma_s_data.mutex, 1); + mutex_init(&dma_s_data.ov_mutex); #ifndef CONFIG_FB_MSM_MDP303 dma_e_data.busy = FALSE; dma_e_data.waiting = FALSE; diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c index 58cebca3..4c5ba6f4 100644 --- a/drivers/video/msm/mdss/mdss_fb.c +++ b/drivers/video/msm/mdss/mdss_fb.c @@ -66,6 +66,9 @@ int backlight_min = 0; module_param(backlight_min, int, 0644); +#define SMARTDIM_MIN 35 +#define SMARTDIM_PCC_MIN 5000 // minimum perceptible value of lowest brightness +#define PCC_MAX 32768 #define MAX_FBI_LIST 32 static struct fb_info *fbi_list[MAX_FBI_LIST]; @@ -116,6 +119,7 @@ static int mdss_fb_pan_idle(struct msm_fb_data_type *mfd); static int mdss_fb_send_panel_event(struct msm_fb_data_type *mfd, int event, void *arg); static void mdss_fb_set_mdp_sync_pt_threshold(struct msm_fb_data_type *mfd); +static unsigned int smartdim_enabled = 0; #if defined (CONFIG_FB_MSM_MIPI_SAMSUNG_TFT_VIDEO_WQXGA_PT_PANEL)|| \ defined (CONFIG_FB_MSM8x26_MDSS_CHECK_LCD_CONNECTION) @@ -246,6 +250,75 @@ static int mdss_fb_notify_update(struct msm_fb_data_type *mfd, static int lcd_backlight_registered; +static int pcc_r = 32768, pcc_g = 32768, pcc_b = 32768; + +static ssize_t smart_dim_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + sprintf(buf, "%u\n", smartdim_enabled); + + return strlen(buf); +} + +static ssize_t smart_dim_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + int rc, value; + + rc = kstrtouint(buf, 0, &value); + + if (rc < 0) + return rc; + + if (smartdim_enabled != value) + smartdim_enabled = value; + + return size; +} + +static DEVICE_ATTR(smart_dim, 0664, smart_dim_show, smart_dim_store); + +static struct attribute *smart_dim_attrs[] = { + &dev_attr_smart_dim.attr, + NULL, +}; + +static struct attribute_group smart_dim_attr_group = { + .attrs = smart_dim_attrs, +}; + +static int pcc_ratio(int pcc_old, int pcc_new) +{ + + int ratio = pcc_old * pcc_new / PCC_MAX; + + return ratio; +} + +static void bl_to_pcc(int value) +{ + struct mdp_pcc_cfg_data pcc_cfg; + u32 copyback = 0; + + int pcc_intp = PCC_MAX + ((PCC_MAX - SMARTDIM_PCC_MIN) * (value - SMARTDIM_MIN)) / (SMARTDIM_MIN - 1); + + memset(&pcc_cfg, 0, sizeof(struct mdp_pcc_cfg_data)); + pcc_cfg.block = MDP_LOGICAL_BLOCK_DISP_0; + pcc_cfg.ops = MDP_PP_OPS_ENABLE | MDP_PP_OPS_WRITE; + + if (value < SMARTDIM_MIN && value != 0) { + pcc_cfg.r.r = pcc_ratio(pcc_r, pcc_intp); + pcc_cfg.g.g = pcc_ratio(pcc_g, pcc_intp); + pcc_cfg.b.b = pcc_ratio(pcc_b, pcc_intp); + } else if (value != 0) { + pcc_cfg.r.r = pcc_r; + pcc_cfg.g.g = pcc_g; + pcc_cfg.b.b = pcc_b; + } + + mdss_mdp_pcc_config(&pcc_cfg, ©back); +} + static void mdss_fb_set_bl_brightness(struct led_classdev *led_cdev, enum led_brightness value) { @@ -255,9 +328,15 @@ static void mdss_fb_set_bl_brightness(struct led_classdev *led_cdev, if (value > mfd->panel_info->brightness_max) value = mfd->panel_info->brightness_max; - // Boeffla: apply min limits for LCD backlight (0 is exception for display off) - if (value != 0 && value < backlight_min) - value = backlight_min; + // Boeffla: apply min limits for LCD backlight (0 is exception for display off) + if (value != 0 && value < backlight_min) + value = backlight_min; + + if (smartdim_enabled) + bl_to_pcc(value); + + if (value < SMARTDIM_MIN && value != 0) + value = SMARTDIM_MIN; /* This maps android backlight level 0 to 255 into driver backlight level 0 to bl_max with rounding */ @@ -496,7 +575,6 @@ static ssize_t mdss_fb_get_idle_notify(struct device *dev, return ret; } -static int pcc_r = 32768, pcc_g = 32768, pcc_b = 32768; static ssize_t mdss_get_rgb(struct device *dev, struct device_attribute *attr, char *buf) { @@ -694,6 +772,10 @@ static int mdss_fb_create_sysfs(struct msm_fb_data_type *mfd) { int rc; + rc = sysfs_create_group(&mfd->fbi->dev->kobj, &smart_dim_attr_group); + if (rc) + pr_err("sysfs group creation failed, rc=%d\n", rc); + rc = sysfs_create_group(&mfd->fbi->dev->kobj, &mdss_fb_attr_group); if (rc) pr_err("sysfs group creation failed, rc=%d\n", rc); @@ -2558,10 +2640,15 @@ static int __mdss_fb_display_thread(void *data) while (1) { ATRACE_BEGIN(__func__); - wait_event(mfd->commit_wait_q, + ret = wait_event_interruptible(mfd->commit_wait_q, (atomic_read(&mfd->commits_pending) || kthread_should_stop())); + if (ret) { + pr_info("%s: interrupted", __func__); + continue; + } + if (kthread_should_stop()) break; @@ -3361,5 +3448,6 @@ int mdss_fb_suspres_panel(struct device *dev, void *data) pr_warn("unable to %s fb%d (%d)\n", event == MDSS_EVENT_RESUME ? "resume" : "suspend", mfd->index, rc); + return rc; } diff --git a/drivers/video/msm/mdss/mdss_mdp_kcal_ctrl.c b/drivers/video/msm/mdss/mdss_mdp_kcal_ctrl.c index 5217c93a..89166c78 100644 --- a/drivers/video/msm/mdss/mdss_mdp_kcal_ctrl.c +++ b/drivers/video/msm/mdss/mdss_mdp_kcal_ctrl.c @@ -580,12 +580,12 @@ static int kcal_ctrl_probe(struct platform_device *pdev) lut_data->red = DEF_PCC; lut_data->green = DEF_PCC; lut_data->blue = DEF_PCC; - lut_data->minimum = 0x23; + lut_data->minimum = 0x43; lut_data->invert = 0x0; lut_data->hue = 0x0; - lut_data->sat = DEF_PA; - lut_data->val = DEF_PA; - lut_data->cont = DEF_PA; + lut_data->sat = DEF_PA-0x0d; + lut_data->val = DEF_PA+0x02; + lut_data->cont = DEF_PA-0x02; lut_data->queue_changes = false; diff --git a/drivers/video/msm/mdss/mdss_mdp_util.c b/drivers/video/msm/mdss/mdss_mdp_util.c index 3586f63f..31c30a11 100644 --- a/drivers/video/msm/mdss/mdss_mdp_util.c +++ b/drivers/video/msm/mdss/mdss_mdp_util.c @@ -333,6 +333,8 @@ int mdss_mdp_get_plane_sizes(u32 format, u32 w, u32 h, if (ps == NULL) return -EINVAL; + memset(ps, 0, sizeof(struct mdss_mdp_plane_sizes)); + if ((w > MAX_IMG_WIDTH) || (h > MAX_IMG_HEIGHT)) return -ERANGE; @@ -341,7 +343,6 @@ int mdss_mdp_get_plane_sizes(u32 format, u32 w, u32 h, return -EINVAL; bpp = fmt->bpp; - memset(ps, 0, sizeof(struct mdss_mdp_plane_sizes)); if (bwc_mode) { u32 height, meta_size; diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 4485bf0e..8405f381 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c @@ -460,8 +460,8 @@ int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg, int offset; int remainder_of_page; - if (sg) - sg_init_table(sg, sg_size); + if (sg) + sg_init_table(sg, sg_size); while (size > 0 && i < sg_size) { pg = virt_to_page(addr); diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 0108f891..ba83a466 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -162,7 +162,6 @@ void ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, unsigned int bit, bit_max; struct ext4_sb_info *sbi = EXT4_SB(sb); ext4_fsblk_t start, tmp; - int flex_bg = 0; J_ASSERT_BH(bh, buffer_locked(bh)); @@ -184,22 +183,19 @@ void ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, start = ext4_group_first_block_no(sb, block_group); - if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) - flex_bg = 1; - /* Set bits for block and inode bitmaps, and inode table */ tmp = ext4_block_bitmap(sb, gdp); - if (!flex_bg || ext4_block_in_group(sb, tmp, block_group)) + if (ext4_block_in_group(sb, tmp, block_group)) ext4_set_bit(EXT4_B2C(sbi, tmp - start), bh->b_data); tmp = ext4_inode_bitmap(sb, gdp); - if (!flex_bg || ext4_block_in_group(sb, tmp, block_group)) + if (ext4_block_in_group(sb, tmp, block_group)) ext4_set_bit(EXT4_B2C(sbi, tmp - start), bh->b_data); tmp = ext4_inode_table(sb, gdp); for (; tmp < ext4_inode_table(sb, gdp) + sbi->s_itb_per_group; tmp++) { - if (!flex_bg || ext4_block_in_group(sb, tmp, block_group)) + if (ext4_block_in_group(sb, tmp, block_group)) ext4_set_bit(EXT4_B2C(sbi, tmp - start), bh->b_data); } diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 0e2341bc..a06eea0d 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -572,6 +572,8 @@ enum { #define EXT4_GET_BLOCKS_NO_NORMALIZE 0x0040 /* Request will not result in inode size update (user for fallocate) */ #define EXT4_GET_BLOCKS_KEEP_SIZE 0x0080 +/* Write zeros to newly created written extents */ +#define EXT4_GET_BLOCKS_ZERO 0x0200 /* * Flags used by ext4_free_blocks diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 831e8c9c..5d298691 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -658,6 +658,21 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode, int ret = check_block_validity(inode, map); if (ret != 0) return ret; + + /* + * Inodes with freshly allocated blocks where contents will be + * visible after transaction commit must be on transaction's + * ordered data list. + */ + if (map->m_flags & EXT4_MAP_NEW && + !(map->m_flags & EXT4_MAP_UNWRITTEN) && + !(flags & EXT4_GET_BLOCKS_ZERO) && + !IS_NOQUOTA(inode) && + ext4_should_order_data(inode)) { + ret = ext4_jbd2_file_inode(handle, inode); + if (ret) + return ret; + } } return retval; } @@ -4580,10 +4595,25 @@ static int ext4_expand_extra_isize(struct inode *inode, { struct ext4_inode *raw_inode; struct ext4_xattr_ibody_header *header; + unsigned int inode_size = EXT4_INODE_SIZE(inode->i_sb); + struct ext4_inode_info *ei = EXT4_I(inode); if (EXT4_I(inode)->i_extra_isize >= new_extra_isize) return 0; + /* this was checked at iget time, but double check for good measure */ + if ((EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize > inode_size) || + (ei->i_extra_isize & 3)) { + EXT4_ERROR_INODE(inode, "bad extra_isize %u (inode size %u)", + ei->i_extra_isize, + EXT4_INODE_SIZE(inode->i_sb)); + return -EIO; + } + if ((new_extra_isize < ei->i_extra_isize) || + (new_extra_isize < 4) || + (new_extra_isize > inode_size - EXT4_GOOD_OLD_INODE_SIZE)) + return -EINVAL; /* Should never happen */ + raw_inode = ext4_raw_inode(&iloc); header = IHDR(inode, raw_inode); diff --git a/fs/ext4/super.c b/fs/ext4/super.c index bb72281d..84b77393 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -2049,11 +2049,13 @@ int ext4_group_desc_csum_verify(struct ext4_sb_info *sbi, __u32 block_group, /* Called at mount-time, super-block is locked */ static int ext4_check_descriptors(struct super_block *sb, + ext4_fsblk_t sb_block, ext4_group_t *first_not_zeroed) { struct ext4_sb_info *sbi = EXT4_SB(sb); ext4_fsblk_t first_block = le32_to_cpu(sbi->s_es->s_first_data_block); ext4_fsblk_t last_block; + ext4_fsblk_t last_bg_block = sb_block + ext4_bg_num_gdb(sb, 0); ext4_fsblk_t block_bitmap; ext4_fsblk_t inode_bitmap; ext4_fsblk_t inode_table; @@ -2079,6 +2081,19 @@ static int ext4_check_descriptors(struct super_block *sb, grp = i; block_bitmap = ext4_block_bitmap(sb, gdp); + if (block_bitmap == sb_block) { + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " + "Block bitmap for group %u overlaps " + "superblock", i); + } + if (block_bitmap >= sb_block + 1 && + block_bitmap <= last_bg_block) { + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " + "Block bitmap for group %u overlaps " + "block group descriptors", i); + if (!(sb->s_flags & MS_RDONLY)) + return 0; + } if (block_bitmap < first_block || block_bitmap > last_block) { ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " "Block bitmap for group %u not in group " @@ -2086,6 +2101,19 @@ static int ext4_check_descriptors(struct super_block *sb, return 0; } inode_bitmap = ext4_inode_bitmap(sb, gdp); + if (inode_bitmap == sb_block) { + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " + "Inode bitmap for group %u overlaps " + "superblock", i); + } + if (inode_bitmap >= sb_block + 1 && + inode_bitmap <= last_bg_block) { + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " + "Inode bitmap for group %u overlaps " + "block group descriptors", i); + if (!(sb->s_flags & MS_RDONLY)) + return 0; + } if (inode_bitmap < first_block || inode_bitmap > last_block) { ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " "Inode bitmap for group %u not in group " @@ -2093,6 +2121,19 @@ static int ext4_check_descriptors(struct super_block *sb, return 0; } inode_table = ext4_inode_table(sb, gdp); + if (inode_table == sb_block) { + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " + "Inode table for group %u overlaps " + "superblock", i); + } + if (inode_table >= sb_block + 1 && + inode_table <= last_bg_block) { + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " + "Inode table for group %u overlaps " + "block group descriptors", i); + if (!(sb->s_flags & MS_RDONLY)) + return 0; + } if (inode_table < first_block || inode_table + sbi->s_itb_per_group - 1 > last_block) { ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " @@ -2957,8 +2998,14 @@ static ext4_group_t ext4_has_uninit_itable(struct super_block *sb) if (!gdp) continue; - if (!(gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_ZEROED))) + if (gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_ZEROED)) + continue; + if (group != 0) break; + ext4_error(sb, "Inode table for bg 0 marked as " + "needing zeroing"); + if (sb->s_flags & MS_RDONLY) + return ngroups; } return group; @@ -3271,6 +3318,41 @@ int ext4_calculate_overhead(struct super_block *sb) return 0; } +static void ext4_clamp_want_extra_isize(struct super_block *sb) +{ + struct ext4_sb_info *sbi = EXT4_SB(sb); + struct ext4_super_block *es = sbi->s_es; + unsigned def_extra_isize = sizeof(struct ext4_inode) - + EXT4_GOOD_OLD_INODE_SIZE; + + if (sbi->s_inode_size == EXT4_GOOD_OLD_INODE_SIZE) { + sbi->s_want_extra_isize = 0; + return; + } + if (sbi->s_want_extra_isize < 4) { + sbi->s_want_extra_isize = def_extra_isize; + if (EXT4_HAS_RO_COMPAT_FEATURE(sb, + EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)) { + if (sbi->s_want_extra_isize < + le16_to_cpu(es->s_want_extra_isize)) + sbi->s_want_extra_isize = + le16_to_cpu(es->s_want_extra_isize); + if (sbi->s_want_extra_isize < + le16_to_cpu(es->s_min_extra_isize)) + sbi->s_want_extra_isize = + le16_to_cpu(es->s_min_extra_isize); + } + } + /* Check if enough inode space is available */ + if ((sbi->s_want_extra_isize > sbi->s_inode_size) || + (EXT4_GOOD_OLD_INODE_SIZE + sbi->s_want_extra_isize > + sbi->s_inode_size)) { + sbi->s_want_extra_isize = def_extra_isize; + ext4_msg(sb, KERN_INFO, + "required extra inode space not available"); + } +} + static int ext4_fill_super(struct super_block *sb, void *data, int silent) { char *orig_data = kstrdup(data, GFP_KERNEL); @@ -3766,7 +3848,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) goto failed_mount2; } } - if (!ext4_check_descriptors(sb, &first_not_zeroed)) { + sbi->s_gdb_count = db_count; + if (!ext4_check_descriptors(sb, logical_sb_block, &first_not_zeroed)) { ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); goto failed_mount2; } @@ -3778,7 +3861,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) goto failed_mount2; } - sbi->s_gdb_count = db_count; get_random_bytes(&sbi->s_next_generation, sizeof(u32)); spin_lock_init(&sbi->s_next_gen_lock); @@ -3973,30 +4055,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) if (ext4_setup_super(sb, es, sb->s_flags & MS_RDONLY)) sb->s_flags |= MS_RDONLY; - /* determine the minimum size of new large inodes, if present */ - if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE) { - sbi->s_want_extra_isize = sizeof(struct ext4_inode) - - EXT4_GOOD_OLD_INODE_SIZE; - if (EXT4_HAS_RO_COMPAT_FEATURE(sb, - EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)) { - if (sbi->s_want_extra_isize < - le16_to_cpu(es->s_want_extra_isize)) - sbi->s_want_extra_isize = - le16_to_cpu(es->s_want_extra_isize); - if (sbi->s_want_extra_isize < - le16_to_cpu(es->s_min_extra_isize)) - sbi->s_want_extra_isize = - le16_to_cpu(es->s_min_extra_isize); - } - } - /* Check if enough inode space is available */ - if (EXT4_GOOD_OLD_INODE_SIZE + sbi->s_want_extra_isize > - sbi->s_inode_size) { - sbi->s_want_extra_isize = sizeof(struct ext4_inode) - - EXT4_GOOD_OLD_INODE_SIZE; - ext4_msg(sb, KERN_INFO, "required extra inode space not" - "available"); - } + ext4_clamp_want_extra_isize(sb); atomic64_set(&sbi->s_r_blocks_count, ext4_r_blocks_count(es)); diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 486f7c40..e54f0bbd 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -1332,6 +1332,11 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize, /* Find the entry best suited to be pushed into EA block */ entry = NULL; for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) { + /* never move system.data out of the inode */ + if ((last->e_name_len == 4) && + (last->e_name_index == EXT4_XATTR_INDEX_SYSTEM) && + !memcmp(last->e_name, "data", 4)) + continue; total_size = EXT4_XATTR_SIZE(le32_to_cpu(last->e_value_size)) + EXT4_XATTR_LEN(last->e_name_len); diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h index 91f31ca7..dbfcb289 100644 --- a/fs/ext4/xattr.h +++ b/fs/ext4/xattr.h @@ -21,6 +21,7 @@ #define EXT4_XATTR_INDEX_TRUSTED 4 #define EXT4_XATTR_INDEX_LUSTRE 5 #define EXT4_XATTR_INDEX_SECURITY 6 +#define EXT4_XATTR_INDEX_SYSTEM 7 struct ext4_xattr_header { __le32 h_magic; /* magic number for identification */ diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 3eee6202..0c9d220a 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -274,10 +274,11 @@ static int f2fs_write_meta_pages(struct address_space *mapping, get_pages(sbi, F2FS_DIRTY_META) < nr_pages_to_skip(sbi, META)) goto skip_write; - trace_f2fs_writepages(mapping->host, wbc, META); + /* if locked failed, cp will flush dirty pages instead */ + if (!mutex_trylock(&sbi->cp_mutex)) + goto skip_write; - /* if mounting is failed, skip writing node pages */ - mutex_lock(&sbi->cp_mutex); + trace_f2fs_writepages(mapping->host, wbc, META); diff = nr_pages_to_write(sbi, META, wbc); blk_start_plug(&plug); written = sync_meta_pages(sbi, META, wbc->nr_to_write); @@ -772,7 +773,9 @@ static void __add_dirty_inode(struct inode *inode, enum inode_type type) return; set_inode_flag(inode, flag); - list_add_tail(&F2FS_I(inode)->dirty_list, &sbi->inode_list[type]); + if (!f2fs_is_volatile_file(inode)) + list_add_tail(&F2FS_I(inode)->dirty_list, + &sbi->inode_list[type]); stat_inc_dirty_inode(sbi, type); } @@ -916,6 +919,7 @@ static int block_operations(struct f2fs_sb_info *sbi) err = sync_dirty_inodes(sbi, DIR_INODE); if (err) goto out; + cond_resched(); goto retry_flush_dents; } @@ -924,6 +928,7 @@ static int block_operations(struct f2fs_sb_info *sbi) err = f2fs_sync_inode_meta(sbi); if (err) goto out; + cond_resched(); goto retry_flush_dents; } @@ -941,6 +946,7 @@ static int block_operations(struct f2fs_sb_info *sbi) f2fs_unlock_all(sbi); goto out; } + cond_resched(); goto retry_flush_nodes; } out: diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index 9197c8d8..6a2b49d3 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c @@ -142,7 +142,11 @@ static void update_mem_info(struct f2fs_sb_info *sbi) if (si->base_mem) goto get_cache; - si->base_mem = sizeof(struct f2fs_sb_info) + sbi->sb->s_blocksize; + /* build stat */ + si->base_mem = sizeof(struct f2fs_stat_info); + + /* build superblock */ + si->base_mem += sizeof(struct f2fs_sb_info) + sbi->sb->s_blocksize; si->base_mem += 2 * sizeof(struct f2fs_inode_info); si->base_mem += sizeof(*sbi->ckpt); si->base_mem += sizeof(struct percpu_counter) * NR_COUNT_TYPE; diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 6ef8c890..4a78ab03 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1912,12 +1912,6 @@ static inline void f2fs_kvfree(void *ptr) ((is_inode_flag_set(i, FI_ACL_MODE)) ? \ (F2FS_I(i)->i_acl_mode) : ((i)->i_mode)) -/* get offset of first page in next direct node */ -#define PGOFS_OF_NEXT_DNODE(pgofs, inode) \ - ((pgofs < ADDRS_PER_INODE(inode)) ? ADDRS_PER_INODE(inode) : \ - (pgofs - ADDRS_PER_INODE(inode) + ADDRS_PER_BLOCK) / \ - ADDRS_PER_BLOCK * ADDRS_PER_BLOCK + ADDRS_PER_INODE(inode)) - /* * file.c */ diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 8ec1e70f..f55da6bf 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -110,6 +110,9 @@ static int get_parent_ino(struct inode *inode, nid_t *pino) { struct dentry *dentry; + if (file_enc_name(inode)) + return 0; + inode = igrab(inode); dentry = d_find_any_alias(inode); iput(inode); @@ -1203,8 +1206,6 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len, if (ret) return ret; - if (offset + len > new_size) - new_size = offset + len; new_size = max_t(loff_t, new_size, offset + len); } else { if (off_start) { @@ -1269,8 +1270,9 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len) int ret = 0; new_size = i_size_read(inode) + len; - if (new_size > inode->i_sb->s_maxbytes) - return -EFBIG; + ret = inode_newsize_ok(inode, new_size); + if (ret) + return ret; if (offset >= i_size_read(inode)) return -EINVAL; @@ -1494,10 +1496,10 @@ static int f2fs_ioc_setflags(struct file *filp, unsigned long arg) if (ret) return ret; - flags = f2fs_mask_flags(inode->i_mode, flags); - inode_lock(inode); + flags = f2fs_mask_flags(inode->i_mode, flags); + oldflags = fi->i_flags; if ((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) { @@ -1511,10 +1513,11 @@ static int f2fs_ioc_setflags(struct file *filp, unsigned long arg) flags = flags & FS_FL_USER_MODIFIABLE; flags |= oldflags & ~FS_FL_USER_MODIFIABLE; fi->i_flags = flags; - inode_unlock(inode); inode->i_ctime = CURRENT_TIME; f2fs_set_inode_flags(inode); + + inode_unlock(inode); out: mnt_drop_write_file(filp); return ret; @@ -1535,6 +1538,9 @@ static int f2fs_ioc_start_atomic_write(struct file *filp) if (!inode_owner_or_capable(inode)) return -EACCES; + if (!S_ISREG(inode->i_mode)) + return -EINVAL; + ret = mnt_want_write_file(filp); if (ret) return ret; @@ -1607,6 +1613,9 @@ static int f2fs_ioc_start_volatile_write(struct file *filp) if (!inode_owner_or_capable(inode)) return -EACCES; + if (!S_ISREG(inode->i_mode)) + return -EINVAL; + ret = mnt_want_write_file(filp); if (ret) return ret; @@ -2060,39 +2069,37 @@ static int f2fs_ioc_defragment(struct file *filp, unsigned long arg) if (!S_ISREG(inode->i_mode)) return -EINVAL; - err = mnt_want_write_file(filp); - if (err) - return err; - - if (f2fs_readonly(sbi->sb)) { - err = -EROFS; - goto out; - } + if (f2fs_readonly(sbi->sb)) + return -EROFS; if (copy_from_user(&range, (struct f2fs_defragment __user *)arg, - sizeof(range))) { - err = -EFAULT; - goto out; - } + sizeof(range))) + return -EFAULT; /* verify alignment of offset & size */ - if (range.start & (F2FS_BLKSIZE - 1) || - range.len & (F2FS_BLKSIZE - 1)) { - err = -EINVAL; - goto out; - } + if (range.start & (F2FS_BLKSIZE - 1) || range.len & (F2FS_BLKSIZE - 1)) + return -EINVAL; + + if (unlikely((range.start + range.len) >> PAGE_SHIFT > + sbi->max_file_blocks)) + return -EINVAL; + + err = mnt_want_write_file(filp); + if (err) + return err; err = f2fs_defragment_range(sbi, filp, &range); + mnt_drop_write_file(filp); + f2fs_update_time(sbi, REQ_TIME); if (err < 0) - goto out; + return err; if (copy_to_user((struct f2fs_defragment __user *)arg, &range, sizeof(range))) - err = -EFAULT; -out: - mnt_drop_write_file(filp); - return err; + return -EFAULT; + + return 0; } long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 2062e767..1bd1177b 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -164,7 +164,11 @@ static void select_policy(struct f2fs_sb_info *sbi, int gc_type, if (p->max_search > sbi->max_victim_search) p->max_search = sbi->max_victim_search; - p->offset = sbi->last_victim[p->gc_mode]; + /* let's select beginning hot/small space first */ + if (type == CURSEG_HOT_DATA || IS_NODESEG(type)) + p->offset = 0; + else + p->offset = sbi->last_victim[p->gc_mode]; } static unsigned int get_max_cost(struct f2fs_sb_info *sbi, @@ -174,7 +178,7 @@ static unsigned int get_max_cost(struct f2fs_sb_info *sbi, if (p->alloc_mode == SSR) return sbi->blocks_per_seg; if (p->gc_mode == GC_GREEDY) - return sbi->blocks_per_seg * p->ofs_unit; + return 2 * sbi->blocks_per_seg * p->ofs_unit; else if (p->gc_mode == GC_CB) return UINT_MAX; else /* No other gc_mode */ @@ -337,6 +341,7 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi, sbi->last_victim[p.gc_mode] = last_victim + 1; else sbi->last_victim[p.gc_mode] = segno + 1; + sbi->last_victim[p.gc_mode] %= MAIN_SEGS(sbi); break; } } @@ -520,8 +525,10 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, get_node_info(sbi, nid, dni); if (sum->version != dni->version) { - f2fs_put_page(node_page, 1); - return false; + f2fs_msg(sbi->sb, KERN_WARNING, + "%s: valid data with mismatched node version.", + __func__); + set_sbi_flag(sbi, SBI_NEED_FSCK); } *nofs = ofs_of_node(node_page); diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index b9b7459f..e1990489 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -383,7 +383,10 @@ void f2fs_evict_inode(struct inode *inode) stat_dec_inline_dir(inode); stat_dec_inline_inode(inode); - invalidate_mapping_pages(NODE_MAPPING(sbi), inode->i_ino, inode->i_ino); + /* ino == 0, if f2fs_new_inode() was failed t*/ + if (inode->i_ino) + invalidate_mapping_pages(NODE_MAPPING(sbi), inode->i_ino, + inode->i_ino); if (xnid) invalidate_mapping_pages(NODE_MAPPING(sbi), xnid, xnid); if (is_inode_flag_set(inode, FI_APPEND_WRITE)) diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index c6ffdf8c..2359cb66 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -75,8 +75,9 @@ bool available_free_memory(struct f2fs_sb_info *sbi, int type) int i; for (i = 0; i <= UPDATE_INO; i++) - mem_size += (sbi->im[i].ino_num * - sizeof(struct ino_entry)) >> PAGE_SHIFT; + mem_size += sbi->im[i].ino_num * + sizeof(struct ino_entry); + mem_size >>= PAGE_SHIFT; res = mem_size < ((avail_ram * nm_i->ram_thresh / 100) >> 1); } else if (type == EXTENT_CACHE) { mem_size = (atomic_read(&sbi->total_ext_tree) * @@ -379,6 +380,7 @@ void get_node_info(struct f2fs_sb_info *sbi, nid_t nid, struct node_info *ni) struct page *page = NULL; struct f2fs_nat_entry ne; struct nat_entry *e; + pgoff_t index; int i; ni->nid = nid; @@ -404,17 +406,21 @@ void get_node_info(struct f2fs_sb_info *sbi, nid_t nid, struct node_info *ni) node_info_from_raw_nat(ni, &ne); } up_read(&curseg->journal_rwsem); - if (i >= 0) + if (i >= 0) { + up_read(&nm_i->nat_tree_lock); goto cache; + } /* Fill node_info from nat page */ - page = get_current_nat_page(sbi, start_nid); + index = current_nat_addr(sbi, nid); + up_read(&nm_i->nat_tree_lock); + + page = get_meta_page(sbi, index); nat_blk = (struct f2fs_nat_block *)page_address(page); ne = nat_blk->entries[nid - start_nid]; node_info_from_raw_nat(ni, &ne); f2fs_put_page(page, 1); cache: - up_read(&nm_i->nat_tree_lock); /* cache nat entry */ down_write(&nm_i->nat_tree_lock); cache_nat_entry(sbi, nid, &ne); @@ -1381,6 +1387,9 @@ int fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode, f2fs_wait_on_page_writeback(page, NODE, true); BUG_ON(PageWriteback(page)); + set_fsync_mark(page, 0); + set_dentry_mark(page, 0); + if (!atomic || page == last_page) { set_fsync_mark(page, 1); if (IS_INODE(page)) { @@ -1796,6 +1805,9 @@ void build_free_nids(struct f2fs_sb_info *sbi) int i = 0; nid_t nid = nm_i->next_scan_nid; + if (unlikely(nid >= nm_i->max_nid)) + nid = 0; + /* Enough entries */ if (nm_i->fcnt >= NAT_ENTRY_PER_BLOCK) return; diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h index fc768455..b6c24574 100644 --- a/fs/f2fs/node.h +++ b/fs/f2fs/node.h @@ -193,13 +193,16 @@ static inline pgoff_t current_nat_addr(struct f2fs_sb_info *sbi, nid_t start) struct f2fs_nm_info *nm_i = NM_I(sbi); pgoff_t block_off; pgoff_t block_addr; - int seg_off; + /* + * block_off = segment_off * 512 + off_in_segment + * OLD = (segment_off * 512) * 2 + off_in_segment + * NEW = 2 * (segment_off * 512 + off_in_segment) - off_in_segment + */ block_off = NAT_BLOCK_OFFSET(start); - seg_off = block_off >> sbi->log_blocks_per_seg; block_addr = (pgoff_t)(nm_i->nat_blkaddr + - (seg_off << sbi->log_blocks_per_seg << 1) + + (block_off << 1) - (block_off & (sbi->blocks_per_seg - 1))); if (f2fs_test_bit(block_off, nm_i->nat_bitmap)) diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 011646af..2d39ed89 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -903,6 +903,12 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, block_t blkaddr, int del) f2fs_bug_on(sbi, 1); if (!f2fs_test_and_set_bit(offset, se->discard_map)) sbi->discard_blks--; + + /* don't overwrite by SSR to keep node chain */ + if (se->type == CURSEG_WARM_NODE) { + if (!f2fs_test_and_set_bit(offset, se->ckpt_valid_map)) + se->ckpt_valid_blocks++; + } } else { if (!f2fs_test_and_clear_bit(offset, se->cur_valid_map)) f2fs_bug_on(sbi, 1); @@ -1191,6 +1197,14 @@ static void reset_curseg(struct f2fs_sb_info *sbi, int type, int modified) __set_sit_entry_type(sbi, type, curseg->segno, modified); } +static unsigned int __get_next_segno(struct f2fs_sb_info *sbi, int type) +{ + if (type == CURSEG_HOT_DATA || IS_NODESEG(type)) + return 0; + + return CURSEG_I(sbi, type)->segno; +} + /* * Allocate a current working segment. * This function always allocates a free segment in LFS manner. @@ -1209,6 +1223,7 @@ static void new_curseg(struct f2fs_sb_info *sbi, int type, bool new_sec) if (test_opt(sbi, NOHEAP)) dir = ALLOC_RIGHT; + segno = __get_next_segno(sbi, type); get_new_segment(sbi, &segno, new_sec, dir); curseg->next_segno = segno; reset_curseg(sbi, type, 1); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index e9293552..b11dedbe 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -77,6 +77,7 @@ enum { Opt_discard, Opt_nodiscard, Opt_noheap, + Opt_heap, Opt_user_xattr, Opt_nouser_xattr, Opt_acl, @@ -106,6 +107,7 @@ static match_table_t f2fs_tokens = { {Opt_discard, "discard"}, {Opt_nodiscard, "nodiscard"}, {Opt_noheap, "no_heap"}, + {Opt_heap, "heap"}, {Opt_user_xattr, "user_xattr"}, {Opt_nouser_xattr, "nouser_xattr"}, {Opt_acl, "acl"}, @@ -428,6 +430,9 @@ static int parse_options(struct super_block *sb, char *options) case Opt_noheap: set_opt(sbi, NOHEAP); break; + case Opt_heap: + clear_opt(sbi, NOHEAP); + break; #ifdef CONFIG_F2FS_FS_XATTR case Opt_user_xattr: set_opt(sbi, XATTR_USER); @@ -836,7 +841,9 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root) if (test_opt(sbi, DISCARD)) seq_puts(seq, ",discard"); if (test_opt(sbi, NOHEAP)) - seq_puts(seq, ",no_heap_alloc"); + seq_puts(seq, ",no_heap"); + else + seq_puts(seq, ",heap"); #ifdef CONFIG_F2FS_FS_XATTR if (test_opt(sbi, XATTR_USER)) seq_puts(seq, ",user_xattr"); @@ -958,6 +965,7 @@ static void default_options(struct f2fs_sb_info *sbi) set_opt(sbi, BG_GC); set_opt(sbi, INLINE_DATA); set_opt(sbi, EXTENT_CACHE); + set_opt(sbi, NOHEAP); set_opt(sbi, FLUSH_MERGE); if (f2fs_sb_mounted_hmsmr(sbi->sb)) { set_opt_mode(sbi, F2FS_MOUNT_LFS); @@ -1397,6 +1405,13 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi, return 1; } + if (le32_to_cpu(raw_super->segment_count) > F2FS_MAX_SEGMENT) { + f2fs_msg(sb, KERN_INFO, + "Invalid segment count (%u)", + le32_to_cpu(raw_super->segment_count)); + return 1; + } + /* check CP/SIT/NAT/SSA/MAIN_AREA area boundary */ if (sanity_check_area_boundary(sbi, bh)) return 1; @@ -1763,6 +1778,10 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) f2fs_join_shrinker(sbi); + err = f2fs_build_stats(sbi); + if (err) + goto free_nm; + /* if there are nt orphan nodes free them */ err = recover_orphan_inodes(sbi); if (err) @@ -1787,10 +1806,6 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) goto free_root_inode; } - err = f2fs_build_stats(sbi); - if (err) - goto free_root_inode; - if (f2fs_proc_root) sbi->s_proc = proc_mkdir(sb->s_id, f2fs_proc_root); @@ -1879,7 +1894,6 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) remove_proc_entry("segment_bits", sbi->s_proc); remove_proc_entry(sb->s_id, f2fs_proc_root); } - f2fs_destroy_stats(sbi); free_root_inode: dput(sb->s_root); sb->s_root = NULL; @@ -1888,6 +1902,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) f2fs_leave_shrinker(sbi); iput(sbi->node_inode); mutex_unlock(&sbi->umount_mutex); + f2fs_destroy_stats(sbi); free_nm: destroy_node_manager(sbi); free_sm: diff --git a/fs/f2fs/trace.c b/fs/f2fs/trace.c index 562ce082..fff34850 100644 --- a/fs/f2fs/trace.c +++ b/fs/f2fs/trace.c @@ -59,7 +59,7 @@ void f2fs_trace_pid(struct page *page) pid_t pid = task_pid_nr(current); void *p; - page->private = pid; + set_page_private(page, (unsigned long)pid); if (radix_tree_preload(GFP_NOFS)) return; @@ -137,7 +137,7 @@ static unsigned int gang_lookup_pids(pid_t *results, unsigned long first_index, radix_tree_for_each_slot(slot, &pids, &iter, first_index) { results[ret] = iter.index; - if (++ret == PIDVEC_SIZE) + if (++ret == max_items) break; } return ret; diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 85a854e3..098e9078 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c @@ -1535,8 +1535,11 @@ static void drop_sysctl_table(struct ctl_table_header *header) if (--header->nreg) return; - put_links(header); - start_unregistering(header); + if (parent) { + put_links(header); + start_unregistering(header); + } + if (!--header->count) kfree_rcu(header, rcu); diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 1368e20a..77da11f2 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -172,7 +172,7 @@ static void *m_start(struct seq_file *m, loff_t *pos) return mm; down_read(&mm->mmap_sem); - tail_vma = get_gate_vma(priv->task->mm); + tail_vma = get_gate_vma(mm); priv->tail_vma = tail_vma; /* Start with last addr hint */ @@ -348,12 +348,11 @@ static int show_map(struct seq_file *m, void *v, int is_pid) { struct vm_area_struct *vma = v; struct proc_maps_private *priv = m->private; - struct task_struct *task = priv->task; show_map_vma(m, vma, is_pid); if (m->count < m->size) /* vma is copied successfully */ - m->version = (vma != get_gate_vma(task->mm)) + m->version = (vma != priv->tail_vma) ? vma->vm_start : 0; return 0; } @@ -531,7 +530,6 @@ static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, static int show_smap(struct seq_file *m, void *v, int is_pid) { struct proc_maps_private *priv = m->private; - struct task_struct *task = priv->task; struct vm_area_struct *vma = v; struct mem_size_stats mss; struct mm_walk smaps_walk = { @@ -588,7 +586,7 @@ static int show_smap(struct seq_file *m, void *v, int is_pid) } if (m->count < m->size) /* vma is copied successfully */ - m->version = (vma != get_gate_vma(task->mm)) + m->version = (vma != priv->tail_vma) ? vma->vm_start : 0; return 0; } diff --git a/include/Kbuild b/include/Kbuild index 5f65ac28..a3f8df15 100644 --- a/include/Kbuild +++ b/include/Kbuild @@ -11,3 +11,4 @@ header-y += drm/ header-y += xen/ header-y += scsi/ header-y += media/ +header-y += uapi/ diff --git a/include/asm-generic/Kbuild.asm b/include/asm-generic/Kbuild.asm index c5d2e5dd..d2ee86b4 100644 --- a/include/asm-generic/Kbuild.asm +++ b/include/asm-generic/Kbuild.asm @@ -1,45 +1 @@ -ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/kvm.h \ - $(srctree)/include/asm-$(SRCARCH)/kvm.h),) -header-y += kvm.h -endif - -ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/kvm_para.h \ - $(srctree)/include/asm-$(SRCARCH)/kvm_para.h),) -header-y += kvm_para.h -endif - -ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/a.out.h \ - $(srctree)/include/asm-$(SRCARCH)/a.out.h),) -header-y += a.out.h -endif - -header-y += auxvec.h -header-y += bitsperlong.h -header-y += byteorder.h -header-y += errno.h -header-y += fcntl.h -header-y += ioctl.h -header-y += ioctls.h -header-y += ipcbuf.h -header-y += mman.h -header-y += msgbuf.h -header-y += param.h -header-y += poll.h -header-y += posix_types.h -header-y += ptrace.h -header-y += resource.h -header-y += sembuf.h -header-y += setup.h -header-y += shmbuf.h -header-y += sigcontext.h -header-y += siginfo.h -header-y += signal.h -header-y += socket.h -header-y += sockios.h -header-y += stat.h -header-y += statfs.h -header-y += swab.h -header-y += termbits.h -header-y += termios.h -header-y += types.h -header-y += unistd.h +include include/uapi/asm-generic/Kbuild.asm diff --git a/include/asm-generic/unistd.h b/include/asm-generic/unistd.h index 440c728d..66505208 100644 --- a/include/asm-generic/unistd.h +++ b/include/asm-generic/unistd.h @@ -695,9 +695,11 @@ __SC_COMP(__NR_process_vm_writev, sys_process_vm_writev, \ __SYSCALL(__NR_seccomp, sys_seccomp) #define __NR_getrandom 278 __SYSCALL(__NR_getrandom, sys_getrandom) +#define __NR_memfd_create 279 +__SYSCALL(__NR_memfd_create, sys_memfd_create) #undef __NR_syscalls -#define __NR_syscalls 279 +#define __NR_syscalls 280 /* * All syscalls below here should go away really, diff --git a/include/linux/Kbuild b/include/linux/Kbuild index c9db3aa1..c6dce24e 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -21,8 +21,6 @@ header-y += usb/ header-y += wimax/ header-y += mfd/ -objhdr-y += version.h - ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/a.out.h \ $(srctree)/include/asm-$(SRCARCH)/a.out.h \ $(INSTALL_HDR_PATH)/include/asm-*/a.out.h),) diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index 6ab6fd05..11698944 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h @@ -209,6 +209,12 @@ #endif #endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */ +#if GCC_VERSION >= 50000 +#define KASAN_ABI_VERSION 4 +#elif GCC_VERSION >= 40902 +#define KASAN_ABI_VERSION 3 +#endif + #endif /* gcc version >= 40000 specific checks */ #if !defined(__noclone) diff --git a/include/linux/device.h b/include/linux/device.h index 5bf8909d..1910cf77 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -24,6 +24,7 @@ #include #include #include +#include #include struct device; @@ -950,6 +951,32 @@ int _dev_info(const struct device *dev, const char *fmt, ...) #endif +#define dev_level_ratelimited(dev_level, dev, fmt, ...) \ +do { \ + static DEFINE_RATELIMIT_STATE(_rs, \ + DEFAULT_RATELIMIT_INTERVAL, \ + DEFAULT_RATELIMIT_BURST); \ + if (__ratelimit(&_rs)) \ + dev_level(dev, fmt, ##__VA_ARGS__); \ +} while (0) + +#define dev_emerg_ratelimited(dev, fmt, ...) \ + dev_level_ratelimited(dev_emerg, dev, fmt, ##__VA_ARGS__) +#define dev_alert_ratelimited(dev, fmt, ...) \ + dev_level_ratelimited(dev_alert, dev, fmt, ##__VA_ARGS__) +#define dev_crit_ratelimited(dev, fmt, ...) \ + dev_level_ratelimited(dev_crit, dev, fmt, ##__VA_ARGS__) +#define dev_err_ratelimited(dev, fmt, ...) \ + dev_level_ratelimited(dev_err, dev, fmt, ##__VA_ARGS__) +#define dev_warn_ratelimited(dev, fmt, ...) \ + dev_level_ratelimited(dev_warn, dev, fmt, ##__VA_ARGS__) +#define dev_notice_ratelimited(dev, fmt, ...) \ + dev_level_ratelimited(dev_notice, dev, fmt, ##__VA_ARGS__) +#define dev_info_ratelimited(dev, fmt, ...) \ + dev_level_ratelimited(dev_info, dev, fmt, ##__VA_ARGS__) +#define dev_dbg_ratelimited(dev, fmt, ...) \ + dev_level_ratelimited(dev_dbg, dev, fmt, ##__VA_ARGS__) + /* * Stupid hackaround for existing uses of non-printk uses dev_info * diff --git a/include/linux/siphash.h b/include/linux/siphash.h new file mode 100644 index 00000000..c8c7ae2e --- /dev/null +++ b/include/linux/siphash.h @@ -0,0 +1,90 @@ +/* Copyright (C) 2016 Jason A. Donenfeld . All Rights Reserved. + * + * This file is provided under a dual BSD/GPLv2 license. + * + * SipHash: a fast short-input PRF + * https://131002.net/siphash/ + * + * This implementation is specifically for SipHash2-4. + */ + +#ifndef _LINUX_SIPHASH_H +#define _LINUX_SIPHASH_H + +#include +#include + +#define SIPHASH_ALIGNMENT __alignof__(u64) +typedef struct { + u64 key[2]; +} siphash_key_t; + +static inline bool siphash_key_is_zero(const siphash_key_t *key) +{ + return !(key->key[0] | key->key[1]); +} + +u64 __siphash_aligned(const void *data, size_t len, const siphash_key_t *key); +#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS +u64 __siphash_unaligned(const void *data, size_t len, const siphash_key_t *key); +#endif + +u64 siphash_1u64(const u64 a, const siphash_key_t *key); +u64 siphash_2u64(const u64 a, const u64 b, const siphash_key_t *key); +u64 siphash_3u64(const u64 a, const u64 b, const u64 c, + const siphash_key_t *key); +u64 siphash_4u64(const u64 a, const u64 b, const u64 c, const u64 d, + const siphash_key_t *key); +u64 siphash_1u32(const u32 a, const siphash_key_t *key); +u64 siphash_3u32(const u32 a, const u32 b, const u32 c, + const siphash_key_t *key); + +static inline u64 siphash_2u32(const u32 a, const u32 b, + const siphash_key_t *key) +{ + return siphash_1u64((u64)b << 32 | a, key); +} +static inline u64 siphash_4u32(const u32 a, const u32 b, const u32 c, + const u32 d, const siphash_key_t *key) +{ + return siphash_2u64((u64)b << 32 | a, (u64)d << 32 | c, key); +} + + +static inline u64 ___siphash_aligned(const __le64 *data, size_t len, + const siphash_key_t *key) +{ + if (__builtin_constant_p(len) && len == 4) + return siphash_1u32(le32_to_cpup((const __le32 *)data), key); + if (__builtin_constant_p(len) && len == 8) + return siphash_1u64(le64_to_cpu(data[0]), key); + if (__builtin_constant_p(len) && len == 16) + return siphash_2u64(le64_to_cpu(data[0]), le64_to_cpu(data[1]), + key); + if (__builtin_constant_p(len) && len == 24) + return siphash_3u64(le64_to_cpu(data[0]), le64_to_cpu(data[1]), + le64_to_cpu(data[2]), key); + if (__builtin_constant_p(len) && len == 32) + return siphash_4u64(le64_to_cpu(data[0]), le64_to_cpu(data[1]), + le64_to_cpu(data[2]), le64_to_cpu(data[3]), + key); + return __siphash_aligned(data, len, key); +} + +/** + * siphash - compute 64-bit siphash PRF value + * @data: buffer to hash + * @size: size of @data + * @key: the siphash key + */ +static inline u64 siphash(const void *data, size_t len, + const siphash_key_t *key) +{ +#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS + if (!IS_ALIGNED((unsigned long)data, SIPHASH_ALIGNMENT)) + return __siphash_unaligned(data, len, key); +#endif + return ___siphash_aligned(data, len, key); +} + +#endif /* _LINUX_SIPHASH_H */ diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index bd9ef27c..7d3db143 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -813,6 +813,7 @@ asmlinkage long sys_timerfd_settime(int ufd, int flags, asmlinkage long sys_timerfd_gettime(int ufd, struct itimerspec __user *otmr); asmlinkage long sys_eventfd(unsigned int count); asmlinkage long sys_eventfd2(unsigned int count, int flags); +asmlinkage long sys_memfd_create(const char __user *uname_ptr, unsigned int flags); asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len); asmlinkage long sys_old_readdir(unsigned int, struct old_linux_dirent __user *, unsigned int); asmlinkage long sys_pselect6(int, fd_set __user *, fd_set __user *, diff --git a/include/net/af_unix.h b/include/net/af_unix.h index 97dcf4f6..ffabf493 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -6,8 +6,8 @@ #include #include -void unix_inflight(struct user_struct *user, struct file *fp); -void unix_notinflight(struct user_struct *user, struct file *fp); +extern void unix_inflight(struct user_struct *user, struct file *fp); +extern void unix_notinflight(struct user_struct *user, struct file *fp); extern void unix_gc(void); extern void wait_for_unix_gc(void); extern struct sock *unix_get_socket(struct file *filp); diff --git a/include/net/ip.h b/include/net/ip.h index c2425b2a..6ce79c12 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -271,9 +271,10 @@ int ip_dont_fragment(struct sock *sk, struct dst_entry *dst) } u32 ip_idents_reserve(u32 hash, int segs); -void __ip_select_ident(struct iphdr *iph, int segs); +void __ip_select_ident(struct net *net, struct iphdr *iph, int segs); -static inline void ip_select_ident_segs(struct sk_buff *skb, struct sock *sk, int segs) +static inline void ip_select_ident_segs(struct net *net, struct sk_buff *skb, + struct sock *sk, int segs) { struct iphdr *iph = ip_hdr(skb); @@ -290,13 +291,14 @@ static inline void ip_select_ident_segs(struct sk_buff *skb, struct sock *sk, in iph->id = 0; } } else { - __ip_select_ident(iph, segs); + __ip_select_ident(net, iph, segs); } } -static inline void ip_select_ident(struct sk_buff *skb, struct sock *sk) +static inline void ip_select_ident(struct net *net, struct sk_buff *skb, + struct sock *sk) { - ip_select_ident_segs(skb, sk, 1); + ip_select_ident_segs(net, skb, sk, 1); } /* diff --git a/include/net/ipip.h b/include/net/ipip.h index e8ee3bb1..98ca3327 100644 --- a/include/net/ipip.h +++ b/include/net/ipip.h @@ -3,6 +3,7 @@ #include #include +#include /* Keep error state on tunnel for 30 sec */ #define IPTUNNEL_ERR_TIMEO (30*HZ) @@ -50,7 +51,7 @@ struct ip_tunnel_prl_entry { int pkt_len = skb->len - skb_transport_offset(skb); \ \ skb->ip_summed = CHECKSUM_NONE; \ - ip_select_ident(skb, NULL); \ + ip_select_ident(dev_net(rt->dst.dev), skb, NULL); \ \ err = ip_local_out(skb); \ if (likely(net_xmit_eval(err) == 0)) { \ diff --git a/include/net/ipv6.h b/include/net/ipv6.h index b55d3466..b6589f19 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -526,8 +526,9 @@ static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_add return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr)); } -extern void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt); -void ipv6_proxy_select_ident(struct sk_buff *skb); +extern void ipv6_select_ident(struct net *net, struct frag_hdr *fhdr, + struct rt6_info *rt); +void ipv6_proxy_select_ident(struct net *net, struct sk_buff *skb); /* * Prototypes exported by ipv6 diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index 6e6b175e..1f126457 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -50,6 +50,8 @@ struct net { #endif spinlock_t rules_mod_lock; + u32 hash_mix; + struct list_head list; /* list of network namespaces */ struct list_head cleanup_list; /* namespaces on death row */ struct list_head exit_list; /* Use only net_mutex */ diff --git a/include/net/netns/hash.h b/include/net/netns/hash.h index 548d78f2..b516001d 100644 --- a/include/net/netns/hash.h +++ b/include/net/netns/hash.h @@ -1,21 +1,10 @@ #ifndef __NET_NS_HASH_H__ #define __NET_NS_HASH_H__ -#include - -struct net; +#include static inline unsigned net_hash_mix(struct net *net) { -#ifdef CONFIG_NET_NS - /* - * shift this right to eliminate bits, that are - * always zeroed - */ - - return (unsigned)(((unsigned long)net) >> L1_CACHE_SHIFT); -#else - return 0; -#endif + return net->hash_mix; } #endif diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h index adbe8c6e..d39cf0e4 100644 --- a/include/net/netns/ipv4.h +++ b/include/net/netns/ipv4.h @@ -6,6 +6,7 @@ #define __NETNS_IPV4_H__ #include +#include struct ctl_table_header; struct ipv4_devconf; @@ -68,5 +69,6 @@ struct netns_ipv4 { struct fib_rules_ops *mr_rules_ops; #endif #endif + siphash_key_t ip_id_key; }; #endif diff --git a/include/net/tcp.h b/include/net/tcp.h index eb72aa60..e5a46108 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1252,6 +1252,8 @@ extern int tcp_md5_hash_skb_data(struct tcp_md5sig_pool *, const struct sk_buff extern int tcp_md5_hash_key(struct tcp_md5sig_pool *hp, const struct tcp_md5sig_key *key); +static inline void tcp_init_send_head(struct sock *sk); + /* write queue abstraction */ static inline void tcp_write_queue_purge(struct sock *sk) { @@ -1259,6 +1261,7 @@ static inline void tcp_write_queue_purge(struct sock *sk) while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) sk_wmem_free_skb(sk, skb); + tcp_init_send_head(sk); sk_mem_reclaim(sk); tcp_clear_all_retrans_hints(tcp_sk(sk)); } diff --git a/include/uapi/Kbuild b/include/uapi/Kbuild new file mode 100644 index 00000000..3098462d --- /dev/null +++ b/include/uapi/Kbuild @@ -0,0 +1,15 @@ +# UAPI Header export list +# Top-level Makefile calls into asm-$(ARCH) +# List only non-arch directories below + + +header-y += asm-generic/ +header-y += linux/ +header-y += sound/ +header-y += mtd/ +header-y += rdma/ +header-y += video/ +header-y += drm/ +header-y += xen/ +header-y += scsi/ +header-y += media/ diff --git a/include/uapi/asm-generic/Kbuild b/include/uapi/asm-generic/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/asm-generic/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/asm-generic/Kbuild.asm b/include/uapi/asm-generic/Kbuild.asm new file mode 100644 index 00000000..fcd50b75 --- /dev/null +++ b/include/uapi/asm-generic/Kbuild.asm @@ -0,0 +1,49 @@ +# +# Headers that are optional in usr/include/asm/ +# +opt-header += kvm.h +opt-header += kvm_para.h +opt-header += a.out.h + +# +# Headers that are mandatory in usr/include/asm/ +# +header-y += auxvec.h +header-y += bitsperlong.h +header-y += byteorder.h +header-y += errno.h +header-y += fcntl.h +header-y += ioctl.h +header-y += ioctls.h +header-y += ipcbuf.h +header-y += mman.h +header-y += msgbuf.h +header-y += param.h +header-y += poll.h +header-y += posix_types.h +header-y += ptrace.h +header-y += resource.h +header-y += sembuf.h +header-y += setup.h +header-y += shmbuf.h +header-y += sigcontext.h +header-y += siginfo.h +header-y += signal.h +header-y += socket.h +header-y += sockios.h +header-y += stat.h +header-y += statfs.h +header-y += swab.h +header-y += termbits.h +header-y += termios.h +header-y += types.h +header-y += unistd.h + +header-y += $(foreach hdr,$(opt-header), \ + $(if \ + $(wildcard \ + $(srctree)/arch/$(SRCARCH)/include/uapi/asm/$(hdr) \ + $(srctree)/arch/$(SRCARCH)/include/asm/$(hdr) \ + ), \ + $(hdr) \ + )) diff --git a/include/uapi/drm/Kbuild b/include/uapi/drm/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/drm/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild new file mode 100644 index 00000000..b0fd4d03 --- /dev/null +++ b/include/uapi/linux/Kbuild @@ -0,0 +1,24 @@ +# UAPI Header export list +header-y += byteorder/ +header-y += can/ +header-y += caif/ +header-y += dvb/ +header-y += hdlc/ +header-y += hsi/ +header-y += isdn/ +header-y += mmc/ +header-y += nfsd/ +header-y += raid/ +header-y += spi/ +header-y += sunrpc/ +header-y += tc_act/ +header-y += tc_ematch/ +header-y += netfilter/ +header-y += netfilter_arp/ +header-y += netfilter_bridge/ +header-y += netfilter_ipv4/ +header-y += netfilter_ipv6/ +header-y += usb/ +header-y += wimax/ + +genhdr-y += version.h diff --git a/include/uapi/linux/byteorder/Kbuild b/include/uapi/linux/byteorder/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/linux/byteorder/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/linux/caif/Kbuild b/include/uapi/linux/caif/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/linux/caif/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/linux/can/Kbuild b/include/uapi/linux/can/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/linux/can/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/linux/dvb/Kbuild b/include/uapi/linux/dvb/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/linux/dvb/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/linux/hdlc/Kbuild b/include/uapi/linux/hdlc/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/linux/hdlc/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/linux/hsi/Kbuild b/include/uapi/linux/hsi/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/linux/hsi/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/linux/isdn/Kbuild b/include/uapi/linux/isdn/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/linux/isdn/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/linux/memfd.h b/include/uapi/linux/memfd.h new file mode 100644 index 00000000..534e364b --- /dev/null +++ b/include/uapi/linux/memfd.h @@ -0,0 +1,8 @@ +#ifndef _UAPI_LINUX_MEMFD_H +#define _UAPI_LINUX_MEMFD_H + +/* flags for memfd_create(2) (unsigned int) */ +#define MFD_CLOEXEC 0x0001U +#define MFD_ALLOW_SEALING 0x0002U + +#endif /* _UAPI_LINUX_MEMFD_H */ diff --git a/include/uapi/linux/mfd/Kbuild b/include/uapi/linux/mfd/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/linux/mfd/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/linux/mfd/wcd9xxx/Kbuild b/include/uapi/linux/mfd/wcd9xxx/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/linux/mfd/wcd9xxx/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/linux/mmc/Kbuild b/include/uapi/linux/mmc/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/linux/mmc/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/linux/netfilter/Kbuild b/include/uapi/linux/netfilter/Kbuild new file mode 100644 index 00000000..4afbace8 --- /dev/null +++ b/include/uapi/linux/netfilter/Kbuild @@ -0,0 +1,2 @@ +# UAPI Header export list +header-y += ipset/ diff --git a/include/uapi/linux/netfilter/ipset/Kbuild b/include/uapi/linux/netfilter/ipset/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/linux/netfilter/ipset/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/linux/netfilter_arp/Kbuild b/include/uapi/linux/netfilter_arp/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/linux/netfilter_arp/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/linux/netfilter_bridge/Kbuild b/include/uapi/linux/netfilter_bridge/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/linux/netfilter_bridge/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/linux/netfilter_ipv4/Kbuild b/include/uapi/linux/netfilter_ipv4/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/linux/netfilter_ipv4/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/linux/netfilter_ipv6/Kbuild b/include/uapi/linux/netfilter_ipv6/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/linux/netfilter_ipv6/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/linux/nfsd/Kbuild b/include/uapi/linux/nfsd/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/linux/nfsd/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/linux/raid/Kbuild b/include/uapi/linux/raid/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/linux/raid/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/linux/spi/Kbuild b/include/uapi/linux/spi/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/linux/spi/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/linux/sunrpc/Kbuild b/include/uapi/linux/sunrpc/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/linux/sunrpc/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/linux/tc_act/Kbuild b/include/uapi/linux/tc_act/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/linux/tc_act/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/linux/tc_ematch/Kbuild b/include/uapi/linux/tc_ematch/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/linux/tc_ematch/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/linux/usb/Kbuild b/include/uapi/linux/usb/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/linux/usb/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/linux/wimax/Kbuild b/include/uapi/linux/wimax/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/linux/wimax/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/media/Kbuild b/include/uapi/media/Kbuild new file mode 100644 index 00000000..ee8b0a38 --- /dev/null +++ b/include/uapi/media/Kbuild @@ -0,0 +1 @@ +header-y += msm_media_info.h diff --git a/include/media/msm_media_info.h b/include/uapi/media/msm_media_info.h similarity index 100% rename from include/media/msm_media_info.h rename to include/uapi/media/msm_media_info.h diff --git a/include/uapi/mtd/Kbuild b/include/uapi/mtd/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/mtd/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/rdma/Kbuild b/include/uapi/rdma/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/rdma/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/scsi/Kbuild b/include/uapi/scsi/Kbuild new file mode 100644 index 00000000..29a87dd2 --- /dev/null +++ b/include/uapi/scsi/Kbuild @@ -0,0 +1,2 @@ +# UAPI Header export list +header-y += fc/ diff --git a/include/uapi/scsi/fc/Kbuild b/include/uapi/scsi/fc/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/scsi/fc/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/sound/Kbuild b/include/uapi/sound/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/sound/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/video/Kbuild b/include/uapi/video/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/video/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/include/uapi/xen/Kbuild b/include/uapi/xen/Kbuild new file mode 100644 index 00000000..aafaa5aa --- /dev/null +++ b/include/uapi/xen/Kbuild @@ -0,0 +1 @@ +# UAPI Header export list diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 93c2b38a..6c719469 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1698,32 +1698,32 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts (context->return_valid==AUDITSC_SUCCESS)?"yes":"no", context->return_code); - spin_lock_irq(&tsk->sighand->siglock); - if (tsk->signal && tsk->signal->tty && tsk->signal->tty->name) - tty = tsk->signal->tty->name; - else - tty = "(none)"; - spin_unlock_irq(&tsk->sighand->siglock); - - audit_log_format(ab, - " a0=%lx a1=%lx a2=%lx a3=%lx items=%d" - " ppid=%d ppcomm=%s pid=%d auid=%u uid=%u gid=%u" - " euid=%u suid=%u fsuid=%u" - " egid=%u sgid=%u fsgid=%u tty=%s ses=%u", - context->argv[0], - context->argv[1], - context->argv[2], - context->argv[3], - context->name_count, - context->ppid, - tsk->parent->comm, - context->pid, - tsk->loginuid, - context->uid, - context->gid, - context->euid, context->suid, context->fsuid, - context->egid, context->sgid, context->fsgid, tty, - tsk->sessionid); + spin_lock_irq(&tsk->sighand->siglock); + if (tsk->signal && tsk->signal->tty && tsk->signal->tty->name) + tty = tsk->signal->tty->name; + else + tty = "(none)"; + spin_unlock_irq(&tsk->sighand->siglock); + + audit_log_format(ab, + " a0=%lx a1=%lx a2=%lx a3=%lx items=%d" + " ppid=%d ppcomm=%s pid=%d auid=%u uid=%u gid=%u" + " euid=%u suid=%u fsuid=%u" + " egid=%u sgid=%u fsgid=%u tty=%s ses=%u", + context->argv[0], + context->argv[1], + context->argv[2], + context->argv[3], + context->name_count, + context->ppid, + tsk->parent->comm, + context->pid, + tsk->loginuid, + context->uid, + context->gid, + context->euid, context->suid, context->fsuid, + context->egid, context->sgid, context->fsgid, tty, + tsk->sessionid); audit_log_task_info(ab, tsk); diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 2b39657a..29bb4fcd 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -1906,9 +1906,6 @@ void sched_fork(struct task_struct *p) if (!rt_prio(p->prio)) p->sched_class = &fair_sched_class; - if (p->sched_class->task_fork) - p->sched_class->task_fork(p); - /* * The child is not yet in the pid-hash so no cgroup attach races, * and the cgroup is pinned to this child due to cgroup_fork() @@ -1917,7 +1914,13 @@ void sched_fork(struct task_struct *p) * Silence PROVE_RCU. */ raw_spin_lock_irqsave(&p->pi_lock, flags); - set_task_cpu(p, cpu); + /* + * We're setting the cpu for the first time, we don't migrate, + * so use __set_task_cpu(). + */ + __set_task_cpu(p, cpu); + if (p->sched_class->task_fork) + p->sched_class->task_fork(p); raw_spin_unlock_irqrestore(&p->pi_lock, flags); #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) @@ -1956,8 +1959,11 @@ void wake_up_new_task(struct task_struct *p) * Fork balancing, do it here and not earlier because: * - cpus_allowed can change in the fork path * - any previously selected cpu might disappear through hotplug + * + * Use __set_task_cpu() to avoid calling sched_class::migrate_task_rq, + * as we're not fully set-up yet. */ - set_task_cpu(p, select_task_rq(p, SD_BALANCE_FORK, 0)); + __set_task_cpu(p, select_task_rq(p, SD_BALANCE_FORK, 0)); #endif rq = __task_rq_lock(p); @@ -2447,10 +2453,13 @@ static long calc_load_fold_active(struct rq *this_rq) static unsigned long calc_load(unsigned long load, unsigned long exp, unsigned long active) { - load *= exp; - load += active * (FIXED_1 - exp); - load += 1UL << (FSHIFT - 1); - return load >> FSHIFT; + unsigned long newload; + + newload = load * exp + active * (FIXED_1 - exp); + if (active >= load) + newload += FIXED_1-1; + + return newload / FIXED_1; } #ifdef CONFIG_NO_HZ diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index e1e6aae4..f151c306 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -2230,7 +2230,7 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags) * * note: in the case of encountering a throttled cfs_rq we will * post the final h_nr_running increment below. - */ + */ if (cfs_rq_throttled(cfs_rq)) break; cfs_rq->h_nr_running++; @@ -5272,31 +5272,17 @@ static void task_fork_fair(struct task_struct *p) { struct cfs_rq *cfs_rq; struct sched_entity *se = &p->se, *curr; - int this_cpu = smp_processor_id(); struct rq *rq = this_rq(); - unsigned long flags; - - raw_spin_lock_irqsave(&rq->lock, flags); + raw_spin_lock(&rq->lock); update_rq_clock(rq); cfs_rq = task_cfs_rq(current); curr = cfs_rq->curr; - - /* - * Not only the cpu but also the task_group of the parent might have - * been changed after parent->se.parent,cfs_rq were copied to - * child->se.parent,cfs_rq. So call __set_task_cpu() to make those - * of child point to valid ones. - */ - rcu_read_lock(); - __set_task_cpu(p, this_cpu); - rcu_read_unlock(); - - update_curr(cfs_rq); - - if (curr) + if (curr) { + update_curr(cfs_rq); se->vruntime = curr->vruntime; + } place_entity(cfs_rq, se, 1); if (sysctl_sched_child_runs_first && curr && entity_before(curr, se)) { @@ -5309,8 +5295,7 @@ static void task_fork_fair(struct task_struct *p) } se->vruntime -= cfs_rq->min_vruntime; - - raw_spin_unlock_irqrestore(&rq->lock, flags); + raw_spin_unlock(&rq->lock); } /* diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index 026f30a8..b97ab3a6 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c @@ -191,6 +191,7 @@ cond_syscall(compat_sys_timerfd_settime); cond_syscall(compat_sys_timerfd_gettime); cond_syscall(sys_eventfd); cond_syscall(sys_eventfd2); +cond_syscall(sys_memfd_create); /* performance counters: */ cond_syscall(sys_perf_event_open); diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index 720ae294..e73e5767 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -377,8 +377,13 @@ int alarm_start(struct alarm *alarm, ktime_t start) */ int alarm_start_relative(struct alarm *alarm, ktime_t start) { - struct alarm_base *base = &alarm_bases[alarm->type]; + struct alarm_base *base; + if (alarm->type >= ALARM_NUMTYPE) { + pr_err("Array out of index\n"); + return -EINVAL; + } + base = &alarm_bases[alarm->type]; start = ktime_add(start, base->gettime()); return alarm_start(alarm, start); } @@ -404,10 +409,15 @@ void alarm_restart(struct alarm *alarm) */ int alarm_try_to_cancel(struct alarm *alarm) { - struct alarm_base *base = &alarm_bases[alarm->type]; + struct alarm_base *base; unsigned long flags; int ret; + if (alarm->type >= ALARM_NUMTYPE) { + pr_err("Array out of index\n"); + return -EINVAL; + } + base = &alarm_bases[alarm->type]; spin_lock_irqsave(&base->lock, flags); ret = hrtimer_try_to_cancel(&alarm->timer); if (ret >= 0) diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 62919e98..ad71cff8 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -1310,3 +1310,13 @@ source "lib/Kconfig.kmemcheck" config TEST_KSTRTOX tristate "Test kstrto*() family of functions at runtime" + +config TEST_HASH + tristate "Perform selftest on hash functions" + default n + help + Enable this option to test the kernel's siphash () + hash functions on boot (or module load). + + This is intended to help people writing architecture-specific + optimized versions. If unsure, say N. diff --git a/lib/Makefile b/lib/Makefile index faa3d6a0..c9526d2f 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -22,8 +22,9 @@ lib-y += kobject.o klist.o obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \ string_helpers.o gcd.o lcm.o list_sort.o uuid.o flex_array.o \ - bsearch.o find_last_bit.o find_next_bit.o llist.o + bsearch.o find_last_bit.o find_next_bit.o llist.o siphash.o obj-y += kstrtox.o +obj-$(CONFIG_TEST_HASH) += test_siphash.o obj-$(CONFIG_TEST_KSTRTOX) += test-kstrtox.o ifeq ($(CONFIG_DEBUG_KOBJECT),y) diff --git a/lib/siphash.c b/lib/siphash.c new file mode 100644 index 00000000..f3809ab5 --- /dev/null +++ b/lib/siphash.c @@ -0,0 +1,233 @@ +/* Copyright (C) 2016 Jason A. Donenfeld . All Rights Reserved. + * + * This file is provided under a dual BSD/GPLv2 license. + * + * SipHash: a fast short-input PRF + * https://131002.net/siphash/ + * + * This implementation is specifically for SipHash2-4. + */ + +#include +#include +#include + +#if defined(CONFIG_DCACHE_WORD_ACCESS) && BITS_PER_LONG == 64 +#include +#include +#endif + +#define SIPROUND \ + do { \ + v0 += v1; v1 = rol64(v1, 13); v1 ^= v0; v0 = rol64(v0, 32); \ + v2 += v3; v3 = rol64(v3, 16); v3 ^= v2; \ + v0 += v3; v3 = rol64(v3, 21); v3 ^= v0; \ + v2 += v1; v1 = rol64(v1, 17); v1 ^= v2; v2 = rol64(v2, 32); \ + } while (0) + +#define PREAMBLE(len) \ + u64 v0 = 0x736f6d6570736575ULL; \ + u64 v1 = 0x646f72616e646f6dULL; \ + u64 v2 = 0x6c7967656e657261ULL; \ + u64 v3 = 0x7465646279746573ULL; \ + u64 b = ((u64)(len)) << 56; \ + v3 ^= key->key[1]; \ + v2 ^= key->key[0]; \ + v1 ^= key->key[1]; \ + v0 ^= key->key[0]; + +#define POSTAMBLE \ + v3 ^= b; \ + SIPROUND; \ + SIPROUND; \ + v0 ^= b; \ + v2 ^= 0xff; \ + SIPROUND; \ + SIPROUND; \ + SIPROUND; \ + SIPROUND; \ + return (v0 ^ v1) ^ (v2 ^ v3); + +u64 __siphash_aligned(const void *data, size_t len, const siphash_key_t *key) +{ + const u8 *end = data + len - (len % sizeof(u64)); + const u8 left = len & (sizeof(u64) - 1); + u64 m; + PREAMBLE(len) + for (; data != end; data += sizeof(u64)) { + m = le64_to_cpup(data); + v3 ^= m; + SIPROUND; + SIPROUND; + v0 ^= m; + } +#if defined(CONFIG_DCACHE_WORD_ACCESS) && BITS_PER_LONG == 64 + if (left) + b |= le64_to_cpu((__force __le64)(load_unaligned_zeropad(data) & + bytemask_from_count(left))); +#else + switch (left) { + case 7: b |= ((u64)end[6]) << 48; + case 6: b |= ((u64)end[5]) << 40; + case 5: b |= ((u64)end[4]) << 32; + case 4: b |= le32_to_cpup(data); break; + case 3: b |= ((u64)end[2]) << 16; + case 2: b |= le16_to_cpup(data); break; + case 1: b |= end[0]; + } +#endif + POSTAMBLE +} +EXPORT_SYMBOL(__siphash_aligned); + +#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS +u64 __siphash_unaligned(const void *data, size_t len, const siphash_key_t *key) +{ + const u8 *end = data + len - (len % sizeof(u64)); + const u8 left = len & (sizeof(u64) - 1); + u64 m; + PREAMBLE(len) + for (; data != end; data += sizeof(u64)) { + m = get_unaligned_le64(data); + v3 ^= m; + SIPROUND; + SIPROUND; + v0 ^= m; + } +#if defined(CONFIG_DCACHE_WORD_ACCESS) && BITS_PER_LONG == 64 + if (left) + b |= le64_to_cpu((__force __le64)(load_unaligned_zeropad(data) & + bytemask_from_count(left))); +#else + switch (left) { + case 7: b |= ((u64)end[6]) << 48; + case 6: b |= ((u64)end[5]) << 40; + case 5: b |= ((u64)end[4]) << 32; + case 4: b |= get_unaligned_le32(end); break; + case 3: b |= ((u64)end[2]) << 16; + case 2: b |= get_unaligned_le16(end); break; + case 1: b |= end[0]; + } +#endif + POSTAMBLE +} +EXPORT_SYMBOL(__siphash_unaligned); +#endif + +/** + * siphash_1u64 - compute 64-bit siphash PRF value of a u64 + * @first: first u64 + * @key: the siphash key + */ +u64 siphash_1u64(const u64 first, const siphash_key_t *key) +{ + PREAMBLE(8) + v3 ^= first; + SIPROUND; + SIPROUND; + v0 ^= first; + POSTAMBLE +} +EXPORT_SYMBOL(siphash_1u64); + +/** + * siphash_2u64 - compute 64-bit siphash PRF value of 2 u64 + * @first: first u64 + * @second: second u64 + * @key: the siphash key + */ +u64 siphash_2u64(const u64 first, const u64 second, const siphash_key_t *key) +{ + PREAMBLE(16) + v3 ^= first; + SIPROUND; + SIPROUND; + v0 ^= first; + v3 ^= second; + SIPROUND; + SIPROUND; + v0 ^= second; + POSTAMBLE +} +EXPORT_SYMBOL(siphash_2u64); + +/** + * siphash_3u64 - compute 64-bit siphash PRF value of 3 u64 + * @first: first u64 + * @second: second u64 + * @third: third u64 + * @key: the siphash key + */ +u64 siphash_3u64(const u64 first, const u64 second, const u64 third, + const siphash_key_t *key) +{ + PREAMBLE(24) + v3 ^= first; + SIPROUND; + SIPROUND; + v0 ^= first; + v3 ^= second; + SIPROUND; + SIPROUND; + v0 ^= second; + v3 ^= third; + SIPROUND; + SIPROUND; + v0 ^= third; + POSTAMBLE +} +EXPORT_SYMBOL(siphash_3u64); + +/** + * siphash_4u64 - compute 64-bit siphash PRF value of 4 u64 + * @first: first u64 + * @second: second u64 + * @third: third u64 + * @forth: forth u64 + * @key: the siphash key + */ +u64 siphash_4u64(const u64 first, const u64 second, const u64 third, + const u64 forth, const siphash_key_t *key) +{ + PREAMBLE(32) + v3 ^= first; + SIPROUND; + SIPROUND; + v0 ^= first; + v3 ^= second; + SIPROUND; + SIPROUND; + v0 ^= second; + v3 ^= third; + SIPROUND; + SIPROUND; + v0 ^= third; + v3 ^= forth; + SIPROUND; + SIPROUND; + v0 ^= forth; + POSTAMBLE +} +EXPORT_SYMBOL(siphash_4u64); + +u64 siphash_1u32(const u32 first, const siphash_key_t *key) +{ + PREAMBLE(4) + b |= first; + POSTAMBLE +} +EXPORT_SYMBOL(siphash_1u32); + +u64 siphash_3u32(const u32 first, const u32 second, const u32 third, + const siphash_key_t *key) +{ + u64 combined = (u64)second << 32 | first; + PREAMBLE(12) + v3 ^= combined; + SIPROUND; + SIPROUND; + v0 ^= combined; + b |= third; + POSTAMBLE +} +EXPORT_SYMBOL(siphash_3u32); diff --git a/lib/test_siphash.c b/lib/test_siphash.c new file mode 100644 index 00000000..d972acfc --- /dev/null +++ b/lib/test_siphash.c @@ -0,0 +1,131 @@ +/* Test cases for siphash.c + * + * Copyright (C) 2016 Jason A. Donenfeld . All Rights Reserved. + * + * This file is provided under a dual BSD/GPLv2 license. + * + * SipHash: a fast short-input PRF + * https://131002.net/siphash/ + * + * This implementation is specifically for SipHash2-4. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include + +/* Test vectors taken from official reference source available at: + * https://131002.net/siphash/siphash24.c + */ + +static const siphash_key_t test_key_siphash = + {{ 0x0706050403020100ULL, 0x0f0e0d0c0b0a0908ULL }}; + +static const u64 test_vectors_siphash[64] = { + 0x726fdb47dd0e0e31ULL, 0x74f839c593dc67fdULL, 0x0d6c8009d9a94f5aULL, + 0x85676696d7fb7e2dULL, 0xcf2794e0277187b7ULL, 0x18765564cd99a68dULL, + 0xcbc9466e58fee3ceULL, 0xab0200f58b01d137ULL, 0x93f5f5799a932462ULL, + 0x9e0082df0ba9e4b0ULL, 0x7a5dbbc594ddb9f3ULL, 0xf4b32f46226bada7ULL, + 0x751e8fbc860ee5fbULL, 0x14ea5627c0843d90ULL, 0xf723ca908e7af2eeULL, + 0xa129ca6149be45e5ULL, 0x3f2acc7f57c29bdbULL, 0x699ae9f52cbe4794ULL, + 0x4bc1b3f0968dd39cULL, 0xbb6dc91da77961bdULL, 0xbed65cf21aa2ee98ULL, + 0xd0f2cbb02e3b67c7ULL, 0x93536795e3a33e88ULL, 0xa80c038ccd5ccec8ULL, + 0xb8ad50c6f649af94ULL, 0xbce192de8a85b8eaULL, 0x17d835b85bbb15f3ULL, + 0x2f2e6163076bcfadULL, 0xde4daaaca71dc9a5ULL, 0xa6a2506687956571ULL, + 0xad87a3535c49ef28ULL, 0x32d892fad841c342ULL, 0x7127512f72f27cceULL, + 0xa7f32346f95978e3ULL, 0x12e0b01abb051238ULL, 0x15e034d40fa197aeULL, + 0x314dffbe0815a3b4ULL, 0x027990f029623981ULL, 0xcadcd4e59ef40c4dULL, + 0x9abfd8766a33735cULL, 0x0e3ea96b5304a7d0ULL, 0xad0c42d6fc585992ULL, + 0x187306c89bc215a9ULL, 0xd4a60abcf3792b95ULL, 0xf935451de4f21df2ULL, + 0xa9538f0419755787ULL, 0xdb9acddff56ca510ULL, 0xd06c98cd5c0975ebULL, + 0xe612a3cb9ecba951ULL, 0xc766e62cfcadaf96ULL, 0xee64435a9752fe72ULL, + 0xa192d576b245165aULL, 0x0a8787bf8ecb74b2ULL, 0x81b3e73d20b49b6fULL, + 0x7fa8220ba3b2eceaULL, 0x245731c13ca42499ULL, 0xb78dbfaf3a8d83bdULL, + 0xea1ad565322a1a0bULL, 0x60e61c23a3795013ULL, 0x6606d7e446282b93ULL, + 0x6ca4ecb15c5f91e1ULL, 0x9f626da15c9625f3ULL, 0xe51b38608ef25f57ULL, + 0x958a324ceb064572ULL +}; + +static int __init siphash_test_init(void) +{ + u8 in[64] __aligned(SIPHASH_ALIGNMENT); + u8 in_unaligned[65] __aligned(SIPHASH_ALIGNMENT); + u8 i; + int ret = 0; + + for (i = 0; i < 64; ++i) { + in[i] = i; + in_unaligned[i + 1] = i; + if (siphash(in, i, &test_key_siphash) != + test_vectors_siphash[i]) { + pr_info("siphash self-test aligned %u: FAIL\n", i + 1); + ret = -EINVAL; + } + if (siphash(in_unaligned + 1, i, &test_key_siphash) != + test_vectors_siphash[i]) { + pr_info("siphash self-test unaligned %u: FAIL\n", i + 1); + ret = -EINVAL; + } + } + if (siphash_1u64(0x0706050403020100ULL, &test_key_siphash) != + test_vectors_siphash[8]) { + pr_info("siphash self-test 1u64: FAIL\n"); + ret = -EINVAL; + } + if (siphash_2u64(0x0706050403020100ULL, 0x0f0e0d0c0b0a0908ULL, + &test_key_siphash) != test_vectors_siphash[16]) { + pr_info("siphash self-test 2u64: FAIL\n"); + ret = -EINVAL; + } + if (siphash_3u64(0x0706050403020100ULL, 0x0f0e0d0c0b0a0908ULL, + 0x1716151413121110ULL, &test_key_siphash) != + test_vectors_siphash[24]) { + pr_info("siphash self-test 3u64: FAIL\n"); + ret = -EINVAL; + } + if (siphash_4u64(0x0706050403020100ULL, 0x0f0e0d0c0b0a0908ULL, + 0x1716151413121110ULL, 0x1f1e1d1c1b1a1918ULL, + &test_key_siphash) != test_vectors_siphash[32]) { + pr_info("siphash self-test 4u64: FAIL\n"); + ret = -EINVAL; + } + if (siphash_1u32(0x03020100U, &test_key_siphash) != + test_vectors_siphash[4]) { + pr_info("siphash self-test 1u32: FAIL\n"); + ret = -EINVAL; + } + if (siphash_2u32(0x03020100U, 0x07060504U, &test_key_siphash) != + test_vectors_siphash[8]) { + pr_info("siphash self-test 2u32: FAIL\n"); + ret = -EINVAL; + } + if (siphash_3u32(0x03020100U, 0x07060504U, + 0x0b0a0908U, &test_key_siphash) != + test_vectors_siphash[12]) { + pr_info("siphash self-test 3u32: FAIL\n"); + ret = -EINVAL; + } + if (siphash_4u32(0x03020100U, 0x07060504U, + 0x0b0a0908U, 0x0f0e0d0cU, &test_key_siphash) != + test_vectors_siphash[16]) { + pr_info("siphash self-test 4u32: FAIL\n"); + ret = -EINVAL; + } + if (!ret) + pr_info("self-tests: pass\n"); + return ret; +} + +static void __exit siphash_test_exit(void) +{ +} + +module_init(siphash_test_init); +module_exit(siphash_test_exit); + +MODULE_AUTHOR("Jason A. Donenfeld "); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/mm/shmem.c b/mm/shmem.c index 788a3008..88fb3540 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -62,7 +62,9 @@ static struct vfsmount *shm_mnt; #include #include #include +#include #include +#include #include #include @@ -2370,6 +2372,75 @@ static int shmem_show_options(struct seq_file *seq, struct dentry *root) shmem_show_mpol(seq, sbinfo->mpol); return 0; } + +#define MFD_NAME_PREFIX "memfd:" +#define MFD_NAME_PREFIX_LEN (sizeof(MFD_NAME_PREFIX) - 1) +#define MFD_NAME_MAX_LEN (NAME_MAX - MFD_NAME_PREFIX_LEN) + +#define MFD_ALL_FLAGS (MFD_CLOEXEC | MFD_ALLOW_SEALING) + +SYSCALL_DEFINE2(memfd_create, + const char __user *, uname, + unsigned int, flags) +{ + struct shmem_inode_info *info; + struct file *file; + int fd, error; + char *name; + long len; + + if (flags & ~(unsigned int)MFD_ALL_FLAGS) + return -EINVAL; + + /* length includes terminating zero */ + len = strnlen_user(uname, MFD_NAME_MAX_LEN + 1); + if (len <= 0) + return -EFAULT; + if (len > MFD_NAME_MAX_LEN + 1) + return -EINVAL; + + name = kmalloc(len + MFD_NAME_PREFIX_LEN, GFP_TEMPORARY); + if (!name) + return -ENOMEM; + + strcpy(name, MFD_NAME_PREFIX); + if (copy_from_user(&name[MFD_NAME_PREFIX_LEN], uname, len)) { + error = -EFAULT; + goto err_name; + } + + /* terminating-zero may have changed after strnlen_user() returned */ + if (name[len + MFD_NAME_PREFIX_LEN - 1]) { + error = -EFAULT; + goto err_name; + } + + fd = get_unused_fd_flags((flags & MFD_CLOEXEC) ? O_CLOEXEC : 0); + if (fd < 0) { + error = fd; + goto err_name; + } + + file = shmem_file_setup(name, 0, VM_NORESERVE); + if (IS_ERR(file)) { + error = PTR_ERR(file); + goto err_fd; + } + info = SHMEM_I(file->f_path.dentry->d_inode); + file->f_mode |= FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE; + file->f_flags |= O_RDWR | O_LARGEFILE; + + fd_install(fd, file); + kfree(name); + return fd; + +err_fd: + put_unused_fd(fd); +err_name: + kfree(name); + return error; +} + #endif /* CONFIG_TMPFS */ static void shmem_put_super(struct super_block *sb) diff --git a/mm/slub.c b/mm/slub.c index 21d4adff..f848e7d3 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -3978,9 +3978,9 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size, } return s; } - kfree(n); kfree(s); } + kfree(n); err: up_write(&slub_lock); diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 79aaac28..d7dc8944 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -1031,6 +1031,11 @@ static int atalk_create(struct net *net, struct socket *sock, int protocol, */ if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM) goto out; + + rc = -EPERM; + if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW)) + goto out; + rc = -ENOMEM; sk = sk_alloc(net, PF_APPLETALK, GFP_KERNEL, &ddp_proto); if (!sk) diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index f59c8af1..63c83ce3 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -857,6 +857,8 @@ static int ax25_create(struct net *net, struct socket *sock, int protocol, break; case SOCK_RAW: + if (!capable(CAP_NET_RAW)) + return -EPERM; break; default: return -ESOCKTNOSUPPORT; diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 812a2c90..a397e317 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -153,6 +153,7 @@ static __net_init int setup_net(struct net *net, struct user_namespace *user_ns) atomic_set(&net->count, 1); atomic_set(&net->passive, 1); + get_random_bytes(&net->hash_mix, sizeof(u32)); net->dev_base_seq = 1; net->user_ns = user_ns; diff --git a/net/ieee802154/af_ieee802154.c b/net/ieee802154/af_ieee802154.c index 40e606f3..aa5cbeb8 100644 --- a/net/ieee802154/af_ieee802154.c +++ b/net/ieee802154/af_ieee802154.c @@ -253,6 +253,9 @@ static int ieee802154_create(struct net *net, struct socket *sock, switch (sock->type) { case SOCK_RAW: + rc = -EPERM; + if (!capable(CAP_NET_RAW)) + goto out; proto = &ieee802154_raw_prot; ops = &ieee802154_raw_ops; break; diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index e6e389ef..3cd805d2 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -343,7 +343,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) pip->saddr = fl4.saddr; pip->protocol = IPPROTO_IGMP; pip->tot_len = 0; /* filled in later */ - ip_select_ident(skb, NULL); + ip_select_ident(net, skb, NULL); ((u8*)&pip[1])[0] = IPOPT_RA; ((u8*)&pip[1])[1] = 4; ((u8*)&pip[1])[2] = 0; @@ -687,7 +687,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc, iph->daddr = dst; iph->saddr = fl4.saddr; iph->protocol = IPPROTO_IGMP; - ip_select_ident(skb, NULL); + ip_select_ident(net, skb, NULL); ((u8*)&iph[1])[0] = IPOPT_RA; ((u8*)&iph[1])[1] = 4; ((u8*)&iph[1])[2] = 0; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 670fdde2..a14eb005 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -161,7 +161,7 @@ int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk, iph->daddr = (opt && opt->opt.srr ? opt->opt.faddr : daddr); iph->saddr = saddr; iph->protocol = sk->sk_protocol; - ip_select_ident(skb, sk); + ip_select_ident(sock_net(sk), skb, sk); if (opt && opt->opt.optlen) { iph->ihl += opt->opt.optlen>>2; @@ -403,7 +403,8 @@ int ip_queue_xmit(struct sk_buff *skb, struct flowi *fl) ip_options_build(skb, &inet_opt->opt, inet->inet_daddr, rt, 0); } - ip_select_ident_segs(skb, sk, skb_shinfo(skb)->gso_segs ?: 1); + ip_select_ident_segs(sock_net(sk), skb, sk, + skb_shinfo(skb)->gso_segs ?: 1); skb->priority = sk->sk_priority; skb->mark = sk->sk_mark; @@ -1354,7 +1355,7 @@ struct sk_buff *__ip_make_skb(struct sock *sk, iph->ttl = ttl; iph->protocol = sk->sk_protocol; ip_copy_addrs(iph, fl4); - ip_select_ident(skb, sk); + ip_select_ident(net, skb, sk); if (opt) { iph->ihl += opt->optlen>>2; diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 7b2ada06..e9153812 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -1557,7 +1557,8 @@ static struct notifier_block ip_mr_notifier = { * important for multicast video. */ -static void ip_encap(struct sk_buff *skb, __be32 saddr, __be32 daddr) +static void ip_encap(struct net *net, struct sk_buff *skb, + __be32 saddr, __be32 daddr) { struct iphdr *iph; const struct iphdr *old_iph = ip_hdr(skb); @@ -1576,7 +1577,7 @@ static void ip_encap(struct sk_buff *skb, __be32 saddr, __be32 daddr) iph->protocol = IPPROTO_IPIP; iph->ihl = 5; iph->tot_len = htons(skb->len); - ip_select_ident(skb, NULL); + ip_select_ident(net, skb, NULL); ip_send_check(iph); memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); @@ -1672,7 +1673,7 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt, * What do we do with netfilter? -- RR */ if (vif->flags & VIFF_TUNNEL) { - ip_encap(skb, vif->local, vif->remote); + ip_encap(net, skb, vif->local, vif->remote); /* FIXME: extra output firewall step used to be here. --RR */ vif->dev->stats.tx_packets++; vif->dev->stats.tx_bytes += skb->len; diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index b6d4ff51..12994879 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -397,7 +397,7 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4, iph->check = 0; iph->tot_len = htons(length); if (!iph->id) - ip_select_ident(skb, NULL); + ip_select_ident(net, skb, NULL); iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); } diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 2e54a2e2..90697b8b 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1398,21 +1398,19 @@ u32 ip_idents_reserve(u32 hash, int segs) } EXPORT_SYMBOL(ip_idents_reserve); -void __ip_select_ident(struct iphdr *iph, int segs) +void __ip_select_ident(struct net *net, struct iphdr *iph, int segs) { - static u32 ip_idents_hashrnd __read_mostly; - static bool hashrnd_initialized = false; u32 hash, id; - if (unlikely(!hashrnd_initialized)) { - hashrnd_initialized = true; - get_random_bytes(&ip_idents_hashrnd, sizeof(ip_idents_hashrnd)); - } + /* Note the following code is not safe, but this is okay. */ + if (unlikely(siphash_key_is_zero(&net->ipv4.ip_id_key))) + get_random_bytes(&net->ipv4.ip_id_key, + sizeof(net->ipv4.ip_id_key)); - hash = jhash_3words((__force u32)iph->daddr, + hash = siphash_3u32((__force u32)iph->daddr, (__force u32)iph->saddr, iph->protocol, - ip_idents_hashrnd); + &net->ipv4.ip_id_key); id = ip_idents_reserve(hash, segs); iph->id = htons(id); } diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c index 5531eb2a..1b0533e5 100644 --- a/net/ipv4/xfrm4_mode_tunnel.c +++ b/net/ipv4/xfrm4_mode_tunnel.c @@ -59,7 +59,7 @@ static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) top_iph->saddr = x->props.saddr.a4; top_iph->daddr = x->id.daddr.a4; - ip_select_ident(skb, NULL); + ip_select_ident(dev_net(dst->dev), skb, NULL); return 0; } diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 387c5eba..b428c528 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -601,18 +601,23 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) return -EINVAL; } -void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt) +void ipv6_select_ident(struct net *net, struct frag_hdr *fhdr, struct rt6_info *rt) { - static u32 ip6_idents_hashrnd __read_mostly; - static bool hashrnd_initialized = false; + const struct { + struct in6_addr dst; + struct in6_addr src; + } __aligned(SIPHASH_ALIGNMENT) combined = { + .dst = rt->rt6i_dst.addr, + .src = rt->rt6i_src.addr, + }; u32 hash, id; - if (unlikely(!hashrnd_initialized)) { - hashrnd_initialized = true; - get_random_bytes(&ip6_idents_hashrnd, sizeof(ip6_idents_hashrnd)); - } - hash = __ipv6_addr_jhash(&rt->rt6i_dst.addr, ip6_idents_hashrnd); - hash = __ipv6_addr_jhash(&rt->rt6i_src.addr, hash); + /* Note the following code is not safe, but this is okay. */ + if (unlikely(siphash_key_is_zero(&net->ipv4.ip_id_key))) + get_random_bytes(&net->ipv4.ip_id_key, + sizeof(net->ipv4.ip_id_key)); + + hash = siphash(&combined, sizeof(combined), &net->ipv4.ip_id_key); id = ip_idents_reserve(hash, 1); fhdr->identification = htonl(id); @@ -708,7 +713,7 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) skb_reset_network_header(skb); memcpy(skb_network_header(skb), tmp_hdr, hlen); - ipv6_select_ident(fh, rt); + ipv6_select_ident(net, fh, rt); fh->nexthdr = nexthdr; fh->reserved = 0; fh->frag_off = htons(IP6_MF); @@ -857,7 +862,7 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) fh->nexthdr = nexthdr; fh->reserved = 0; if (!frag_id) { - ipv6_select_ident(fh, rt); + ipv6_select_ident(net, fh, rt); frag_id = fh->identification; } else fh->identification = frag_id; @@ -1158,7 +1163,7 @@ static inline int ip6_ufo_append_data(struct sock *sk, skb_shinfo(skb)->gso_size = (mtu - fragheaderlen - sizeof(struct frag_hdr)) & ~7; skb_shinfo(skb)->gso_type = SKB_GSO_UDP; - ipv6_select_ident(&fhdr, rt); + ipv6_select_ident(sock_net(sk), &fhdr, rt); skb_shinfo(skb)->ip6_frag_id = fhdr.identification; __skb_queue_tail(&sk->sk_write_queue, skb); } diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c index a6126c62..9ef25226 100644 --- a/net/ipv6/output_core.c +++ b/net/ipv6/output_core.c @@ -9,10 +9,8 @@ * This is similar to ipv6_select_ident() but we use an independent hash * seed to limit information leakage. */ -void ipv6_proxy_select_ident(struct sk_buff *skb) +void ipv6_proxy_select_ident(struct net *net, struct sk_buff *skb) { - static u32 ip6_proxy_idents_hashrnd __read_mostly; - static bool hashrnd_initialized = false; struct in6_addr buf[2]; struct in6_addr *addrs; u32 hash, id; @@ -21,18 +19,25 @@ void ipv6_proxy_select_ident(struct sk_buff *skb) skb_network_offset(skb) + offsetof(struct ipv6hdr, saddr), sizeof(buf), buf); - if (!addrs) - return; + if (addrs) + { + const struct { + struct in6_addr dst; + struct in6_addr src; + } __aligned(SIPHASH_ALIGNMENT) combined = { + .dst = addrs[1], + .src = addrs[0], + }; - if (unlikely(!hashrnd_initialized)) { - hashrnd_initialized = true; - get_random_bytes(&ip6_proxy_idents_hashrnd, - sizeof(ip6_proxy_idents_hashrnd)); - } - hash = __ipv6_addr_jhash(&addrs[1], ip6_proxy_idents_hashrnd); - hash = __ipv6_addr_jhash(&addrs[0], hash); + /* Note the following code is not safe, but this is okay. */ + if (unlikely(siphash_key_is_zero(&net->ipv4.ip_id_key))) + get_random_bytes(&net->ipv4.ip_id_key, + sizeof(net->ipv4.ip_id_key)); + + hash = siphash(&combined, sizeof(combined), &net->ipv4.ip_id_key); - id = ip_idents_reserve(hash, 1); - skb_shinfo(skb)->ip6_frag_id = htonl(id); + id = ip_idents_reserve(hash, 1); + skb_shinfo(skb)->ip6_frag_id = htonl(id); + } } EXPORT_SYMBOL_GPL(ipv6_proxy_select_ident); diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index e680491c..92462d92 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c @@ -780,6 +780,7 @@ int ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp) { + struct net *net = skb_net(skb); struct rtable *rt; /* Route to the other host */ __be32 saddr; /* Source for tunnel */ struct net_device *tdev; /* Device to other host */ @@ -867,7 +868,7 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, iph->daddr = cp->daddr.ip; iph->saddr = saddr; iph->ttl = old_iph->ttl; - ip_select_ident(skb, NULL); + ip_select_ident(net, skb, NULL); /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c index 7c01c2f3..f3cde1e7 100644 --- a/net/wireless/wext-sme.c +++ b/net/wireless/wext-sme.c @@ -217,6 +217,7 @@ int cfg80211_mgd_wext_giwessid(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *ssid) { + int ret = 0; struct wireless_dev *wdev = dev->ieee80211_ptr; /* call only for station! */ @@ -232,7 +233,10 @@ int cfg80211_mgd_wext_giwessid(struct net_device *dev, if (ie) { data->flags = 1; data->length = ie[1]; - memcpy(ssid, ie + 2, data->length); + if (data->length > IW_ESSID_MAX_SIZE) + ret = -EINVAL; + else + memcpy(ssid, ie + 2, data->length); } } else if (wdev->wext.connect.ssid && wdev->wext.connect.ssid_len) { data->flags = 1; @@ -241,7 +245,7 @@ int cfg80211_mgd_wext_giwessid(struct net_device *dev, } wdev_unlock(wdev); - return 0; + return ret; } int cfg80211_mgd_wext_siwap(struct net_device *dev, diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index dfb869dd..6c9ae79c 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -1258,6 +1258,9 @@ static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family) if (!ut[i].family) ut[i].family = family; + if (ut[i].mode >= XFRM_MODE_MAX) + return -EINVAL; + switch (ut[i].family) { case AF_INET: break; diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst index d3bae5e7..8ccf8305 100644 --- a/scripts/Makefile.headersinst +++ b/scripts/Makefile.headersinst @@ -3,63 +3,86 @@ # # header-y - list files to be installed. They are preprocessed # to remove __KERNEL__ section of the file -# objhdr-y - Same as header-y but for generated files -# genhdr-y - Same as objhdr-y but in a generated/ directory +# genhdr-y - Same as header-y but in a generated/ directory # # ========================================================================== -# called may set destination dir (when installing to asm/) -_dst := $(if $(dst),$(dst),$(obj)) - # generated header directory gen := $(if $(gen),$(gen),$(subst include/,include/generated/,$(obj))) kbuild-file := $(srctree)/$(obj)/Kbuild include $(kbuild-file) -_dst := $(if $(destination-y),$(destination-y),$(_dst)) +# called may set destination dir (when installing to asm/) +_dst := $(if $(destination-y),$(destination-y),$(if $(dst),$(dst),$(obj))) + +old-kbuild-file := $(srctree)/$(subst uapi/,,$(obj))/Kbuild +ifneq ($(wildcard $(old-kbuild-file)),) +include $(old-kbuild-file) +endif include scripts/Kbuild.include -install := $(INSTALL_HDR_PATH)/$(_dst) +installdir := $(INSTALL_HDR_PATH)/$(subst uapi/,,$(_dst)) header-y := $(sort $(header-y)) subdirs := $(patsubst %/,%,$(filter %/, $(header-y))) header-y := $(filter-out %/, $(header-y)) # files used to track state of install/check -install-file := $(install)/.install -check-file := $(install)/.check +install-file := $(installdir)/.install +check-file := $(installdir)/.check # generic-y list all files an architecture uses from asm-generic # Use this to build a list of headers which require a wrapper wrapper-files := $(filter $(header-y), $(generic-y)) +srcdir := $(srctree)/$(obj) +gendir := $(objtree)/$(gen) + +oldsrcdir := $(srctree)/$(subst /uapi,,$(obj)) + # all headers files for this dir header-y := $(filter-out $(generic-y), $(header-y)) -all-files := $(header-y) $(objhdr-y) $(genhdr-y) $(wrapper-files) -input-files := $(addprefix $(srctree)/$(obj)/,$(header-y)) \ - $(addprefix $(objtree)/$(obj)/,$(objhdr-y)) \ - $(addprefix $(objtree)/$(gen)/,$(genhdr-y)) -output-files := $(addprefix $(install)/, $(all-files)) +all-files := $(header-y) $(genhdr-y) $(wrapper-files) +output-files := $(addprefix $(installdir)/, $(all-files)) + +input-files1 := $(foreach hdr, $(header-y), \ + $(if $(wildcard $(srcdir)/$(hdr)), \ + $(wildcard $(srcdir)/$(hdr))) \ + ) +input-files1-name := $(notdir $(input-files1)) +input-files2 := $(foreach hdr, $(header-y), \ + $(if $(wildcard $(srcdir)/$(hdr)),, \ + $(if $(wildcard $(oldsrcdir)/$(hdr)), \ + $(wildcard $(oldsrcdir)/$(hdr)), \ + $(error Missing UAPI file $(srcdir)/$(hdr))) \ + )) +input-files2-name := $(notdir $(input-files2)) +input-files3 := $(foreach hdr, $(genhdr-y), \ + $(if $(wildcard $(gendir)/$(hdr)), \ + $(wildcard $(gendir)/$(hdr)), \ + $(error Missing generated UAPI file $(gendir)/$(hdr)) \ + )) +input-files3-name := $(notdir $(input-files3)) # Work out what needs to be removed -oldheaders := $(patsubst $(install)/%,%,$(wildcard $(install)/*.h)) +oldheaders := $(patsubst $(installdir)/%,%,$(wildcard $(installdir)/*.h)) unwanted := $(filter-out $(all-files),$(oldheaders)) # Prefix unwanted with full paths to $(INSTALL_HDR_PATH) -unwanted-file := $(addprefix $(install)/, $(unwanted)) +unwanted-file := $(addprefix $(installdir)/, $(unwanted)) printdir = $(patsubst $(INSTALL_HDR_PATH)/%/,%,$(dir $@)) quiet_cmd_install = INSTALL $(printdir) ($(words $(all-files))\ file$(if $(word 2, $(all-files)),s)) cmd_install = \ - $(PERL) $< $(srctree)/$(obj) $(install) $(SRCARCH) $(header-y); \ - $(PERL) $< $(objtree)/$(obj) $(install) $(SRCARCH) $(objhdr-y); \ - $(PERL) $< $(objtree)/$(gen) $(install) $(SRCARCH) $(genhdr-y); \ + $(CONFIG_SHELL) $< $(installdir) $(srcdir) $(input-files1-name); \ + $(CONFIG_SHELL) $< $(installdir) $(oldsrcdir) $(input-files2-name); \ + $(CONFIG_SHELL) $< $(installdir) $(gendir) $(input-files3-name); \ for F in $(wrapper-files); do \ - echo "\#include " > $(install)/$$F; \ + echo "\#include " > $(installdir)/$$F; \ done; \ touch $@ @@ -70,7 +93,7 @@ quiet_cmd_check = CHECK $(printdir) ($(words $(all-files)) files) # Headers list can be pretty long, xargs helps to avoid # the "Argument list too long" error. cmd_check = for f in $(all-files); do \ - echo "$(install)/$${f}"; done \ + echo "$(installdir)/$${f}"; done \ | xargs \ $(PERL) $< $(INSTALL_HDR_PATH)/include $(SRCARCH); \ touch $@ @@ -83,7 +106,7 @@ __headersinst: $(subdirs) $(install-file) @: targets += $(install-file) -$(install-file): scripts/headers_install.pl $(input-files) FORCE +$(install-file): scripts/headers_install.sh $(input-files1) $(input-files2) $(input-files3) FORCE $(if $(unwanted),$(call cmd,remove),) $(if $(wildcard $(dir $@)),,$(shell mkdir -p $(dir $@))) $(call if_changed,install) diff --git a/scripts/bootgraph.pl b/scripts/bootgraph.pl old mode 100644 new mode 100755 diff --git a/scripts/export_report.pl b/scripts/export_report.pl old mode 100644 new mode 100755 diff --git a/scripts/gcc-goto.sh b/scripts/gcc-goto.sh old mode 100644 new mode 100755 diff --git a/scripts/gcc-version.sh b/scripts/gcc-version.sh old mode 100644 new mode 100755 diff --git a/scripts/gcc-x86_32-has-stack-protector.sh b/scripts/gcc-x86_32-has-stack-protector.sh old mode 100644 new mode 100755 diff --git a/scripts/gcc-x86_64-has-stack-protector.sh b/scripts/gcc-x86_64-has-stack-protector.sh old mode 100644 new mode 100755 diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh old mode 100644 new mode 100755 diff --git a/scripts/headers_check.pl b/scripts/headers_check.pl old mode 100644 new mode 100755 diff --git a/scripts/headers_install.pl b/scripts/headers_install.pl deleted file mode 100644 index 48462be3..00000000 --- a/scripts/headers_install.pl +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/perl -w -# -# headers_install prepare the listed header files for use in -# user space and copy the files to their destination. -# -# Usage: headers_install.pl readdir installdir arch [files...] -# readdir: dir to open files -# installdir: dir to install the files -# arch: current architecture -# arch is used to force a reinstallation when the arch -# changes because kbuild then detect a command line change. -# files: list of files to check -# -# Step in preparation for users space: -# 1) Drop all use of compiler.h definitions -# 2) Drop include of compiler.h -# 3) Drop all sections defined out by __KERNEL__ (using unifdef) - -use strict; - -my ($readdir, $installdir, $arch, @files) = @ARGV; - -my $unifdef = "scripts/unifdef -U__KERNEL__ -D__EXPORTED_HEADERS__"; - -foreach my $file (@files) { - my $tmpfile = "$installdir/$file.tmp"; - - open(my $in, '<', "$readdir/$file") - or die "$readdir/$file: $!\n"; - open(my $out, '>', $tmpfile) - or die "$tmpfile: $!\n"; - while (my $line = <$in>) { - $line =~ s/([\s(])__user\s/$1/g; - $line =~ s/([\s(])__force\s/$1/g; - $line =~ s/([\s(])__iomem\s/$1/g; - $line =~ s/\s__attribute_const__\s/ /g; - $line =~ s/\s__attribute_const__$//g; - $line =~ s/\b__packed\b/__attribute__((packed))/g; - $line =~ s/^#include //; - $line =~ s/(^|\s)(inline)\b/$1__$2__/g; - $line =~ s/(^|\s)(asm)\b(\s|[(]|$)/$1__$2__$3/g; - $line =~ s/(^|\s|[(])(volatile)\b(\s|[(]|$)/$1__$2__$3/g; - printf {$out} "%s", $line; - } - close $out; - close $in; - - system $unifdef . " $tmpfile > $installdir/$file"; - # unifdef will exit 0 on success, and will exit 1 when the - # file was processed successfully but no changes were made, - # so abort only when it's higher than that. - my $e = $? >> 8; - if ($e > 1) { - die "$tmpfile: $!\n"; - } - unlink $tmpfile; -} -exit 0; diff --git a/scripts/headers_install.sh b/scripts/headers_install.sh new file mode 100755 index 00000000..fdebd66f --- /dev/null +++ b/scripts/headers_install.sh @@ -0,0 +1,46 @@ +#!/bin/sh + +if [ $# -lt 2 ] +then + echo "Usage: headers_install.sh OUTDIR SRCDIR [FILES...]" + echo + echo "Prepares kernel header files for use by user space, by removing" + echo "all compiler.h definitions and #includes, removing any" + echo "#ifdef __KERNEL__ sections, and putting __underscores__ around" + echo "asm/inline/volatile keywords." + echo + echo "OUTDIR: directory to write each userspace header FILE to." + echo "SRCDIR: source directory where files are picked." + echo "FILES: list of header files to operate on." + + exit 1 +fi + +# Grab arguments + +OUTDIR="$1" +shift +SRCDIR="$1" +shift + +# Iterate through files listed on command line + +FILE= +trap 'rm -f "$OUTDIR/$FILE" "$OUTDIR/$FILE.sed"' EXIT +for i in "$@" +do + FILE="$(basename "$i")" + sed -r \ + -e 's/([ \t(])(__user|__force|__iomem)[ \t]/\1/g' \ + -e 's/__attribute_const__([ \t]|$)/\1/g' \ + -e 's@^#include @@' \ + -e 's/(^|[^a-zA-Z0-9])__packed([^a-zA-Z0-9_]|$)/\1__attribute__((packed))\2/g' \ + -e 's/(^|[ \t(])(inline|asm|volatile)([ \t(]|$)/\1__\2__\3/g' \ + -e 's@#(ifndef|define|endif[ \t]*/[*])[ \t]*_UAPI@#\1 @' \ + "$SRCDIR/$i" > "$OUTDIR/$FILE.sed" || exit 1 + scripts/unifdef -U__KERNEL__ -D__EXPORTED_HEADERS__ "$OUTDIR/$FILE.sed" \ + > "$OUTDIR/$FILE" + [ $? -gt 1 ] && exit 1 + rm -f "$OUTDIR/$FILE.sed" +done +trap - EXIT diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh old mode 100644 new mode 100755 diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl old mode 100644 new mode 100755 diff --git a/scripts/markup_oops.pl b/scripts/markup_oops.pl old mode 100644 new mode 100755 diff --git a/scripts/mkmakefile b/scripts/mkmakefile old mode 100644 new mode 100755 diff --git a/scripts/mksysmap b/scripts/mksysmap old mode 100644 new mode 100755 diff --git a/scripts/package/builddeb b/scripts/package/builddeb old mode 100644 new mode 100755 diff --git a/scripts/package/buildtar b/scripts/package/buildtar old mode 100644 new mode 100755 diff --git a/scripts/profile2linkerlist.pl b/scripts/profile2linkerlist.pl old mode 100644 new mode 100755 diff --git a/scripts/rt-tester/rt-tester.py b/scripts/rt-tester/rt-tester.py old mode 100644 new mode 100755 diff --git a/scripts/selinux/install_policy.sh b/scripts/selinux/install_policy.sh old mode 100644 new mode 100755 diff --git a/scripts/tracing/draw_functrace.py b/scripts/tracing/draw_functrace.py old mode 100644 new mode 100755 diff --git a/scripts/xz_wrap.sh b/scripts/xz_wrap.sh old mode 100644 new mode 100755 diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c index 5d02f447..bba1595f 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c @@ -3447,7 +3447,7 @@ static const char * const slim0_rx_vi_fb_tx_lch_mux_text[] = { "ZERO", "SLIM4_TX" }; -static const int const slim0_rx_vi_fb_tx_lch_value[] = { +static const int slim0_rx_vi_fb_tx_lch_value[] = { MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_SLIMBUS_4_TX }; static const struct soc_enum slim0_rx_vi_fb_lch_mux_enum = diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c index 3fd7f8bd..a2c5c510 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c @@ -541,7 +541,7 @@ static int msm_roaming_get(struct snd_kcontrol *kcontrol, return 0; } -static const char const *tty_mode[] = {"OFF", "HCO", "VCO", "FULL"}; +static const char *tty_mode[] = {"OFF", "HCO", "VCO", "FULL"}; static const struct soc_enum msm_tty_mode_enum[] = { SOC_ENUM_SINGLE_EXT(4, tty_mode), }; diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c index e7b908d3..cb3a0997 100644 --- a/sound/soc/msm/qdsp6v2/q6adm.c +++ b/sound/soc/msm/qdsp6v2/q6adm.c @@ -650,7 +650,8 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) /* is big enough and has a valid param size */ if ((payload[0] == 0) && (data->payload_size > (4 * sizeof(*payload))) && - (data->payload_size - 4 >= + (data->payload_size - + (4 * sizeof(*payload)) >= payload[3]) && (ARRAY_SIZE(adm_get_parameters)-1 >= payload[3])) { diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c index ada082ee..6d07d589 100644 --- a/sound/soc/msm/qdsp6v2/q6voice.c +++ b/sound/soc/msm/qdsp6v2/q6voice.c @@ -5526,7 +5526,7 @@ int voice_sec_set_dha_data(uint32_t session_id, short mode, if (v->voc_state == VOC_RUN) ret = voice_send_dha_data(v); - mutex_unlock(&v->lock); + mutex_unlock(&v->lock); #endif return ret; diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index e1c205a6..dfb3e077 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -81,6 +81,7 @@ struct mixer_build { unsigned char *buffer; unsigned int buflen; DECLARE_BITMAP(unitbitmap, MAX_ID_ELEMS); + DECLARE_BITMAP(termbitmap, MAX_ID_ELEMS); struct usb_audio_term oterm; const struct usbmix_name_map *map; const struct usbmix_selector_map *selector_map; @@ -663,14 +664,24 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm * parse the source unit recursively until it reaches to a terminal * or a branched unit. */ -static int check_input_term(struct mixer_build *state, int id, struct usb_audio_term *term) +static int __check_input_term(struct mixer_build *state, int id, + struct usb_audio_term *term) { int err; void *p1; + unsigned char *hdr; memset(term, 0, sizeof(*term)); - while ((p1 = find_audio_control_unit(state, id)) != NULL) { - unsigned char *hdr = p1; + for (;;) { + /* a loop in the terminal chain? */ + if (test_and_set_bit(id, state->termbitmap)) + return -EINVAL; + + p1 = find_audio_control_unit(state, id); + if (!p1) + break; + + hdr = p1; term->id = id; switch (hdr[2]) { case UAC_INPUT_TERMINAL: @@ -688,7 +699,7 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_ term->name = d->iTerminal; /* call recursively to get the clock selectors */ - err = check_input_term(state, d->bCSourceID, term); + err = __check_input_term(state, d->bCSourceID, term); if (err < 0) return err; } @@ -711,7 +722,7 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_ case UAC2_CLOCK_SELECTOR: { struct uac_selector_unit_descriptor *d = p1; /* call recursively to retrieve the channel info */ - err = check_input_term(state, d->baSourceID[0], term); + err = __check_input_term(state, d->baSourceID[0], term); if (err < 0) return err; term->type = d->bDescriptorSubtype << 16; /* virtual type */ @@ -759,6 +770,14 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_ } +static int check_input_term(struct mixer_build *state, int id, + struct usb_audio_term *term) +{ + memset(term, 0, sizeof(*term)); + memset(state->termbitmap, 0, sizeof(state->termbitmap)); + return __check_input_term(state, id, term); +} + /* * Feature Unit */