Merge remote-tracking branch 'upstream/master' into olimex-som204-a20
This commit is contained in:
commit
40cf650ca7
@ -4,13 +4,13 @@ BOARDFAMILY="mvebu"
|
||||
BOOTCONFIG="armada_38x_helios4_config"
|
||||
MODULES="mv_cesa"
|
||||
BUILD_DESKTOP="no"
|
||||
#
|
||||
KERNEL_TARGET="default"
|
||||
CLI_TARGET=""
|
||||
|
||||
KERNEL_TARGET="default,next"
|
||||
CLI_TARGET="jessie:default,stretch:next"
|
||||
|
||||
CLI_BETA_TARGET=""
|
||||
#
|
||||
RECOMMENDED=""
|
||||
RECOMMENDED="Debian_jessie_default_nightly:85,Debian_stretch_next_nightly:85"
|
||||
#
|
||||
BOARDRATING=""
|
||||
CHIP="https://kobol.io/helios4"
|
||||
@ -8,7 +8,7 @@ MODULES_NEXT=""
|
||||
CPUMIN="400000"
|
||||
CPUMAX="1400000"
|
||||
#
|
||||
KERNEL_TARGET="next,dev"
|
||||
KERNEL_TARGET="default,next,dev"
|
||||
CLI_TARGET="xenial:next"
|
||||
DESKTOP_TARGET="xenial:next"
|
||||
#
|
||||
|
||||
@ -8,7 +8,7 @@ MODULES="sunxi_codec sunxi_i2s sunxi_sndcodec 8723cs r8152 hall"
|
||||
MODULES_NEXT=""
|
||||
DISPLAY_MANAGER=lightdm
|
||||
#
|
||||
KERNEL_TARGET="default,next"
|
||||
KERNEL_TARGET="default"
|
||||
CLI_TARGET=""
|
||||
DESKTOP_TARGET="xenial:default"
|
||||
|
||||
|
||||
2
config/bootenv/s5p6818-default.txt
Normal file
2
config/bootenv/s5p6818-default.txt
Normal file
@ -0,0 +1,2 @@
|
||||
verbosity=1
|
||||
console=both
|
||||
@ -1,3 +1,34 @@
|
||||
# DO NOT EDIT THIS FILE
|
||||
#
|
||||
# Please edit /boot/armbianEnv.txt to set supported parameters
|
||||
#
|
||||
|
||||
# default values
|
||||
setenv rootdev "/dev/mmcblk2p1"
|
||||
setenv rootfstype "ext4"
|
||||
setenv verbosity "1"
|
||||
setenv fdt_addr "0x48000000"
|
||||
setenv ramdisk_addr_r "0x49000000"
|
||||
setenv kernel_addr_r "0x4a000000"
|
||||
|
||||
# fdtfile should come from compile-time u-boot patches
|
||||
if test -z "${fdtfile}"; then
|
||||
setenv fdtfile "s5p6818-nanopi-m3.dtb"
|
||||
fi
|
||||
|
||||
echo "Boot script loaded from SD card"
|
||||
|
||||
if ext4load mmc 1:1 ${kernel_addr_r} boot/armbianEnv.txt; then
|
||||
env import -t ${kernel_addr_r} ${filesize}
|
||||
fi
|
||||
|
||||
setenv bootargs "console=ttySAC0,115200n8 root=${rootdev} rootwait rootfstype=${rootfstype} loglevel=${verbosity} usb-storage.quirks=${usbstoragequirks} ${extraargs}"
|
||||
|
||||
if ext4load mmc 1:1 ${fdt_addr} boot/dtb/nexell/${fdtfile} || ext4load mmc 1:1 ${fdt_addr} boot/dtb/nexell/s5p6818-nanopi3-rev07.dtb; then echo "Loading DTB"; fi
|
||||
ext4load mmc 1:1 ${ramdisk_addr_r} boot/uInitrd
|
||||
ext4load mmc 1:1 ${kernel_addr_r} boot/Image
|
||||
|
||||
booti ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr}
|
||||
|
||||
# Recompile with:
|
||||
# mkimage -C none -A arm -T script -d /boot/boot.cmd /boot/boot.scr
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
#
|
||||
# Automatically generated file; DO NOT EDIT.
|
||||
# Linux/arm 4.4.99 Kernel Configuration
|
||||
# Linux/arm 4.4.110 Kernel Configuration
|
||||
#
|
||||
CONFIG_ARM=y
|
||||
CONFIG_ARM_HAS_SG_CHAIN=y
|
||||
@ -3028,6 +3028,7 @@ CONFIG_SENSORS_LM75=m
|
||||
# CONFIG_SENSORS_NCT7904 is not set
|
||||
# CONFIG_SENSORS_PCF8591 is not set
|
||||
# CONFIG_PMBUS is not set
|
||||
CONFIG_SENSORS_PWM_FAN=m
|
||||
# CONFIG_SENSORS_SHT15 is not set
|
||||
# CONFIG_SENSORS_SHT21 is not set
|
||||
# CONFIG_SENSORS_SHTC1 is not set
|
||||
@ -3276,6 +3277,7 @@ CONFIG_REGULATOR_GPIO=m
|
||||
# CONFIG_REGULATOR_MAX8973 is not set
|
||||
# CONFIG_REGULATOR_MT6311 is not set
|
||||
# CONFIG_REGULATOR_PFUZE100 is not set
|
||||
CONFIG_REGULATOR_PWM=m
|
||||
# CONFIG_REGULATOR_TPS51632 is not set
|
||||
# CONFIG_REGULATOR_TPS62360 is not set
|
||||
# CONFIG_REGULATOR_TPS65023 is not set
|
||||
@ -3373,11 +3375,14 @@ CONFIG_LCD_LMS501KF03=m
|
||||
CONFIG_LCD_HX8357=m
|
||||
CONFIG_BACKLIGHT_CLASS_DEVICE=m
|
||||
CONFIG_BACKLIGHT_GENERIC=m
|
||||
CONFIG_BACKLIGHT_PWM=m
|
||||
CONFIG_BACKLIGHT_PM8941_WLED=m
|
||||
CONFIG_BACKLIGHT_ADP8860=m
|
||||
CONFIG_BACKLIGHT_ADP8870=m
|
||||
CONFIG_BACKLIGHT_88PM860X=m
|
||||
CONFIG_BACKLIGHT_LM3630A=m
|
||||
CONFIG_BACKLIGHT_LM3639=m
|
||||
CONFIG_BACKLIGHT_LP855X=m
|
||||
CONFIG_BACKLIGHT_GPIO=m
|
||||
CONFIG_BACKLIGHT_LV5207LP=m
|
||||
CONFIG_BACKLIGHT_BD6107=m
|
||||
@ -3849,6 +3854,7 @@ CONFIG_LEDS_GPIO=m
|
||||
# CONFIG_LEDS_PCA955X is not set
|
||||
# CONFIG_LEDS_PCA963X is not set
|
||||
# CONFIG_LEDS_DAC124S085 is not set
|
||||
CONFIG_LEDS_PWM=m
|
||||
CONFIG_LEDS_REGULATOR=m
|
||||
# CONFIG_LEDS_BD2802 is not set
|
||||
# CONFIG_LEDS_LT3593 is not set
|
||||
@ -4220,6 +4226,7 @@ CONFIG_COMMON_CLK_SCPI=m
|
||||
# CONFIG_COMMON_CLK_SI570 is not set
|
||||
# CONFIG_COMMON_CLK_CDCE925 is not set
|
||||
# CONFIG_CLK_QORIQ is not set
|
||||
CONFIG_COMMON_CLK_PWM=m
|
||||
# CONFIG_COMMON_CLK_PXA is not set
|
||||
# CONFIG_COMMON_CLK_CDCE706 is not set
|
||||
CONFIG_MVEBU_CLK_COMMON=y
|
||||
@ -4528,7 +4535,10 @@ CONFIG_IIO_SYSFS_TRIGGER=m
|
||||
# CONFIG_TSYS02D is not set
|
||||
# CONFIG_NTB is not set
|
||||
# CONFIG_VME_BUS is not set
|
||||
# CONFIG_PWM is not set
|
||||
CONFIG_PWM=y
|
||||
CONFIG_PWM_SYSFS=y
|
||||
CONFIG_PWM_FSL_FTM=m
|
||||
CONFIG_PWM_PCA9685=m
|
||||
CONFIG_IRQCHIP=y
|
||||
CONFIG_ARM_GIC=y
|
||||
CONFIG_ARMADA_370_XP_IRQ=y
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
#
|
||||
# Automatically generated file; DO NOT EDIT.
|
||||
# Linux/arm 4.14.2 Kernel Configuration
|
||||
# Linux/arm 4.14.12 Kernel Configuration
|
||||
#
|
||||
CONFIG_ARM=y
|
||||
CONFIG_ARM_HAS_SG_CHAIN=y
|
||||
@ -1887,6 +1887,8 @@ CONFIG_SCSI_LOWLEVEL=y
|
||||
CONFIG_ATA=y
|
||||
# CONFIG_ATA_NONSTANDARD is not set
|
||||
CONFIG_ATA_VERBOSE_ERROR=y
|
||||
CONFIG_ARCH_WANT_LIBATA_LEDS=y
|
||||
CONFIG_ATA_LEDS=y
|
||||
CONFIG_SATA_PMP=y
|
||||
|
||||
#
|
||||
@ -3614,7 +3616,7 @@ CONFIG_MMC_MVSDIO=y
|
||||
# CONFIG_MMC_SDHCI_XENON is not set
|
||||
# CONFIG_MEMSTICK is not set
|
||||
CONFIG_NEW_LEDS=y
|
||||
CONFIG_LEDS_CLASS=m
|
||||
CONFIG_LEDS_CLASS=y
|
||||
# CONFIG_LEDS_CLASS_FLASH is not set
|
||||
CONFIG_LEDS_BRIGHTNESS_HW_CHANGED=y
|
||||
|
||||
@ -3651,6 +3653,7 @@ CONFIG_LEDS_IS31FL32XX=m
|
||||
# LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM)
|
||||
#
|
||||
# CONFIG_LEDS_BLINKM is not set
|
||||
# CONFIG_LEDS_SYSCON is not set
|
||||
CONFIG_LEDS_USER=m
|
||||
|
||||
#
|
||||
@ -4185,6 +4188,24 @@ CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
|
||||
# CONFIG_PSTORE is not set
|
||||
# CONFIG_SYSV_FS is not set
|
||||
# CONFIG_UFS_FS is not set
|
||||
CONFIG_AUFS_FS=y
|
||||
CONFIG_AUFS_BRANCH_MAX_127=y
|
||||
# CONFIG_AUFS_BRANCH_MAX_511 is not set
|
||||
# CONFIG_AUFS_BRANCH_MAX_1023 is not set
|
||||
# CONFIG_AUFS_BRANCH_MAX_32767 is not set
|
||||
CONFIG_AUFS_SBILIST=y
|
||||
# CONFIG_AUFS_HNOTIFY is not set
|
||||
# CONFIG_AUFS_EXPORT is not set
|
||||
# CONFIG_AUFS_XATTR is not set
|
||||
# CONFIG_AUFS_FHSM is not set
|
||||
# CONFIG_AUFS_RDU is not set
|
||||
# CONFIG_AUFS_DIRREN is not set
|
||||
# CONFIG_AUFS_SHWH is not set
|
||||
# CONFIG_AUFS_BR_RAMFS is not set
|
||||
# CONFIG_AUFS_BR_FUSE is not set
|
||||
CONFIG_AUFS_BR_HFSPLUS=y
|
||||
CONFIG_AUFS_BDEV_LOOP=y
|
||||
# CONFIG_AUFS_DEBUG is not set
|
||||
CONFIG_NETWORK_FILESYSTEMS=y
|
||||
CONFIG_NFS_FS=y
|
||||
CONFIG_NFS_V2=y
|
||||
|
||||
4547
config/kernel/linux-s5p6818-default.config
Normal file
4547
config/kernel/linux-s5p6818-default.config
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
#
|
||||
# Automatically generated file; DO NOT EDIT.
|
||||
# Linux/arm 4.14.5 Kernel Configuration
|
||||
# Linux/arm 4.14.11 Kernel Configuration
|
||||
#
|
||||
CONFIG_ARM=y
|
||||
CONFIG_ARM_HAS_SG_CHAIN=y
|
||||
@ -2075,6 +2075,7 @@ CONFIG_MDIO_DEVICE=y
|
||||
CONFIG_MDIO_BUS=y
|
||||
# CONFIG_MDIO_BCM_UNIMAC is not set
|
||||
# CONFIG_MDIO_BITBANG is not set
|
||||
CONFIG_MDIO_BUS_MUX=y
|
||||
# CONFIG_MDIO_BUS_MUX_GPIO is not set
|
||||
# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
|
||||
# CONFIG_MDIO_HISI_FEMAC is not set
|
||||
@ -2338,7 +2339,7 @@ CONFIG_INPUT_MOUSEDEV=y
|
||||
CONFIG_INPUT_MOUSEDEV_PSAUX=y
|
||||
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
|
||||
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
|
||||
# CONFIG_INPUT_JOYDEV is not set
|
||||
CONFIG_INPUT_JOYDEV=m
|
||||
CONFIG_INPUT_EVDEV=m
|
||||
# CONFIG_INPUT_EVBUG is not set
|
||||
|
||||
@ -2397,7 +2398,36 @@ CONFIG_MOUSE_SERIAL=m
|
||||
# CONFIG_MOUSE_GPIO is not set
|
||||
# CONFIG_MOUSE_SYNAPTICS_I2C is not set
|
||||
# CONFIG_MOUSE_SYNAPTICS_USB is not set
|
||||
# CONFIG_INPUT_JOYSTICK is not set
|
||||
CONFIG_INPUT_JOYSTICK=y
|
||||
# CONFIG_JOYSTICK_ANALOG is not set
|
||||
# CONFIG_JOYSTICK_A3D is not set
|
||||
# CONFIG_JOYSTICK_ADI is not set
|
||||
# CONFIG_JOYSTICK_COBRA is not set
|
||||
# CONFIG_JOYSTICK_GF2K is not set
|
||||
# CONFIG_JOYSTICK_GRIP is not set
|
||||
# CONFIG_JOYSTICK_GRIP_MP is not set
|
||||
# CONFIG_JOYSTICK_GUILLEMOT is not set
|
||||
# CONFIG_JOYSTICK_INTERACT is not set
|
||||
# CONFIG_JOYSTICK_SIDEWINDER is not set
|
||||
# CONFIG_JOYSTICK_TMDC is not set
|
||||
# CONFIG_JOYSTICK_IFORCE is not set
|
||||
# CONFIG_JOYSTICK_WARRIOR is not set
|
||||
# CONFIG_JOYSTICK_MAGELLAN is not set
|
||||
# CONFIG_JOYSTICK_SPACEORB is not set
|
||||
# CONFIG_JOYSTICK_SPACEBALL is not set
|
||||
# CONFIG_JOYSTICK_STINGER is not set
|
||||
# CONFIG_JOYSTICK_TWIDJOY is not set
|
||||
# CONFIG_JOYSTICK_ZHENHUA is not set
|
||||
# CONFIG_JOYSTICK_DB9 is not set
|
||||
# CONFIG_JOYSTICK_GAMECON is not set
|
||||
# CONFIG_JOYSTICK_TURBOGRAFX is not set
|
||||
# CONFIG_JOYSTICK_AS5011 is not set
|
||||
# CONFIG_JOYSTICK_JOYDUMP is not set
|
||||
CONFIG_JOYSTICK_XPAD=m
|
||||
CONFIG_JOYSTICK_XPAD_FF=y
|
||||
CONFIG_JOYSTICK_XPAD_LEDS=y
|
||||
# CONFIG_JOYSTICK_WALKERA0701 is not set
|
||||
# CONFIG_JOYSTICK_PSXPAD_SPI is not set
|
||||
# CONFIG_INPUT_TABLET is not set
|
||||
CONFIG_INPUT_TOUCHSCREEN=y
|
||||
CONFIG_TOUCHSCREEN_PROPERTIES=y
|
||||
@ -6185,14 +6215,6 @@ CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y
|
||||
CONFIG_ARM_UNWIND=y
|
||||
# CONFIG_DEBUG_USER is not set
|
||||
# CONFIG_DEBUG_LL is not set
|
||||
# CONFIG_DEBUG_SUN9I_UART0 is not set
|
||||
# CONFIG_DEBUG_SUNXI_UART0 is not set
|
||||
# CONFIG_DEBUG_SUNXI_UART1 is not set
|
||||
# CONFIG_DEBUG_SUNXI_R_UART is not set
|
||||
# CONFIG_DEBUG_ICEDCC is not set
|
||||
# CONFIG_DEBUG_SEMIHOSTING is not set
|
||||
# CONFIG_DEBUG_LL_UART_8250 is not set
|
||||
# CONFIG_DEBUG_LL_UART_PL01X is not set
|
||||
CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
|
||||
# CONFIG_DEBUG_UART_8250 is not set
|
||||
CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
|
||||
|
||||
@ -30,12 +30,14 @@ case $BRANCH in
|
||||
KERNELBRANCH='branch:linux-4.14.y'
|
||||
KERNELDIR=$MAINLINE_KERNEL_DIR
|
||||
BOOTPATCHDIR='u-boot-cubox-next'
|
||||
KERNEL_USE_GCC='> 7.0'
|
||||
;;
|
||||
|
||||
dev)
|
||||
KERNELSOURCE='https://github.com/SolidRun/linux-fslc'
|
||||
KERNELBRANCH='branch:3.14-1.0.x-mx6-sr'
|
||||
KERNELDIR='linux-cubox'
|
||||
KERNEL_USE_GCC='> 7.0'
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
33
config/sources/mvebu-helios4.inc
Normal file
33
config/sources/mvebu-helios4.inc
Normal file
@ -0,0 +1,33 @@
|
||||
case $BRANCH in
|
||||
default|next)
|
||||
BOOTSOURCE='https://github.com/helios-4/u-boot-marvell.git'
|
||||
BOOTBRANCH='branch:u-boot-2013.01-15t1-helios4'
|
||||
BOOTDIR='u-boot-armada'
|
||||
BOOTSCRIPT='boot-marvell.cmd:boot.cmd'
|
||||
|
||||
UBOOT_TARGET_MAP="u-boot.mmc;;u-boot.mmc"
|
||||
|
||||
UBOOT_USE_GCC='== 4.9'
|
||||
UBOOT_COMPILER='arm-linux-gnueabi-'
|
||||
|
||||
BOOTPATCHDIR='u-boot-helios4'
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
# Helios4 tweak : install and configure fancontrol
|
||||
family_tweaks_s()
|
||||
{
|
||||
chroot $SDCARD /bin/bash -c "apt-get -y -qq install fancontrol >/dev/null 2>&1"
|
||||
case $BRANCH in
|
||||
default)
|
||||
cp -R $SRC/packages/bsp/helios4/fancontrol_gpio-fan.conf $SDCARD/etc/fancontrol
|
||||
;;
|
||||
|
||||
next)
|
||||
cp -R $SRC/packages/bsp/helios4/fancontrol_pwm-fan.conf $SDCARD/etc/fancontrol
|
||||
patch $SDCARD/usr/sbin/fancontrol < $SRC/packages/bsp/helios4/fancontrol.patch
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
@ -1,15 +0,0 @@
|
||||
case $BRANCH in
|
||||
default|next)
|
||||
BOOTSOURCE='https://github.com/helios-4/u-boot-marvell.git'
|
||||
BOOTBRANCH='branch:u-boot-2013.01-15t1-helios4'
|
||||
BOOTDIR='u-boot-armada'
|
||||
BOOTSCRIPT='boot-marvell.cmd:boot.cmd'
|
||||
|
||||
UBOOT_TARGET_MAP="u-boot.mmc;;u-boot.mmc"
|
||||
|
||||
UBOOT_USE_GCC='== 4.9'
|
||||
UBOOT_COMPILER='arm-linux-gnueabi-'
|
||||
|
||||
BOOTPATCHDIR='u-boot-helios4'
|
||||
;;
|
||||
esac
|
||||
@ -1,10 +1,10 @@
|
||||
HAS_UUID_SUPPORT=yes
|
||||
|
||||
if [[ $BOARD == helios4 ]]; then
|
||||
source "${BASH_SOURCE%/*}/mvebu-u-boot-helios4.inc"
|
||||
source "${BASH_SOURCE%/*}/mvebu-helios4.inc"
|
||||
BOOTENV_FILE='helios4-default.txt'
|
||||
else
|
||||
source "${BASH_SOURCE%/*}/mvebu-u-boot-clearfog.inc"
|
||||
source "${BASH_SOURCE%/*}/mvebu-clearfog.inc"
|
||||
BOOTENV_FILE='clearfog-default.txt'
|
||||
fi
|
||||
|
||||
@ -57,5 +57,8 @@ write_uboot_platform()
|
||||
|
||||
family_tweaks()
|
||||
{
|
||||
# execute specific tweaks function if present
|
||||
[[ $(type -t family_tweaks_s) == function ]] && family_tweaks_s
|
||||
|
||||
chroot $SDCARD /bin/bash -c "apt-get -y -qq remove --auto-remove linux-sound-base alsa-base alsa-utils bluez>/dev/null 2>&1"
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ case $BRANCH in
|
||||
KERNELSOURCE='https://github.com/tobetter/linux'
|
||||
KERNELBRANCH='branch:odroidxu4-v4.2'
|
||||
KERNELDIR='linux-odroidxu-next'
|
||||
KERNEL_USE_GCC='> 6.0'
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
@ -14,6 +14,7 @@ case $BRANCH in
|
||||
KERNELSOURCE='https://github.com/hardkernel/linux'
|
||||
KERNELBRANCH='branch:odroidxu3-3.10.y'
|
||||
KERNELDIR='linux-odroidxu4'
|
||||
KERNEL_USE_GCC='> 5.0'
|
||||
CAN_BUILD_STRETCH=no
|
||||
;;
|
||||
|
||||
|
||||
@ -16,11 +16,11 @@ HAS_UUID_SUPPORT=yes
|
||||
BOOTDELAY=0
|
||||
OVERLAY_PREFIX='rk3328'
|
||||
|
||||
ATFSOURCE='https://github.com/rockchip-linux/arm-trusted-firmware'
|
||||
ATFSOURCE='https://github.com/ayufan-rock64/arm-trusted-firmware'
|
||||
ATFDIR='arm-trusted-firmware-rk3328'
|
||||
ATFBRANCH='branch:master'
|
||||
ATFBRANCH='branch:rockchip'
|
||||
ATF_USE_GCC='> 6.3'
|
||||
ATF_TARGET_MAP='PLAT=rk3328 DEBUG=1 bl31;;trust.bin'
|
||||
ATF_TARGET_MAP='PLAT=rk322xh DEBUG=1 bl31;;trust.bin'
|
||||
|
||||
case $BRANCH in
|
||||
default)
|
||||
|
||||
@ -19,18 +19,24 @@ case $BRANCH in
|
||||
KERNELSOURCE='https://github.com/mqmaker/linux-rockchip'
|
||||
KERNELBRANCH='branch:miqi/release-4.4'
|
||||
KERNELDIR='linux-rockchip'
|
||||
|
||||
KERNEL_USE_GCC='< 6.0'
|
||||
;;
|
||||
|
||||
next)
|
||||
KERNELSOURCE=$MAINLINE_KERNEL_SOURCE
|
||||
KERNELBRANCH='branch:linux-4.14.y'
|
||||
KERNELDIR=$MAINLINE_KERNEL_DIR
|
||||
|
||||
KERNEL_USE_GCC='> 7.0'
|
||||
;;
|
||||
|
||||
dev)
|
||||
KERNELSOURCE=$MAINLINE_KERNEL_SOURCE
|
||||
KERNELBRANCH='branch:master'
|
||||
KERNELDIR=$MAINLINE_KERNEL_DIR
|
||||
|
||||
KERNEL_USE_GCC='> 7.0'
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
@ -4,6 +4,7 @@ OFFSET=16
|
||||
KERNELSOURCE='https://github.com/LeMaker/linux-actions'
|
||||
KERNELBRANCH='branch:linux-3.10.y'
|
||||
KERNELDIR='linux-s500'
|
||||
KERNEL_USE_GCC='> 5.0'
|
||||
|
||||
CAN_BUILD_STRETCH=no
|
||||
|
||||
@ -17,6 +18,7 @@ case $BOARD in
|
||||
BOOTBRANCH='branch:s500-master'
|
||||
BOOTDIR='u-boot-s500'
|
||||
UBOOT_TARGET_MAP="u-boot-dtb.img;;$SRC/packages/blobs/s500/s500-bootloader-guitar.bin u-boot-dtb.img"
|
||||
UBOOT_USE_GCC='> 5.0'
|
||||
SERIALCON=ttyS3
|
||||
;;
|
||||
|
||||
@ -26,6 +28,7 @@ case $BOARD in
|
||||
BOOTDIR='u-boot-roseapple'
|
||||
BOOTPATCHDIR='u-boot-roseapple'
|
||||
UBOOT_TARGET_MAP="u-boot-dtb.img;;$SRC/packages/blobs/s500/s500-bootloader-roseapple.bin u-boot-dtb.img"
|
||||
KERNEL_USE_GCC='> 5.0'
|
||||
SERIALCON=ttyS2
|
||||
;;
|
||||
esac
|
||||
|
||||
@ -10,15 +10,29 @@ UBOOT_USE_GCC='> 6.3'
|
||||
UBOOT_COMPILER='aarch64-linux-gnu-'
|
||||
|
||||
case $BRANCH in
|
||||
default)
|
||||
KERNELSOURCE='https://github.com/friendlyarm/linux'
|
||||
KERNELBRANCH='branch:nanopi2-v4.4.y'
|
||||
KERNELDIR='linux-s5p6818'
|
||||
|
||||
KERNEL_USE_GCC='> 5.0'
|
||||
KERNEL_USE_GCC='> 6.3'
|
||||
;;
|
||||
|
||||
dev)
|
||||
KERNELSOURCE='https://github.com/rafaello7/linux-nanopi-m3'
|
||||
KERNELBRANCH='branch:master'
|
||||
KERNELDIR='linux-s5p6818'
|
||||
|
||||
KERNEL_USE_GCC='> 5.0'
|
||||
;;
|
||||
|
||||
next)
|
||||
KERNELSOURCE=$MAINLINE_KERNEL_SOURCE
|
||||
KERNELBRANCH='branch:linux-4.14.y'
|
||||
KERNELDIR=$MAINLINE_KERNEL_DIR
|
||||
|
||||
KERNEL_USE_GCC='> 7.0'
|
||||
;;
|
||||
esac
|
||||
|
||||
@ -27,7 +41,7 @@ KERNEL_IMAGE_TYPE=Image
|
||||
|
||||
KERNEL_USE_GCC='< 5.0'
|
||||
|
||||
CAN_BUILD_STRETCH=no
|
||||
CAN_BUILD_STRETCH=yes
|
||||
|
||||
HAS_UUID_SUPPORT=yes
|
||||
|
||||
|
||||
@ -8,6 +8,8 @@ case $BRANCH in
|
||||
KERNELSOURCE='https://github.com/linux-sunxi/linux-sunxi'
|
||||
KERNELBRANCH='branch:sunxi-3.4'
|
||||
KERNELDIR='linux-sunxi'
|
||||
|
||||
KERNEL_USE_GCC='> 5.0'
|
||||
;;
|
||||
|
||||
dev)
|
||||
|
||||
@ -25,10 +25,6 @@ case $BRANCH in
|
||||
UBOOT_COMPILER='arm-linux-gnueabihf-'
|
||||
UBOOT_USE_GCC='> 5.0'
|
||||
|
||||
#KERNELSOURCE='https://github.com/longsleep/linux-pine64.git'
|
||||
#KERNELBRANCH='branch:pine64-hacks-1.2'
|
||||
#KERNELDIR='linux-pine64'
|
||||
|
||||
KERNELSOURCE='https://github.com/ayufan-pine64/linux-pine64'
|
||||
KERNELBRANCH='branch:my-hacks-1.2'
|
||||
KERNELDIR='linux-pine64'
|
||||
|
||||
@ -8,7 +8,7 @@ case $BRANCH in
|
||||
KERNELSOURCE='https://github.com/linux-sunxi/linux-sunxi'
|
||||
KERNELBRANCH='branch:sunxi-3.4'
|
||||
KERNELDIR='linux-sunxi'
|
||||
KERNEL_USE_GCC='< 5.0'
|
||||
KERNEL_USE_GCC='> 5.0'
|
||||
;;
|
||||
|
||||
dev)
|
||||
|
||||
@ -8,6 +8,7 @@ case $BRANCH in
|
||||
KERNELSOURCE='https://github.com/linux-sunxi/linux-sunxi'
|
||||
KERNELBRANCH='branch:sunxi-3.4'
|
||||
KERNELDIR='linux-sunxi'
|
||||
KERNEL_USE_GCC='> 5.0'
|
||||
|
||||
CPUMAX=1010000
|
||||
;;
|
||||
|
||||
@ -10,6 +10,7 @@ case $BRANCH in
|
||||
KERNELSOURCE='https://github.com/igorpecovnik/linux'
|
||||
KERNELBRANCH='branch:sun8i'
|
||||
KERNELDIR='linux-sun8i'
|
||||
KERNEL_USE_GCC='> 5.0'
|
||||
|
||||
ASOUND_STATE='asound.state.sun8i-default'
|
||||
;;
|
||||
|
||||
@ -5,6 +5,7 @@ BOOTSCRIPT="boot-$BOARD.cmd:boot.cmd"
|
||||
BOOTENV_FILE='udoo-neo-default.txt'
|
||||
HAS_UUID_SUPPORT=yes
|
||||
UBOOT_TARGET_MAP=';;SPL u-boot.img'
|
||||
UBOOT_USE_GCC='> 5.0'
|
||||
|
||||
case $BOARD in
|
||||
udoo)
|
||||
@ -23,12 +24,16 @@ case $BRANCH in
|
||||
KERNELSOURCE='https://github.com/UDOOboard/linux_kernel'
|
||||
KERNELBRANCH='branch:3.14-1.0.x-udoo'
|
||||
KERNELDIR='linux-udoo'
|
||||
|
||||
KERNEL_USE_GCC='> 5.0'
|
||||
;;
|
||||
|
||||
next)
|
||||
KERNELSOURCE='https://github.com/patrykk/linux-udoo'
|
||||
KERNELBRANCH='branch:4.4-5.0.11.p7.3'
|
||||
KERNELDIR='linux-udoo-next'
|
||||
|
||||
KERNEL_USE_GCC='> 6.0'
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ BOOTSCRIPT="boot-$BOARD.cmd:boot.cmd"
|
||||
BOOTENV_FILE='udoo-default.txt'
|
||||
HAS_UUID_SUPPORT=yes
|
||||
UBOOT_TARGET_MAP=';;SPL u-boot.img'
|
||||
UBOOT_USE_GCC='> 5.0'
|
||||
|
||||
case $BOARD in
|
||||
udoo)
|
||||
@ -22,18 +23,24 @@ case $BRANCH in
|
||||
KERNELSOURCE='https://github.com/UDOOboard/linux_kernel'
|
||||
KERNELBRANCH='branch:3.14-1.0.x-udoo'
|
||||
KERNELDIR='linux-udoo'
|
||||
|
||||
KERNEL_USE_GCC='> 5.0'
|
||||
;;
|
||||
|
||||
next)
|
||||
KERNELSOURCE='https://github.com/patrykk/linux-udoo'
|
||||
KERNELBRANCH='branch:4.4-5.0.11.p7.3'
|
||||
KERNELDIR='linux-udoo-next'
|
||||
|
||||
KERNEL_USE_GCC='> 6.0'
|
||||
;;
|
||||
|
||||
dev)
|
||||
KERNELSOURCE=$MAINLINE_KERNEL_SOURCE
|
||||
KERNELBRANCH='branch:master'
|
||||
KERNELDIR=$MAINLINE_KERNEL_DIR
|
||||
|
||||
KERNEL_USE_GCC='> 7.0'
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
@ -76,6 +76,10 @@ fi
|
||||
|
||||
[[ $RELEASE == stretch && $CAN_BUILD_STRETCH != yes ]] && exit_with_error "Building Debian Stretch images with selected kernel is not supported"
|
||||
|
||||
[[ -n $ATFSOURCE && -z $ATF_USE_GCC ]] && exit_with_error "Error in configuration: ATF_USE_GCC is unset"
|
||||
[[ -z $UBOOT_USE_GCC ]] && exit_with_error "Error in configuration: UBOOT_USE_GCC is unset"
|
||||
[[ -z $KERNEL_USE_GCC ]] && exit_with_error "Error in configuration: KERNEL_USE_GCC is unset"
|
||||
|
||||
case $ARCH in
|
||||
arm64)
|
||||
[[ -z $KERNEL_COMPILER ]] && KERNEL_COMPILER="aarch64-linux-gnu-"
|
||||
@ -194,6 +198,9 @@ cat <<-EOF >> $DEST/debug/output.log
|
||||
## BUILD SCRIPT ENVIRONMENT
|
||||
|
||||
Version: $(cd $SRC; git rev-parse @)
|
||||
Host OS: $(lsb_release -sc)
|
||||
Host arch: $(dpkg --print-architecture)
|
||||
Dirty: $(git diff-index --quiet HEAD -- && echo No || echo Yes)
|
||||
|
||||
## BUILD CONFIGURATION
|
||||
|
||||
|
||||
@ -513,50 +513,39 @@ prepare_host()
|
||||
gawk gcc-arm-linux-gnueabihf qemu-user-static u-boot-tools uuid-dev zlib1g-dev unzip libusb-1.0-0-dev fakeroot \
|
||||
parted pkg-config libncurses5-dev whiptail debian-keyring debian-archive-keyring f2fs-tools libfile-fcntllock-perl rsync libssl-dev \
|
||||
nfs-kernel-server btrfs-tools ncurses-term p7zip-full kmod dosfstools libc6-dev-armhf-cross \
|
||||
curl patchutils python liblz4-tool libpython2.7-dev linux-base swig libpython-dev \
|
||||
locales ncurses-base pixz dialog"
|
||||
curl patchutils python liblz4-tool libpython2.7-dev linux-base swig libpython-dev aptly \
|
||||
locales ncurses-base pixz dialog systemd-container udev distcc lib32stdc++6 libc6-i386 lib32ncurses5 lib32tinfo5"
|
||||
|
||||
local codename=$(lsb_release -sc)
|
||||
display_alert "Build host OS release" "${codename:-(unknown)}" "info"
|
||||
|
||||
# ARMBIAN_UNSUPPORTED_OVERRIDE overrides the check for a supported host system
|
||||
# Keep in mind, this is NOT SUPPORTED at all. Not at all, don't ever ask about errors encountered with this enabled.
|
||||
# Since you got here, i assume you are experienced enough to read error/warning messages and solve them yourself
|
||||
if [[ -z $codename || "trusty xenial" != *"$codename"* ]]; then
|
||||
|
||||
if [[ -z $ARMBIAN_UNSUPPORTED_OVERRIDE ]]; then
|
||||
exit_with_error "It seems you ignore documentation and run an unsupported build system: ${codename:-(unknown)}"
|
||||
# Ubuntu Xenial x86_64 is the only supported host OS release
|
||||
# Using Docker/VirtualBox/Vagrant is the only supported way to run the build script on other Linux distributions
|
||||
# NO_HOST_RELEASE_CHECK overrides the check for a supported host system
|
||||
# Disable host OS check at your own risk, any issues reported with unsupported releases will be closed without a discussion
|
||||
if [[ -z $codename || "xenial" != *"$codename"* ]]; then
|
||||
if [[ $NO_HOST_RELEASE_CHECK == yes ]]; then
|
||||
display_alert "You are running on an unsupported system" "${codename:-(unknown)}" "wrn"
|
||||
display_alert "Do not report any errors, warnings or other issues encountered beyond this point" "" "wrn"
|
||||
else
|
||||
display_alert "You are running on an unsupported system: ${codename:-(unknown)}. Do not report any errors, warnings or dragons encountered beyond this point."
|
||||
exit_with_error "It seems you ignore documentation and run an unsupported build system: ${codename:-(unknown)}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ $codename == trusty ]]; then
|
||||
display_alert "Note: Ubuntu Trusty environment support will be removed before the end of 2017" "" "wrn"
|
||||
display_alert "Please upgrade your compilation environment to Ubuntu Xenial" "" "wrn"
|
||||
display_alert "Press <Enter> to continue"
|
||||
read
|
||||
fi
|
||||
|
||||
if [[ $codename == xenial ]]; then
|
||||
hostdeps="$hostdeps systemd-container udev distcc \
|
||||
lib32stdc++6 libc6-i386 lib32ncurses5 lib32tinfo5 aptly"
|
||||
grep -q i386 <(dpkg --print-foreign-architectures) || dpkg --add-architecture i386
|
||||
if systemd-detect-virt -q -c; then
|
||||
display_alert "Running in container" "$(systemd-detect-virt)" "info"
|
||||
# disable apt-cacher unless NO_APT_CACHER=no is not specified explicitly
|
||||
if [[ $NO_APT_CACHER != no ]]; then
|
||||
display_alert "apt-cacher is disabled in containers, set NO_APT_CACHER=no to override" "" "wrn"
|
||||
NO_APT_CACHER=yes
|
||||
fi
|
||||
CONTAINER_COMPAT=yes
|
||||
# trying to use nested containers is not a good idea, so don't permit EXTERNAL_NEW=compile
|
||||
if [[ $EXTERNAL_NEW == compile ]]; then
|
||||
display_alert "EXTERNAL_NEW=compile is not available when running in container, setting to prebuilt" "" "wrn"
|
||||
EXTERNAL_NEW=prebuilt
|
||||
fi
|
||||
SYNC_CLOCK=no
|
||||
grep -q i386 <(dpkg --print-foreign-architectures) || dpkg --add-architecture i386
|
||||
if systemd-detect-virt -q -c; then
|
||||
display_alert "Running in container" "$(systemd-detect-virt)" "info"
|
||||
# disable apt-cacher unless NO_APT_CACHER=no is not specified explicitly
|
||||
if [[ $NO_APT_CACHER != no ]]; then
|
||||
display_alert "apt-cacher is disabled in containers, set NO_APT_CACHER=no to override" "" "wrn"
|
||||
NO_APT_CACHER=yes
|
||||
fi
|
||||
CONTAINER_COMPAT=yes
|
||||
# trying to use nested containers is not a good idea, so don't permit EXTERNAL_NEW=compile
|
||||
if [[ $EXTERNAL_NEW == compile ]]; then
|
||||
display_alert "EXTERNAL_NEW=compile is not available when running in container, setting to prebuilt" "" "wrn"
|
||||
EXTERNAL_NEW=prebuilt
|
||||
fi
|
||||
SYNC_CLOCK=no
|
||||
fi
|
||||
|
||||
# warning: apt-cacher-ng will fail if installed and used both on host and in container/chroot environment with shared network
|
||||
@ -590,7 +579,7 @@ prepare_host()
|
||||
update-ccache-symlinks
|
||||
fi
|
||||
|
||||
if [[ $codename == xenial && $(dpkg-query -W -f='${db:Status-Abbrev}\n' 'zlib1g:i386' 2>/dev/null) != *ii* ]]; then
|
||||
if [[ $(dpkg-query -W -f='${db:Status-Abbrev}\n' 'zlib1g:i386' 2>/dev/null) != *ii* ]]; then
|
||||
apt install -qq -y --no-install-recommends zlib1g:i386 >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
@ -658,7 +647,7 @@ prepare_host()
|
||||
echo 'http://www.armbian.com/using-armbian-tools/' >> $SRC/userpatches/README
|
||||
fi
|
||||
|
||||
# check free space (basic), doesn't work on Trusty
|
||||
# check free space (basic)
|
||||
local freespace=$(findmnt --target $SRC -n -o AVAIL -b 2>/dev/null) # in bytes
|
||||
if [[ -n $freespace && $(( $freespace / 1073741824 )) -lt 10 ]]; then
|
||||
display_alert "Low free space left" "$(( $freespace / 1073741824 )) GiB" "wrn"
|
||||
|
||||
@ -147,16 +147,16 @@ ParseOptions() {
|
||||
;;
|
||||
u)
|
||||
# Upload /var/log/armhwinfo.log with additional support info
|
||||
fping sprunge.us 2>/dev/null | grep -q alive || \
|
||||
fping ix.io 2>/dev/null | grep -q alive || \
|
||||
(echo -e "\nNetwork/firewall problem detected. Not able to upload debug info.\nPlease fix this or use \"-U\" instead and upload ${BOLD}whole output${NC} manually\n" >&2 ; exit 1)
|
||||
which curl >/dev/null 2>&1 || apt-get -f -qq -y install curl
|
||||
echo -e "System diagnosis information will now be uploaded to \c"
|
||||
# we obfuscate IPv4 addresses somehow but not too much, MAC addresses have to remain
|
||||
# in clear since otherwise the log becomes worthless due to randomly generated
|
||||
# in clear since otherwise the log becomes worthless due to randomly generated
|
||||
# addresses here and there that might conflict
|
||||
CollectSupportInfo \
|
||||
| sed -E 's/([0-9]{1,3}\.)([0-9]{1,3}\.)([0-9]{1,3}\.)([0-9]{1,3})/XXX.XXX.\3\4/g' \
|
||||
| curl -F 'sprunge=<-' http://sprunge.us
|
||||
| curl -F 'f:1=<-' ix.io
|
||||
echo -e "Please post the URL in the forum where you've been asked for.\n"
|
||||
exit 0
|
||||
;;
|
||||
@ -210,7 +210,7 @@ ParseOptions() {
|
||||
exit 0
|
||||
;;
|
||||
D)
|
||||
fping sprunge.us 2>/dev/null | grep -q alive || \
|
||||
fping ix.io 2>/dev/null | grep -q alive || \
|
||||
(echo "Network/firewall problem detected. Please fix this prior to installing RPi-Monitor." >&2 ; exit 1)
|
||||
DebugOutput="$(mktemp /tmp/${0##*/}.XXXXXX)"
|
||||
trap "rm \"${DebugOutput}\" ; exit 0" 0 1 2 3 15
|
||||
@ -222,9 +222,9 @@ ParseOptions() {
|
||||
echo -e "\nDebug output has been collected at the following URL: \c"
|
||||
(cat "${DebugOutput}"; echo -e "\n\n\ngdisk.txt contents:\n" ; cat "${MyTempDir}/gdisk.txt" ;\
|
||||
echo -e "\n\n\nsmartctl.txt contents:\n" ; cat "${MyTempDir}/smartctl.txt") \
|
||||
| curl -F 'sprunge=<-' http://sprunge.us
|
||||
| curl -F 'f:1=<-' ix.io
|
||||
echo -e "Please post the URL in the Armbian forum where you've been asked for."
|
||||
exit 0
|
||||
exit 0
|
||||
;;
|
||||
c|C)
|
||||
# check card mode
|
||||
@ -830,7 +830,7 @@ CollectSupportInfo() {
|
||||
stress -t 3 -c $(grep -c processor /proc/cpuinfo) --backoff 250 >/dev/null 2>&1 &
|
||||
"$0" -s | grep "^[0-9]"
|
||||
# Include name resolving information only if upload is not possible
|
||||
fping sprunge.us 2>/dev/null | grep -q alive || \
|
||||
fping ix.io 2>/dev/null | grep -q alive || \
|
||||
[ -f /etc/resolv.conf ] && echo -e "\n### resolv.conf\n\n$(ls -la /etc/resolv.conf ; cat /etc/resolv.conf)" || \
|
||||
echo -e "\n### resolv.conf does not exist or readable"
|
||||
echo -e "\n### Current sysinfo:\n\n$(iostat -p ALL | grep -v "^loop")\n\n$(vmstat -w)\n\n$(free -h)\n\n$(uptime)\n\n$(dmesg | tail -n 250)"
|
||||
|
||||
12
packages/bsp/helios4/fancontrol.patch
Normal file
12
packages/bsp/helios4/fancontrol.patch
Normal file
@ -0,0 +1,12 @@
|
||||
@@ -157,9 +157,9 @@
|
||||
|
||||
function DevicePath()
|
||||
{
|
||||
- if [ -h "$1/device" ]
|
||||
+ if [ -h "$1" ]
|
||||
then
|
||||
- readlink -f "$1/device" | sed -e 's/^\/sys\///'
|
||||
+ readlink -f "$1" | sed -e 's/^\/sys\///;s/\/hwmon\/.*//'
|
||||
fi
|
||||
}
|
||||
|
||||
12
packages/bsp/helios4/fancontrol_gpio-fan.conf
Normal file
12
packages/bsp/helios4/fancontrol_gpio-fan.conf
Normal file
@ -0,0 +1,12 @@
|
||||
# Helios4 GPIO Fan Control Configuration
|
||||
# This is a temporary configuration while relying on gpio-fan driver.
|
||||
# Only low or full speed is supported.
|
||||
# Temp source : lm75 sensor
|
||||
INTERVAL=10
|
||||
DEVPATH=hwmon0=devices/platform/j10-pwm hwmon1=devices/platform/j17-pwm hwmon2=devices/platform/soc/soc:internal-regs/f1011000.i2c/i2c-0/0-004c
|
||||
DEVNAME=hwmon0=gpio_fan hwmon1=gpio_fan hwmon2=lm75
|
||||
FCTEMPS=hwmon0/pwm1=hwmon2/temp1_input hwmon1/pwm1=hwmon2/temp1_input
|
||||
MINTEMP=hwmon0/pwm1=45 hwmon1/pwm1=45
|
||||
MAXTEMP=hwmon0/pwm1=65 hwmon1/pwm1=65
|
||||
MINSTART=hwmon0/pwm1=1 hwmon1/pwm1=1
|
||||
MINSTOP=hwmon0/pwm1=0 hwmon1/pwm1=0
|
||||
11
packages/bsp/helios4/fancontrol_pwm-fan.conf
Normal file
11
packages/bsp/helios4/fancontrol_pwm-fan.conf
Normal file
@ -0,0 +1,11 @@
|
||||
# Helios4 PWM Fan Control Configuration
|
||||
# Temp source : armada_thermal sensor
|
||||
INTERVAL=10
|
||||
DEVPATH=hwmon1=devices/virtual hwmon2=devices/platform/j10-pwm hwmon3=devices/platform/j17-pwm hwmon4=devices/platform/soc/soc:internal-regs/f1011000.i2c/i2c-0/0-004c
|
||||
DEVNAME=hwmon1=armada_thermal hwmon2=pwmfan hwmon3=pwmfan hwmon4=lm75
|
||||
FCTEMPS=hwmon2/pwm1=hwmon1/temp1_input hwmon3/pwm1=hwmon1/temp1_input
|
||||
MINTEMP=hwmon2/pwm1=55 hwmon3/pwm1=55
|
||||
MAXTEMP=hwmon2/pwm1=95 hwmon3/pwm1=95
|
||||
MINSTART=hwmon2/pwm1=100 hwmon3/pwm1=100
|
||||
MINSTOP=hwmon2/pwm1=50 hwmon3/pwm1=50
|
||||
|
||||
@ -24,7 +24,7 @@ compile_armbian-config()
|
||||
Architecture: all
|
||||
Maintainer: $MAINTAINER <$MAINTAINERMAIL>
|
||||
Replaces: armbian-bsp
|
||||
Depends: bash, bc, expect, rcconf, dialog, unzip, build-essential, apt-transport-https, html2text
|
||||
Depends: bash, bc, expect, rcconf, dialog, unzip, build-essential, apt-transport-https
|
||||
Recommends: network-manager, armbian-bsp
|
||||
Section: utils
|
||||
Priority: optional
|
||||
|
||||
2623
patch/kernel/mvebu-default/04-patch-4.4.107-108.patch
Normal file
2623
patch/kernel/mvebu-default/04-patch-4.4.107-108.patch
Normal file
File diff suppressed because it is too large
Load Diff
2275
patch/kernel/mvebu-default/04-patch-4.4.108-109.patch
Normal file
2275
patch/kernel/mvebu-default/04-patch-4.4.108-109.patch
Normal file
File diff suppressed because it is too large
Load Diff
2814
patch/kernel/mvebu-default/04-patch-4.4.109-110.patch
Normal file
2814
patch/kernel/mvebu-default/04-patch-4.4.109-110.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,488 +0,0 @@
|
||||
From 65bce3cd01230b283915be86196f5e1318c18dd6 Mon Sep 17 00:00:00 2001
|
||||
From: aprayoga <adit.prayoga@gmail.com>
|
||||
Date: Sun, 3 Sep 2017 15:59:11 +0800
|
||||
Subject: gpio: mvebu: Add limited PWM support
|
||||
|
||||
backported from https://patchwork.kernel.org/patch/9681399/
|
||||
|
||||
* Remove atomic PWM API portion as this is not supported on LK4.4
|
||||
and use https://patchwork.ozlabs.org/patch/739591/ instead.
|
||||
---
|
||||
.../devicetree/bindings/gpio/gpio-mvebu.txt | 31 +++
|
||||
MAINTAINERS | 2 +
|
||||
drivers/gpio/gpio-mvebu.c | 309 ++++++++++++++++++++-
|
||||
3 files changed, 328 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/gpio/gpio-mvebu.txt b/Documentation/devicetree/bindings/gpio/gpio-mvebu.txt
|
||||
index 6b76891..b6cdcb2 100644
|
||||
--- a/Documentation/devicetree/bindings/gpio/gpio-mvebu.txt
|
||||
+++ b/Documentation/devicetree/bindings/gpio/gpio-mvebu.txt
|
||||
@@ -46,6 +46,23 @@ Optional:
|
||||
The base of CP0 bank0 should be 20 (after AP-806 pins) the base of CP0 bank1 should be
|
||||
52 (after AP-806, and CP0 bank0 pins)
|
||||
|
||||
+Optional properties:
|
||||
+
|
||||
+In order to use the gpio lines in PWM mode, some additional optional
|
||||
+properties are required. Only Armada 370 and XP support these properties.
|
||||
+
|
||||
+- reg: an additional register set is needed, for the GPIO Blink
|
||||
+ Counter on/off registers.
|
||||
+
|
||||
+- reg-names: Must contain an entry "pwm" corresponding to the
|
||||
+ additional register range needed for pwm operation.
|
||||
+
|
||||
+- #pwm-cells: Should be two. The first cell is the pin number. The
|
||||
+ second cell is reserved for flags and should be set to 0, so it has a
|
||||
+ known value. It then becomes possible to use it in the future.
|
||||
+
|
||||
+- clocks: Must be a phandle to the clock for the gpio controller.
|
||||
+
|
||||
Example:
|
||||
|
||||
gpio0: gpio@d0018100 {
|
||||
@@ -59,3 +76,17 @@ Example:
|
||||
#interrupt-cells = <2>;
|
||||
interrupts = <16>, <17>, <18>, <19>;
|
||||
};
|
||||
+
|
||||
+ gpio1: gpio@18140 {
|
||||
+ compatible = "marvell,armada-370-xp-gpio";
|
||||
+ reg = <0x18140 0x40>, <0x181c8 0x08>;
|
||||
+ reg-names = "gpio", "pwm";
|
||||
+ ngpios = <17>;
|
||||
+ gpio-controller;
|
||||
+ #gpio-cells = <2>;
|
||||
+ #pwm-cells = <2>;
|
||||
+ interrupt-controller;
|
||||
+ #interrupt-cells = <2>;
|
||||
+ interrupts = <87>, <88>, <89>;
|
||||
+ clocks = <&coreclk 0>;
|
||||
+ };
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index 7008b0d..d272aca 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -8635,6 +8635,8 @@ F: include/linux/pwm.h
|
||||
F: drivers/pwm/
|
||||
F: drivers/video/backlight/pwm_bl.c
|
||||
F: include/linux/pwm_backlight.h
|
||||
+F: drivers/gpio/gpio-mvebu.c
|
||||
+F: Documentation/devicetree/bindings/gpio/gpio-mvebu.txt
|
||||
|
||||
PXA2xx/PXA3xx SUPPORT
|
||||
M: Daniel Mack <daniel@zonque.org>
|
||||
diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
|
||||
index ffea532..8775123 100644
|
||||
--- a/drivers/gpio/gpio-mvebu.c
|
||||
+++ b/drivers/gpio/gpio-mvebu.c
|
||||
@@ -42,29 +42,43 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_device.h>
|
||||
+#include <linux/pwm.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/irqchip/chained_irq.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+
|
||||
+#include "gpiolib.h"
|
||||
|
||||
/*
|
||||
* GPIO unit register offsets.
|
||||
*/
|
||||
-#define GPIO_OUT_OFF 0x0000
|
||||
-#define GPIO_IO_CONF_OFF 0x0004
|
||||
-#define GPIO_BLINK_EN_OFF 0x0008
|
||||
-#define GPIO_IN_POL_OFF 0x000c
|
||||
-#define GPIO_DATA_IN_OFF 0x0010
|
||||
-#define GPIO_EDGE_CAUSE_OFF 0x0014
|
||||
-#define GPIO_EDGE_MASK_OFF 0x0018
|
||||
-#define GPIO_LEVEL_MASK_OFF 0x001c
|
||||
+#define GPIO_OUT_OFF 0x0000
|
||||
+#define GPIO_IO_CONF_OFF 0x0004
|
||||
+#define GPIO_BLINK_EN_OFF 0x0008
|
||||
+#define GPIO_IN_POL_OFF 0x000c
|
||||
+#define GPIO_DATA_IN_OFF 0x0010
|
||||
+#define GPIO_EDGE_CAUSE_OFF 0x0014
|
||||
+#define GPIO_EDGE_MASK_OFF 0x0018
|
||||
+#define GPIO_LEVEL_MASK_OFF 0x001c
|
||||
+#define GPIO_BLINK_CNT_SELECT_OFF 0x0020
|
||||
+
|
||||
+/*
|
||||
+ * PWM register offsets.
|
||||
+ */
|
||||
+#define PWM_BLINK_ON_DURATION_OFF 0x0
|
||||
+#define PWM_BLINK_OFF_DURATION_OFF 0x4
|
||||
+
|
||||
|
||||
/* The MV78200 has per-CPU registers for edge mask and level mask */
|
||||
#define GPIO_EDGE_MASK_MV78200_OFF(cpu) ((cpu) ? 0x30 : 0x18)
|
||||
#define GPIO_LEVEL_MASK_MV78200_OFF(cpu) ((cpu) ? 0x34 : 0x1C)
|
||||
|
||||
-/* The Armada XP has per-CPU registers for interrupt cause, interrupt
|
||||
+/*
|
||||
+ * The Armada XP has per-CPU registers for interrupt cause, interrupt
|
||||
* mask and interrupt level mask. Those are relative to the
|
||||
- * percpu_membase. */
|
||||
+ * percpu_membase.
|
||||
+ */
|
||||
#define GPIO_EDGE_CAUSE_ARMADAXP_OFF(cpu) ((cpu) * 0x4)
|
||||
#define GPIO_EDGE_MASK_ARMADAXP_OFF(cpu) (0x10 + (cpu) * 0x4)
|
||||
#define GPIO_LEVEL_MASK_ARMADAXP_OFF(cpu) (0x20 + (cpu) * 0x4)
|
||||
@@ -75,6 +89,23 @@
|
||||
|
||||
#define MVEBU_MAX_GPIO_PER_BANK 32
|
||||
|
||||
+struct mvebu_pwm {
|
||||
+ void __iomem *membase;
|
||||
+ unsigned long clk_rate;
|
||||
+ struct gpio_desc *gpiod;
|
||||
+ bool used;
|
||||
+ unsigned int pin;
|
||||
+ struct pwm_chip chip;
|
||||
+ int id;
|
||||
+ spinlock_t lock;
|
||||
+ struct mvebu_gpio_chip *mvchip;
|
||||
+
|
||||
+ /* Used to preserve GPIO/PWM registers across suspend/resume */
|
||||
+ u32 blink_select;
|
||||
+ u32 blink_on_duration;
|
||||
+ u32 blink_off_duration;
|
||||
+};
|
||||
+
|
||||
struct mvebu_gpio_chip {
|
||||
struct gpio_chip chip;
|
||||
spinlock_t lock;
|
||||
@@ -84,6 +115,10 @@ struct mvebu_gpio_chip {
|
||||
struct irq_domain *domain;
|
||||
int soc_variant;
|
||||
|
||||
+ /* Used for PWM support */
|
||||
+ struct clk *clk;
|
||||
+ struct mvebu_pwm *mvpwm;
|
||||
+
|
||||
/* Used to preserve GPIO registers across suspend/resume */
|
||||
u32 out_reg;
|
||||
u32 io_conf_reg;
|
||||
@@ -102,6 +137,11 @@ static inline void __iomem *mvebu_gpioreg_out(struct mvebu_gpio_chip *mvchip)
|
||||
return mvchip->membase + GPIO_OUT_OFF;
|
||||
}
|
||||
|
||||
+static void __iomem *mvebu_gpioreg_blink_select(struct mvebu_gpio_chip *mvchip)
|
||||
+{
|
||||
+ return mvchip->membase + GPIO_BLINK_CNT_SELECT_OFF;
|
||||
+}
|
||||
+
|
||||
static inline void __iomem *mvebu_gpioreg_blink(struct mvebu_gpio_chip *mvchip)
|
||||
{
|
||||
return mvchip->membase + GPIO_BLINK_EN_OFF;
|
||||
@@ -182,6 +222,20 @@ static void __iomem *mvebu_gpioreg_level_mask(struct mvebu_gpio_chip *mvchip)
|
||||
}
|
||||
|
||||
/*
|
||||
+ * Functions returning addresses of individual registers for a given
|
||||
+ * PWM controller.
|
||||
+ */
|
||||
+static void __iomem *mvebu_pwmreg_blink_on_duration(struct mvebu_pwm *mvpwm)
|
||||
+{
|
||||
+ return mvpwm->membase + PWM_BLINK_ON_DURATION_OFF;
|
||||
+}
|
||||
+
|
||||
+static void __iomem *mvebu_pwmreg_blink_off_duration(struct mvebu_pwm *mvpwm)
|
||||
+{
|
||||
+ return mvpwm->membase + PWM_BLINK_OFF_DURATION_OFF;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* Functions implementing the gpio_chip methods
|
||||
*/
|
||||
|
||||
@@ -489,6 +543,220 @@ static void mvebu_gpio_irq_handler(struct irq_desc *desc)
|
||||
chained_irq_exit(chip, desc);
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Functions implementing the pwm_chip methods
|
||||
+ */
|
||||
+static struct mvebu_pwm *to_mvebu_pwm(struct pwm_chip *chip)
|
||||
+{
|
||||
+ return container_of(chip, struct mvebu_pwm, chip);
|
||||
+}
|
||||
+
|
||||
+static int mvebu_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
+{
|
||||
+ struct mvebu_pwm *mvpwm = to_mvebu_pwm(chip);
|
||||
+ struct mvebu_gpio_chip *mvchip = mvpwm->mvchip;
|
||||
+ struct gpio_desc *desc;
|
||||
+ unsigned long flags;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ spin_lock_irqsave(&mvpwm->lock, flags);
|
||||
+ if (mvpwm->gpiod) {
|
||||
+ ret = -EBUSY;
|
||||
+ } else {
|
||||
+ desc = gpio_to_desc(mvchip->chip.base + pwm->hwpwm);
|
||||
+ if (!desc) {
|
||||
+ ret = -ENODEV;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ ret = gpiod_request(desc, "mvebu-pwm");
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+
|
||||
+ ret = gpiod_direction_output(desc, 0);
|
||||
+ if (ret) {
|
||||
+ gpiod_free(desc);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ mvpwm->gpiod = desc;
|
||||
+ mvpwm->pin = pwm->pwm - mvchip->chip.base;
|
||||
+ mvpwm->used = true;
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ spin_unlock_irqrestore(&mvpwm->lock, flags);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void mvebu_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
+{
|
||||
+ struct mvebu_pwm *mvpwm = to_mvebu_pwm(chip);
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ spin_lock_irqsave(&mvpwm->lock, flags);
|
||||
+ gpiod_free(mvpwm->gpiod);
|
||||
+ mvpwm->used = false;
|
||||
+ spin_unlock_irqrestore(&mvpwm->lock, flags);
|
||||
+}
|
||||
+
|
||||
+static int mvebu_pwm_config(struct pwm_chip *chip, struct pwm_device *pwmd,
|
||||
+ int duty_ns, int period_ns)
|
||||
+{
|
||||
+ struct mvebu_pwm *pwm = to_mvebu_pwm(chip);
|
||||
+ struct mvebu_gpio_chip *mvchip = pwm->mvchip;
|
||||
+ unsigned int on, off;
|
||||
+ unsigned long long val;
|
||||
+ u32 u;
|
||||
+
|
||||
+ val = (unsigned long long) pwm->clk_rate * duty_ns;
|
||||
+ do_div(val, NSEC_PER_SEC);
|
||||
+ if (val > UINT_MAX)
|
||||
+ return -EINVAL;
|
||||
+ if (val)
|
||||
+ on = val;
|
||||
+ else
|
||||
+ on = 1;
|
||||
+
|
||||
+ val = (unsigned long long) pwm->clk_rate * (period_ns - duty_ns);
|
||||
+ do_div(val, NSEC_PER_SEC);
|
||||
+ if (val > UINT_MAX)
|
||||
+ return -EINVAL;
|
||||
+ if (val)
|
||||
+ off = val;
|
||||
+ else
|
||||
+ off = 1;
|
||||
+
|
||||
+ u = readl_relaxed(mvebu_gpioreg_blink_select(mvchip));
|
||||
+ u &= ~(1 << pwm->pin);
|
||||
+ u |= (pwm->id << pwm->pin);
|
||||
+ writel_relaxed(u, mvebu_gpioreg_blink_select(mvchip));
|
||||
+
|
||||
+ writel_relaxed(on, mvebu_pwmreg_blink_on_duration(pwm));
|
||||
+ writel_relaxed(off, mvebu_pwmreg_blink_off_duration(pwm));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mvebu_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
+{
|
||||
+ struct mvebu_pwm *mvpwm = to_mvebu_pwm(chip);
|
||||
+ struct mvebu_gpio_chip *mvchip = mvpwm->mvchip;
|
||||
+
|
||||
+ mvebu_gpio_blink(&mvchip->chip, mvpwm->pin, 1);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void mvebu_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
+{
|
||||
+ struct mvebu_pwm *mvpwm = to_mvebu_pwm(chip);
|
||||
+ struct mvebu_gpio_chip *mvchip = mvpwm->mvchip;
|
||||
+
|
||||
+ mvebu_gpio_blink(&mvchip->chip, mvpwm->pin, 0);
|
||||
+}
|
||||
+
|
||||
+static const struct pwm_ops mvebu_pwm_ops = {
|
||||
+ .request = mvebu_pwm_request,
|
||||
+ .free = mvebu_pwm_free,
|
||||
+ .config = mvebu_pwm_config,
|
||||
+ .enable = mvebu_pwm_enable,
|
||||
+ .disable = mvebu_pwm_disable,
|
||||
+ .owner = THIS_MODULE,
|
||||
+};
|
||||
+
|
||||
+static void mvebu_pwm_suspend(struct mvebu_gpio_chip *mvchip)
|
||||
+{
|
||||
+ struct mvebu_pwm *mvpwm = mvchip->mvpwm;
|
||||
+
|
||||
+ mvpwm->blink_select =
|
||||
+ readl_relaxed(mvebu_gpioreg_blink_select(mvchip));
|
||||
+ mvpwm->blink_on_duration =
|
||||
+ readl_relaxed(mvebu_pwmreg_blink_on_duration(mvpwm));
|
||||
+ mvpwm->blink_off_duration =
|
||||
+ readl_relaxed(mvebu_pwmreg_blink_off_duration(mvpwm));
|
||||
+}
|
||||
+
|
||||
+static void mvebu_pwm_resume(struct mvebu_gpio_chip *mvchip)
|
||||
+{
|
||||
+ struct mvebu_pwm *mvpwm = mvchip->mvpwm;
|
||||
+
|
||||
+ writel_relaxed(mvpwm->blink_select,
|
||||
+ mvebu_gpioreg_blink_select(mvchip));
|
||||
+ writel_relaxed(mvpwm->blink_on_duration,
|
||||
+ mvebu_pwmreg_blink_on_duration(mvpwm));
|
||||
+ writel_relaxed(mvpwm->blink_off_duration,
|
||||
+ mvebu_pwmreg_blink_off_duration(mvpwm));
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Armada 370/XP has simple PWM support for gpio lines. Other SoCs
|
||||
+ * don't have this hardware. So if we don't have the necessary
|
||||
+ * resource, it is not an error.
|
||||
+ */
|
||||
+static int mvebu_pwm_probe(struct platform_device *pdev,
|
||||
+ struct mvebu_gpio_chip *mvchip,
|
||||
+ int id)
|
||||
+{
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct mvebu_pwm *mvpwm;
|
||||
+ struct resource *res;
|
||||
+ u32 set;
|
||||
+
|
||||
+ if (!of_device_is_compatible(mvchip->chip.of_node,
|
||||
+ "marvell,armada-370-xp-gpio"))
|
||||
+ return 0;
|
||||
+
|
||||
+ if (IS_ERR(mvchip->clk))
|
||||
+ return PTR_ERR(mvchip->clk);
|
||||
+
|
||||
+ /*
|
||||
+ * There are only two sets of PWM configuration registers for
|
||||
+ * all the GPIO lines on those SoCs which this driver reserves
|
||||
+ * for the first two GPIO chips. So if the resource is missing
|
||||
+ * we can't treat it as an error.
|
||||
+ */
|
||||
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwm");
|
||||
+ if (!res)
|
||||
+ return 0;
|
||||
+
|
||||
+ /*
|
||||
+ * Use set A for lines of GPIO chip with id 0, B for GPIO chip
|
||||
+ * with id 1. Don't allow further GPIO chips to be used for PWM.
|
||||
+ */
|
||||
+ if (id == 0)
|
||||
+ set = 0;
|
||||
+ else if (id == 1)
|
||||
+ set = U32_MAX;
|
||||
+ else
|
||||
+ return -EINVAL;
|
||||
+ writel_relaxed(set, mvebu_gpioreg_blink_select(mvchip));
|
||||
+ mvpwm->id = id;
|
||||
+
|
||||
+ mvpwm = devm_kzalloc(dev, sizeof(struct mvebu_pwm), GFP_KERNEL);
|
||||
+ if (!mvpwm)
|
||||
+ return -ENOMEM;
|
||||
+ mvchip->mvpwm = mvpwm;
|
||||
+ mvpwm->mvchip = mvchip;
|
||||
+
|
||||
+ mvpwm->membase = devm_ioremap_resource(dev, res);
|
||||
+ if (IS_ERR(mvpwm->membase))
|
||||
+ return PTR_ERR(mvpwm->membase);
|
||||
+
|
||||
+ mvpwm->clk_rate = clk_get_rate(mvchip->clk);
|
||||
+ if (!mvpwm->clk_rate) {
|
||||
+ dev_err(dev, "failed to get clock rate\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ mvpwm->chip.dev = dev;
|
||||
+ mvpwm->chip.ops = &mvebu_pwm_ops;
|
||||
+ mvpwm->chip.npwm = mvchip->chip.ngpio;
|
||||
+
|
||||
+ spin_lock_init(&mvpwm->lock);
|
||||
+
|
||||
+ return pwmchip_add(&mvpwm->chip);
|
||||
+}
|
||||
+
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#include <linux/seq_file.h>
|
||||
|
||||
@@ -561,6 +829,10 @@ static const struct of_device_id mvebu_gpio_of_match[] = {
|
||||
.data = (void *) MVEBU_GPIO_SOC_VARIANT_ARMADAXP,
|
||||
},
|
||||
{
|
||||
+ .compatible = "marvell,armada-370-xp-gpio",
|
||||
+ .data = (void *) MVEBU_GPIO_SOC_VARIANT_ORION,
|
||||
+ },
|
||||
+ {
|
||||
/* sentinel */
|
||||
},
|
||||
};
|
||||
@@ -607,6 +879,9 @@ static int mvebu_gpio_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
BUG();
|
||||
}
|
||||
|
||||
+ if (IS_ENABLED(CONFIG_PWM))
|
||||
+ mvebu_pwm_suspend(mvchip);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -650,6 +925,9 @@ static int mvebu_gpio_resume(struct platform_device *pdev)
|
||||
BUG();
|
||||
}
|
||||
|
||||
+ if (IS_ENABLED(CONFIG_PWM))
|
||||
+ mvebu_pwm_resume(mvchip);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -661,7 +939,6 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
|
||||
struct resource *res;
|
||||
struct irq_chip_generic *gc;
|
||||
struct irq_chip_type *ct;
|
||||
- struct clk *clk;
|
||||
unsigned int ngpios;
|
||||
unsigned int gpio_base = -1;
|
||||
int soc_variant;
|
||||
@@ -695,10 +972,10 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
|
||||
return id;
|
||||
}
|
||||
|
||||
- clk = devm_clk_get(&pdev->dev, NULL);
|
||||
+ mvchip->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
/* Not all SoCs require a clock.*/
|
||||
- if (!IS_ERR(clk))
|
||||
- clk_prepare_enable(clk);
|
||||
+ if (!IS_ERR(mvchip->clk))
|
||||
+ clk_prepare_enable(mvchip->clk);
|
||||
|
||||
mvchip->soc_variant = soc_variant;
|
||||
mvchip->chip.label = dev_name(&pdev->dev);
|
||||
@@ -835,6 +1112,10 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
|
||||
goto err_generic_chip;
|
||||
}
|
||||
|
||||
+ /* Armada 370/XP has simple PWM support for GPIO lines */
|
||||
+ if (IS_ENABLED(CONFIG_PWM))
|
||||
+ return mvebu_pwm_probe(pdev, mvchip, id);
|
||||
+
|
||||
return 0;
|
||||
|
||||
err_generic_chip:
|
||||
--
|
||||
2.7.4
|
||||
|
||||
@ -1,62 +0,0 @@
|
||||
From e85a492b45f49e374f544bbffe8c975b1dabe87f Mon Sep 17 00:00:00 2001
|
||||
From: aprayoga <adit.prayoga@gmail.com>
|
||||
Date: Sun, 3 Sep 2017 16:08:59 +0800
|
||||
Subject: ARM: dts: mvebu: Add PWM properties to .dtsi (armada-38x)
|
||||
|
||||
reference:
|
||||
https://patchwork.kernel.org/patch/9681397/
|
||||
---
|
||||
arch/arm/boot/dts/armada-38x.dtsi | 16 ++++++++++++----
|
||||
1 file changed, 12 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi
|
||||
index a73cbe2..f87204f 100644
|
||||
--- a/arch/arm/boot/dts/armada-38x.dtsi
|
||||
+++ b/arch/arm/boot/dts/armada-38x.dtsi
|
||||
@@ -345,31 +345,39 @@
|
||||
};
|
||||
|
||||
gpio0: gpio@18100 {
|
||||
- compatible = "marvell,orion-gpio";
|
||||
- reg = <0x18100 0x40>;
|
||||
+ compatible = "marvell,armada-370-xp-gpio",
|
||||
+ "marvell,orion-gpio";
|
||||
+ reg = <0x18100 0x40>, <0x181c0 0x08>;
|
||||
+ reg-names = "gpio", "pwm";
|
||||
ngpios = <32>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
+ #pwm-cells = <2>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&coreclk 0>;
|
||||
};
|
||||
|
||||
gpio1: gpio@18140 {
|
||||
- compatible = "marvell,orion-gpio";
|
||||
- reg = <0x18140 0x40>;
|
||||
+ compatible = "marvell,armada-370-xp-gpio",
|
||||
+ "marvell,orion-gpio";
|
||||
+ reg = <0x18140 0x40>, <0x181c8 0x08>;
|
||||
+ reg-names = "gpio", "pwm";
|
||||
ngpios = <28>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
+ #pwm-cells = <2>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&coreclk 0>;
|
||||
};
|
||||
|
||||
system-controller@18200 {
|
||||
--
|
||||
2.7.4
|
||||
|
||||
@ -0,0 +1,365 @@
|
||||
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
|
||||
index 7cfb3f4..8143b07 100644
|
||||
--- a/drivers/net/phy/marvell.c
|
||||
+++ b/drivers/net/phy/marvell.c
|
||||
@@ -39,6 +39,8 @@
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#define MII_MARVELL_PHY_PAGE 22
|
||||
+#define MII_MARVELL_COPPER_PAGE 0x00
|
||||
+#define MII_MARVELL_FIBER_PAGE 0x01
|
||||
|
||||
#define MII_M1011_IEVENT 0x13
|
||||
#define MII_M1011_IEVENT_CLEAR 0x0000
|
||||
@@ -136,6 +138,24 @@
|
||||
#define MII_88E1510_PHY_INTERNAL_REG_1 16
|
||||
#define MII_88E1510_PHY_INTERNAL_REG_2 17
|
||||
#define MII_88E1510_PHY_GENERAL_CTRL_1 20
|
||||
+#define MII_88E1510_PHY_GENERAL_CTRL_1_MODE_MASK 0x7
|
||||
+#define MII_88E1510_PHY_GENERAL_CTRL_1_MODE_SGMII 0x1 /* SGMII to copper */
|
||||
+#define MII_88E1510_PHY_GENERAL_CTRL_1_RESET 0x8000 /* Soft reset */
|
||||
+
|
||||
+#define LPA_FIBER_1000HALF 0x40
|
||||
+#define LPA_FIBER_1000FULL 0x20
|
||||
+
|
||||
+#define LPA_PAUSE_FIBER 0x180
|
||||
+#define LPA_PAUSE_ASYM_FIBER 0x100
|
||||
+
|
||||
+#define ADVERTISE_FIBER_1000HALF 0x40
|
||||
+#define ADVERTISE_FIBER_1000FULL 0x20
|
||||
+
|
||||
+#define ADVERTISE_PAUSE_FIBER 0x180
|
||||
+#define ADVERTISE_PAUSE_ASYM_FIBER 0x100
|
||||
+
|
||||
+#define REGISTER_LINK_STATUS 0x400
|
||||
+#define NB_FIBER_STATS 1
|
||||
|
||||
MODULE_DESCRIPTION("Marvell PHY driver");
|
||||
MODULE_AUTHOR("Andy Fleming");
|
||||
@@ -149,8 +169,9 @@ struct marvell_hw_stat {
|
||||
};
|
||||
|
||||
static struct marvell_hw_stat marvell_hw_stats[] = {
|
||||
- { "phy_receive_errors", 0, 21, 16},
|
||||
+ { "phy_receive_errors_copper", 0, 21, 16},
|
||||
{ "phy_idle_errors", 0, 10, 8 },
|
||||
+ { "phy_receive_errors_fiber", 1, 21, 16},
|
||||
};
|
||||
|
||||
struct marvell_priv {
|
||||
@@ -378,7 +399,6 @@ static int m88e1121_config_aneg(struct phy_device *phydev)
|
||||
return err;
|
||||
|
||||
if (phy_interface_is_rgmii(phydev)) {
|
||||
-
|
||||
mscr = phy_read(phydev, MII_88E1121_PHY_MSCR_REG) &
|
||||
MII_88E1121_PHY_MSCR_DELAY_MASK;
|
||||
|
||||
@@ -406,15 +426,7 @@ static int m88e1121_config_aneg(struct phy_device *phydev)
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
- oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE);
|
||||
-
|
||||
- phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_88E1121_PHY_LED_PAGE);
|
||||
- phy_write(phydev, MII_88E1121_PHY_LED_CTRL, MII_88E1121_PHY_LED_DEF);
|
||||
- phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage);
|
||||
-
|
||||
- err = genphy_config_aneg(phydev);
|
||||
-
|
||||
- return err;
|
||||
+ return genphy_config_aneg(phydev);
|
||||
}
|
||||
|
||||
static int m88e1318_config_aneg(struct phy_device *phydev)
|
||||
@@ -422,6 +434,8 @@ static int m88e1318_config_aneg(struct phy_device *phydev)
|
||||
int err, oldpage, mscr;
|
||||
|
||||
oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE);
|
||||
+ if (oldpage < 0)
|
||||
+ return oldpage;
|
||||
|
||||
err = phy_write(phydev, MII_MARVELL_PHY_PAGE,
|
||||
MII_88E1121_PHY_MSCR_PAGE);
|
||||
@@ -442,15 +456,122 @@ static int m88e1318_config_aneg(struct phy_device *phydev)
|
||||
return m88e1121_config_aneg(phydev);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ethtool_adv_to_fiber_adv_t
|
||||
+ * @ethadv: the ethtool advertisement settings
|
||||
+ *
|
||||
+ * A small helper function that translates ethtool advertisement
|
||||
+ * settings to phy autonegotiation advertisements for the
|
||||
+ * MII_ADV register for fiber link.
|
||||
+ */
|
||||
+static inline u32 ethtool_adv_to_fiber_adv_t(u32 ethadv)
|
||||
+{
|
||||
+ u32 result = 0;
|
||||
+
|
||||
+ if (ethadv & ADVERTISED_1000baseT_Half)
|
||||
+ result |= ADVERTISE_FIBER_1000HALF;
|
||||
+ if (ethadv & ADVERTISED_1000baseT_Full)
|
||||
+ result |= ADVERTISE_FIBER_1000FULL;
|
||||
+
|
||||
+ if ((ethadv & ADVERTISE_PAUSE_ASYM) && (ethadv & ADVERTISE_PAUSE_CAP))
|
||||
+ result |= LPA_PAUSE_ASYM_FIBER;
|
||||
+ else if (ethadv & ADVERTISE_PAUSE_CAP)
|
||||
+ result |= (ADVERTISE_PAUSE_FIBER
|
||||
+ & (~ADVERTISE_PAUSE_ASYM_FIBER));
|
||||
+
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * marvell_config_aneg_fiber - restart auto-negotiation or write BMCR
|
||||
+ * @phydev: target phy_device struct
|
||||
+ *
|
||||
+ * Description: If auto-negotiation is enabled, we configure the
|
||||
+ * advertising, and then restart auto-negotiation. If it is not
|
||||
+ * enabled, then we write the BMCR. Adapted for fiber link in
|
||||
+ * some Marvell's devices.
|
||||
+ */
|
||||
+static int marvell_config_aneg_fiber(struct phy_device *phydev)
|
||||
+{
|
||||
+ int changed = 0;
|
||||
+ int err;
|
||||
+ int adv, oldadv;
|
||||
+ u32 advertise;
|
||||
+
|
||||
+ if (phydev->autoneg != AUTONEG_ENABLE)
|
||||
+ return genphy_setup_forced(phydev);
|
||||
+
|
||||
+ /* Only allow advertising what this PHY supports */
|
||||
+ phydev->advertising &= phydev->supported;
|
||||
+ advertise = phydev->advertising;
|
||||
+
|
||||
+ /* Setup fiber advertisement */
|
||||
+ adv = phy_read(phydev, MII_ADVERTISE);
|
||||
+ if (adv < 0)
|
||||
+ return adv;
|
||||
+
|
||||
+ oldadv = adv;
|
||||
+ adv &= ~(ADVERTISE_FIBER_1000HALF | ADVERTISE_FIBER_1000FULL
|
||||
+ | LPA_PAUSE_FIBER);
|
||||
+ adv |= ethtool_adv_to_fiber_adv_t(advertise);
|
||||
+
|
||||
+ if (adv != oldadv) {
|
||||
+ err = phy_write(phydev, MII_ADVERTISE, adv);
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
+
|
||||
+ changed = 1;
|
||||
+ }
|
||||
+
|
||||
+ if (changed == 0) {
|
||||
+ /* Advertisement hasn't changed, but maybe aneg was never on to
|
||||
+ * begin with? Or maybe phy was isolated?
|
||||
+ */
|
||||
+ int ctl = phy_read(phydev, MII_BMCR);
|
||||
+
|
||||
+ if (ctl < 0)
|
||||
+ return ctl;
|
||||
+
|
||||
+ if (!(ctl & BMCR_ANENABLE) || (ctl & BMCR_ISOLATE))
|
||||
+ changed = 1; /* do restart aneg */
|
||||
+ }
|
||||
+
|
||||
+ /* Only restart aneg if we are advertising something different
|
||||
+ * than we were before.
|
||||
+ */
|
||||
+ if (changed > 0)
|
||||
+ changed = genphy_restart_aneg(phydev);
|
||||
+
|
||||
+ return changed;
|
||||
+}
|
||||
+
|
||||
static int m88e1510_config_aneg(struct phy_device *phydev)
|
||||
{
|
||||
int err;
|
||||
|
||||
+ err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_MARVELL_COPPER_PAGE);
|
||||
+ if (err < 0)
|
||||
+ goto error;
|
||||
+
|
||||
+ /* Configure the copper link first */
|
||||
err = m88e1318_config_aneg(phydev);
|
||||
if (err < 0)
|
||||
- return err;
|
||||
+ goto error;
|
||||
|
||||
- return 0;
|
||||
+ /* Then the fiber link */
|
||||
+ err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_MARVELL_FIBER_PAGE);
|
||||
+ if (err < 0)
|
||||
+ goto error;
|
||||
+
|
||||
+ err = marvell_config_aneg_fiber(phydev);
|
||||
+ if (err < 0)
|
||||
+ goto error;
|
||||
+
|
||||
+ return phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_MARVELL_COPPER_PAGE);
|
||||
+
|
||||
+error:
|
||||
+ err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_MARVELL_COPPER_PAGE);
|
||||
+ return err;
|
||||
}
|
||||
|
||||
static int marvell_config_init(struct phy_device *phydev)
|
||||
@@ -635,109 +756,65 @@ static int m88e1111_config_init(struct phy_device *phydev)
|
||||
return phy_write(phydev, MII_BMCR, BMCR_RESET);
|
||||
}
|
||||
|
||||
-static int m88e1510_phy_writebits(struct phy_device *phydev,
|
||||
- u8 reg_num, u16 offset, u16 len, u16 data)
|
||||
+static int m88e1121_config_init(struct phy_device *phydev)
|
||||
{
|
||||
- int err;
|
||||
- int reg;
|
||||
- u16 mask;
|
||||
+ int err, oldpage;
|
||||
|
||||
- if ((len + offset) >= 16)
|
||||
- mask = 0 - (1 << offset);
|
||||
- else
|
||||
- mask = (1 << (len + offset)) - (1 << offset);
|
||||
+ oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE);
|
||||
+ if (oldpage < 0)
|
||||
+ return oldpage;
|
||||
|
||||
- reg = phy_read(phydev, reg_num);
|
||||
- if (reg < 0)
|
||||
- return reg;
|
||||
+ phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_88E1121_PHY_LED_PAGE);
|
||||
|
||||
- reg &= ~mask;
|
||||
- reg |= data << offset;
|
||||
+ /* Default PHY LED config: LED[0] .. Link, LED[1] .. Activity */
|
||||
+ err = phy_write(phydev, MII_88E1121_PHY_LED_CTRL,
|
||||
+ MII_88E1121_PHY_LED_DEF);
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
|
||||
- err = phy_write(phydev, reg_num, (u16)reg);
|
||||
+ err = phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage);
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
|
||||
- return err;
|
||||
+ /* Set marvell,reg-init configuration from device tree */
|
||||
+ return marvell_config_init(phydev);
|
||||
}
|
||||
|
||||
-/* For Marvell 88E1510/88E1518/88E1512/88E1514, need to fix the Errata in
|
||||
- * SGMII mode, which is described in Marvell Release Notes Errata Section 3.1.
|
||||
- * Besides of that, the 88E151X serial PHY should be initialized as legacy
|
||||
- * Marvell 88E1111 PHY.
|
||||
- */
|
||||
static int m88e1510_config_init(struct phy_device *phydev)
|
||||
{
|
||||
int err;
|
||||
+ int temp;
|
||||
|
||||
- /* As per Marvell Release Notes - Alaska 88E1510/88E1518/88E1512
|
||||
- * /88E1514 Rev A0, Errata Section 3.1
|
||||
- */
|
||||
+ /* SGMII-to-Copper mode initialization */
|
||||
if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
|
||||
- err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x00ff);
|
||||
- if (err < 0)
|
||||
- return err;
|
||||
-
|
||||
- err = phy_write(phydev, MII_88E1510_PHY_INTERNAL_REG_2, 0x214B);
|
||||
- if (err < 0)
|
||||
- return err;
|
||||
-
|
||||
- err = phy_write(phydev, MII_88E1510_PHY_INTERNAL_REG_1, 0x2144);
|
||||
- if (err < 0)
|
||||
- return err;
|
||||
-
|
||||
- err = phy_write(phydev, MII_88E1510_PHY_INTERNAL_REG_2, 0x0C28);
|
||||
- if (err < 0)
|
||||
- return err;
|
||||
-
|
||||
- err = phy_write(phydev, MII_88E1510_PHY_INTERNAL_REG_1, 0x2146);
|
||||
- if (err < 0)
|
||||
- return err;
|
||||
-
|
||||
- err = phy_write(phydev, MII_88E1510_PHY_INTERNAL_REG_2, 0xB233);
|
||||
- if (err < 0)
|
||||
- return err;
|
||||
-
|
||||
- err = phy_write(phydev, MII_88E1510_PHY_INTERNAL_REG_1, 0x214D);
|
||||
- if (err < 0)
|
||||
- return err;
|
||||
-
|
||||
- err = phy_write(phydev, MII_88E1510_PHY_INTERNAL_REG_2, 0xCC0C);
|
||||
- if (err < 0)
|
||||
- return err;
|
||||
-
|
||||
- err = phy_write(phydev, MII_88E1510_PHY_INTERNAL_REG_1, 0x2159);
|
||||
- if (err < 0)
|
||||
- return err;
|
||||
-
|
||||
- err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0);
|
||||
- if (err < 0)
|
||||
- return err;
|
||||
-
|
||||
+ /* Select page 18 */
|
||||
err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 18);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
- /* Write HWCFG_MODE = SGMII to Copper */
|
||||
- err = m88e1510_phy_writebits(phydev,
|
||||
- MII_88E1510_PHY_GENERAL_CTRL_1,
|
||||
- 0, 3, 1);
|
||||
+ /* In reg 20, write MODE[2:0] = 0x1 (SGMII to Copper) */
|
||||
+ temp = phy_read(phydev, MII_88E1510_PHY_GENERAL_CTRL_1);
|
||||
+ temp &= ~MII_88E1510_PHY_GENERAL_CTRL_1_MODE_MASK;
|
||||
+ temp |= MII_88E1510_PHY_GENERAL_CTRL_1_MODE_SGMII;
|
||||
+ err = phy_write(phydev, MII_88E1510_PHY_GENERAL_CTRL_1, temp);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
- /* Phy reset */
|
||||
- err = m88e1510_phy_writebits(phydev,
|
||||
- MII_88E1510_PHY_GENERAL_CTRL_1,
|
||||
- 15, 1, 1);
|
||||
+ /* PHY reset is necessary after changing MODE[2:0] */
|
||||
+ temp |= MII_88E1510_PHY_GENERAL_CTRL_1_RESET;
|
||||
+ err = phy_write(phydev, MII_88E1510_PHY_GENERAL_CTRL_1, temp);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
- err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0);
|
||||
+ /* Reset page selection */
|
||||
+ err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_MARVELL_COPPER_PAGE);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
usleep_range(100, 200);
|
||||
}
|
||||
|
||||
- return m88e1111_config_init(phydev);
|
||||
+ return m88e1121_config_init(phydev);
|
||||
}
|
||||
|
||||
static int m88e1118_config_aneg(struct phy_device *phydev)
|
||||
@@ -1372,7 +1449,7 @@ static struct phy_driver marvell_drivers[] = {
|
||||
.phy_id = MARVELL_PHY_ID_88E1510,
|
||||
.phy_id_mask = MARVELL_PHY_ID_MASK,
|
||||
.name = "Marvell 88E1510",
|
||||
- .features = PHY_GBIT_FEATURES | SUPPORTED_Pause,
|
||||
+ .features = PHY_GBIT_FEATURES | SUPPORTED_FIBRE | SUPPORTED_Pause,
|
||||
.flags = PHY_HAS_INTERRUPT,
|
||||
.config_init = &m88e1510_config_init,
|
||||
.config_aneg = &m88e1510_config_aneg,
|
||||
@@ -1391,7 +1468,6 @@ static struct phy_driver marvell_drivers[] = {
|
||||
.flags = PHY_HAS_INTERRUPT,
|
||||
.probe = marvell_probe,
|
||||
.config_init = &marvell_config_init,
|
||||
- .config_init = &marvell_config_init,
|
||||
.config_aneg = &m88e1510_config_aneg,
|
||||
.read_status = &marvell_read_status,
|
||||
.ack_interrupt = &marvell_ack_interrupt,
|
||||
@ -0,0 +1,25 @@
|
||||
From 9ee6345ef82f7af5f98e17a40e667f8ad6b2fa1b Mon Sep 17 00:00:00 2001
|
||||
From: aprayoga <adit.prayoga@gmail.com>
|
||||
Date: Sun, 3 Sep 2017 18:10:12 +0800
|
||||
Subject: Enable ATA port LED trigger
|
||||
|
||||
---
|
||||
arch/arm/configs/mvebu_v7_defconfig | 1 +
|
||||
arch/arm/mach-mvebu/Kconfig | 1 +
|
||||
2 files changed, 2 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
|
||||
index 053ea9d..aa1f389 100644
|
||||
--- a/arch/arm/mach-mvebu/Kconfig
|
||||
+++ b/arch/arm/mach-mvebu/Kconfig
|
||||
@@ -52,6 +52,7 @@ config MACH_ARMADA_375
|
||||
|
||||
config MACH_ARMADA_38X
|
||||
bool "Marvell Armada 380/385 boards" if ARCH_MULTI_V7
|
||||
+ select ARCH_WANT_LIBATA_LEDS
|
||||
select ARM_ERRATA_720789
|
||||
select ARM_ERRATA_753970
|
||||
select ARM_GIC
|
||||
--
|
||||
2.7.4
|
||||
|
||||
@ -8,21 +8,20 @@ Subject: Initial device tree
|
||||
- All 7 LED declared as led-gpio
|
||||
- LED1 (system) default to hearbeat
|
||||
- LED7 (USB) triggered by USB Host activity
|
||||
- GPIO23 (MPP23) declared as GPIO button
|
||||
- SPI NOR flash declared as MTD
|
||||
- Enable IO expander interrupt
|
||||
- Allocate GPIOs for fans
|
||||
---
|
||||
arch/arm/boot/dts/armada-388-helios4.dts | 318 ++++++++++++++++++++++++++++++
|
||||
1 file changed, 318 insertions(+)
|
||||
arch/arm/boot/dts/armada-388-helios4.dts | 333 +++++++++++++++++++++
|
||||
1 file changed, 329 insertions(+)
|
||||
create mode 100644 arch/arm/boot/dts/armada-388-helios4.dts
|
||||
|
||||
diff --git a/arch/arm/boot/dts/armada-388-helios4.dts b/arch/arm/boot/dts/armada-388-helios4.dts
|
||||
new file mode 100644
|
||||
index 0000000..b7a2122
|
||||
index 0000000..19a0256
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/boot/dts/armada-388-helios4.dts
|
||||
@@ -0,0 +1,346 @@
|
||||
@@ -0,0 +1,318 @@
|
||||
+/*
|
||||
+ * Device Tree file for Helios4
|
||||
+ * based on SolidRun Clearfog revision A1 rev 2.0 (88F6828)
|
||||
@ -42,7 +41,7 @@ index 0000000..b7a2122
|
||||
+
|
||||
+ memory {
|
||||
+ device_type = "memory";
|
||||
+ reg = <0x00000000 0x40000000>; /* 1 GB */
|
||||
+ reg = <0x00000000 0x80000000>; /* 2 GB */
|
||||
+ };
|
||||
+
|
||||
+ aliases {
|
||||
@ -92,19 +91,6 @@ index 0000000..b7a2122
|
||||
+ vin-supply = <®_12v>;
|
||||
+ };
|
||||
+
|
||||
+ gpio-keys {
|
||||
+ compatible = "gpio-keys";
|
||||
+ pinctrl-0 = <&user_button_pins>;
|
||||
+ pinctrl-names = "default";
|
||||
+
|
||||
+ button_0 {
|
||||
+ label = "User Button";
|
||||
+ gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
|
||||
+ linux,can-disable;
|
||||
+ linux,code = <BTN_0>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ system-leds {
|
||||
+ compatible = "gpio-leds";
|
||||
+ status-led {
|
||||
@ -116,7 +102,7 @@ index 0000000..b7a2122
|
||||
+
|
||||
+ fault-led {
|
||||
+ label = "helios4:red:fault";
|
||||
+ gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
|
||||
+ gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
|
||||
+ default-state = "keep";
|
||||
+ };
|
||||
+ };
|
||||
@ -156,13 +142,17 @@ index 0000000..b7a2122
|
||||
+ };
|
||||
+
|
||||
+ fan1: j10-pwm {
|
||||
+ compatible = "pwm-fan";
|
||||
+ pwms = <&gpio1 9 3000>;
|
||||
+ compatible = "gpio-fan";
|
||||
+ gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
|
||||
+ gpio-fan,speed-map = < 0 0
|
||||
+ 3800 1>;
|
||||
+ };
|
||||
+
|
||||
+ fan2: j17-pwm {
|
||||
+ compatible = "pwm-fan";
|
||||
+ pwms = <&gpio1 4 4500>;
|
||||
+ compatible = "gpio-fan";
|
||||
+ gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
|
||||
+ gpio-fan,speed-map = < 0 0
|
||||
+ 3800 1>;
|
||||
+ };
|
||||
+
|
||||
+ usb2_phy: usb2-phy {
|
||||
@ -178,7 +168,7 @@ index 0000000..b7a2122
|
||||
+ soc {
|
||||
+ internal-regs {
|
||||
+ i2c@11000 {
|
||||
+ clock-frequency = <100000>;
|
||||
+ clock-frequency = <400000>;
|
||||
+ pinctrl-0 = <&i2c0_pins>;
|
||||
+ pinctrl-names = "default";
|
||||
+ status = "okay";
|
||||
@ -205,7 +195,7 @@ index 0000000..b7a2122
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&pca0_pins>;
|
||||
+ interrupt-parent = <&gpio0>;
|
||||
+ interrupts = <18 IRQ_TYPE_EDGE_FALLING>;
|
||||
+ interrupts = <23 IRQ_TYPE_EDGE_FALLING>;
|
||||
+ interrupt-controller;
|
||||
+ #interrupt-cells = <2>;
|
||||
+
|
||||
@ -234,8 +224,6 @@ index 0000000..b7a2122
|
||||
+ reg = <0x4c>;
|
||||
+ vcc-supply = <®_3p3v>;
|
||||
+ };
|
||||
+
|
||||
+ /* What device at 0x64 ? */
|
||||
+ };
|
||||
+
|
||||
+ i2c@11100 {
|
||||
@ -281,16 +269,6 @@ index 0000000..b7a2122
|
||||
+ µsom_spi1_cs_pins>;
|
||||
+ pinctrl-names = "default";
|
||||
+ status = "okay";
|
||||
+
|
||||
+ spi-flash@0 {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+ compatible = "w25q32", "jedec,spi-nor";
|
||||
+ reg = <0>; /* Chip select 0 */
|
||||
+ spi-max-frequency = <104000000>;
|
||||
+ spi-cpha;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ sdhci@d8000 {
|
||||
@ -303,13 +281,6 @@ index 0000000..b7a2122
|
||||
+ status = "okay";
|
||||
+ vmmc = <®_3p3v>;
|
||||
+ wp-inverted;
|
||||
+ max-frequency = <50000000>;
|
||||
+ cap-sd-highspeed;
|
||||
+ sd-uhs-sdr12;
|
||||
+ sd-uhs-sdr25;
|
||||
+ sd-uhs-sdr50;
|
||||
+ keep-power-in-suspend;
|
||||
+ wakeup-source;
|
||||
+ };
|
||||
+
|
||||
+ usb@58000 {
|
||||
@ -327,7 +298,11 @@ index 0000000..b7a2122
|
||||
+ };
|
||||
+
|
||||
+ pinctrl@18000 {
|
||||
+ pca0_pins: pca0_pins {
|
||||
+ pca0_pins: pca0-pins {
|
||||
+ marvell,pins = "mpp23";
|
||||
+ marvell,function = "gpio";
|
||||
+ };
|
||||
+ microsom_phy0_int_pins: microsom-phy0-int-pins {
|
||||
+ marvell,pins = "mpp18";
|
||||
+ marvell,function = "gpio";
|
||||
+ };
|
||||
@ -354,17 +329,13 @@ index 0000000..b7a2122
|
||||
+ };
|
||||
+ helios_fan_pins: helios-fan-pins {
|
||||
+ marvell,pins = "mpp41", "mpp43",
|
||||
+ "mpp36", "mpp25";
|
||||
+ "mpp48", "mpp55";
|
||||
+ marvell,function = "gpio";
|
||||
+ };
|
||||
+ microsom_spi1_cs_pins: spi1-cs-pins {
|
||||
+ marvell,pins = "mpp59";
|
||||
+ marvell,function = "spi1";
|
||||
+ };
|
||||
+ user_button_pins: user-button-pins {
|
||||
+ marvell,pins = "mpp23";
|
||||
+ marvell,function = "gpio";
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
@ -382,6 +353,6 @@ diff -u a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
|
||||
armada-388-gp.dtb \
|
||||
armada-388-rd.dtb
|
||||
|
||||
--
|
||||
--
|
||||
2.7.4
|
||||
|
||||
|
||||
179
patch/kernel/mvebu-next/91-01-libata-add-ledtrig-support.patch
Normal file
179
patch/kernel/mvebu-next/91-01-libata-add-ledtrig-support.patch
Normal file
@ -0,0 +1,179 @@
|
||||
From 5843af891d0dabf9bb80039cfe807d01e9495154 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel at makrotopia.org>
|
||||
Date: Fri, 12 Dec 2014 13:38:33 +0100
|
||||
Subject: libata: add ledtrig support
|
||||
|
||||
This adds a LED trigger for each ATA port indicating disk activity.
|
||||
|
||||
As this is needed only on specific platforms (NAS SoCs and such),
|
||||
these platforms should define ARCH_WANTS_LIBATA_LEDS if there
|
||||
are boards with LED(s) intended to indicate ATA disk activity and
|
||||
need the OS to take care of that.
|
||||
In that way, if not selected, LED trigger support not will be
|
||||
included in libata-core and both, codepaths and structures remain
|
||||
untouched.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel at makrotopia.org>
|
||||
---
|
||||
drivers/ata/Kconfig | 16 ++++++++++++++
|
||||
drivers/ata/libata-core.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
include/linux/libata.h | 7 ++++++
|
||||
3 files changed, 79 insertions(+)
|
||||
|
||||
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
|
||||
index 6aaa3f8..4e24b64 100644
|
||||
--- a/drivers/ata/Kconfig
|
||||
+++ b/drivers/ata/Kconfig
|
||||
@@ -46,6 +46,22 @@ config ATA_VERBOSE_ERROR
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
+config ARCH_WANT_LIBATA_LEDS
|
||||
+ bool
|
||||
+
|
||||
+config ATA_LEDS
|
||||
+ bool "support ATA port LED triggers"
|
||||
+ depends on ARCH_WANT_LIBATA_LEDS
|
||||
+ select NEW_LEDS
|
||||
+ select LEDS_CLASS
|
||||
+ select LEDS_TRIGGERS
|
||||
+ default y
|
||||
+ help
|
||||
+ This option adds a LED trigger for each registered ATA port.
|
||||
+ It is used to drive disk activity leds connected via GPIO.
|
||||
+
|
||||
+ If unsure, say N.
|
||||
+
|
||||
config ATA_ACPI
|
||||
bool "ATA ACPI Support"
|
||||
depends on ACPI
|
||||
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
|
||||
index b0b77b6..1400f4d 100644
|
||||
--- a/drivers/ata/libata-core.c
|
||||
+++ b/drivers/ata/libata-core.c
|
||||
@@ -728,6 +728,7 @@ u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev)
|
||||
return block;
|
||||
}
|
||||
|
||||
+
|
||||
/**
|
||||
* ata_build_rw_tf - Build ATA taskfile for given read/write request
|
||||
* @tf: Target ATA taskfile
|
||||
@@ -4757,6 +4758,30 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
|
||||
}
|
||||
|
||||
/**
|
||||
+ * ata_led_act - Trigger port activity LED
|
||||
+ * @ap: indicating port
|
||||
+ *
|
||||
+ * Blinks any LEDs registered to the trigger.
|
||||
+ * Commonly used with leds-gpio on NAS systems with disk activity
|
||||
+ * indicator LEDs.
|
||||
+ *
|
||||
+ * LOCKING:
|
||||
+ * None.
|
||||
+ */
|
||||
+static inline void ata_led_act(struct ata_port *ap)
|
||||
+{
|
||||
+#if CONFIG_ATA_LEDS
|
||||
+#define LIBATA_BLINK_DELAY 20 /* ms */
|
||||
+ unsigned long led_delay = LIBATA_BLINK_DELAY;
|
||||
+
|
||||
+ if (unlikely(!ap->ledtrig))
|
||||
+ return;
|
||||
+
|
||||
+ led_trigger_blink_oneshot(ap->ledtrig, &led_delay, &led_delay, 0);
|
||||
+#endif /* CONFIG_ATA_LEDS */
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
* ata_qc_new_init - Request an available ATA command, and initialize it
|
||||
* @dev: Device from whom we request an available command structure
|
||||
* @tag: tag
|
||||
@@ -4780,6 +4805,9 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int tag)
|
||||
if (tag < 0)
|
||||
return NULL;
|
||||
}
|
||||
+#if CONFIG_ATA_LEDS
|
||||
+ ata_led_act(ap);
|
||||
+#endif
|
||||
|
||||
qc = __ata_qc_from_tag(ap, tag);
|
||||
qc->tag = tag;
|
||||
@@ -5677,6 +5705,9 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
|
||||
ap->stats.unhandled_irq = 1;
|
||||
ap->stats.idle_irq = 1;
|
||||
#endif
|
||||
+#if CONFIG_ATA_LEDS
|
||||
+ ap->ledtrig = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
|
||||
+#endif
|
||||
ata_sff_port_init(ap);
|
||||
|
||||
return ap;
|
||||
@@ -5698,6 +5729,12 @@ static void ata_host_release(struct device *gendev, void *res)
|
||||
|
||||
kfree(ap->pmp_link);
|
||||
kfree(ap->slave_link);
|
||||
+#if CONFIG_ATA_LEDS
|
||||
+ if (ap->ledtrig) {
|
||||
+ led_trigger_unregister(ap->ledtrig);
|
||||
+ kfree(ap->ledtrig);
|
||||
+ };
|
||||
+#endif
|
||||
kfree(ap);
|
||||
host->ports[i] = NULL;
|
||||
}
|
||||
@@ -6145,6 +6182,25 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
|
||||
host->ports[i]->local_port_no = i + 1;
|
||||
}
|
||||
|
||||
+#if CONFIG_ATA_LEDS
|
||||
+ /* register LED triggers for all ports */
|
||||
+ for (i = 0; i < host->n_ports; i++) {
|
||||
+ if (unlikely(!host->ports[i]->ledtrig))
|
||||
+ continue;
|
||||
+
|
||||
+ snprintf(host->ports[i]->ledtrig_name,
|
||||
+ sizeof(host->ports[i]->ledtrig_name), "ata%u",
|
||||
+ host->ports[i]->print_id);
|
||||
+
|
||||
+ host->ports[i]->ledtrig->name = host->ports[i]->ledtrig_name;
|
||||
+
|
||||
+ if (led_trigger_register(host->ports[i]->ledtrig)) {
|
||||
+ kfree(host->ports[i]->ledtrig);
|
||||
+ host->ports[i]->ledtrig = NULL;
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
/* Create associated sysfs transport objects */
|
||||
for (i = 0; i < host->n_ports; i++) {
|
||||
rc = ata_tport_add(host->dev,host->ports[i]);
|
||||
diff --git a/include/linux/libata.h b/include/linux/libata.h
|
||||
index b20a275..50eeee3 100644
|
||||
--- a/include/linux/libata.h
|
||||
+++ b/include/linux/libata.h
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/cdrom.h>
|
||||
#include <linux/sched.h>
|
||||
+#include <linux/leds.h>
|
||||
|
||||
/*
|
||||
* Define if arch has non-standard setup. This is a _PCI_ standard
|
||||
@@ -877,6 +878,12 @@ struct ata_port {
|
||||
#ifdef CONFIG_ATA_ACPI
|
||||
struct ata_acpi_gtm __acpi_init_gtm; /* use ata_acpi_init_gtm() */
|
||||
#endif
|
||||
+
|
||||
+#ifdef CONFIG_ATA_LEDS
|
||||
+ struct led_trigger *ledtrig;
|
||||
+ char ledtrig_name[8];
|
||||
+#endif
|
||||
+
|
||||
/* owned by EH */
|
||||
u8 sector_buf[ATA_SECT_SIZE] ____cacheline_aligned;
|
||||
};
|
||||
--
|
||||
2.7.4
|
||||
|
||||
@ -24,10 +24,10 @@ diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
|
||||
index 053ea9d..aa1f389 100644
|
||||
--- a/arch/arm/mach-mvebu/Kconfig
|
||||
+++ b/arch/arm/mach-mvebu/Kconfig
|
||||
@@ -52,6 +52,7 @@ config MACH_ARMADA_375
|
||||
|
||||
@@ -57,6 +57,7 @@ config MACH_ARMADA_375
|
||||
config MACH_ARMADA_38X
|
||||
bool "Marvell Armada 380/385 boards" if ARCH_MULTI_V7
|
||||
bool "Marvell Armada 380/385 boards"
|
||||
depends on ARCH_MULTI_V7
|
||||
+ select ARCH_WANT_LIBATA_LEDS
|
||||
select ARM_ERRATA_720789
|
||||
select ARM_ERRATA_753970
|
||||
@ -0,0 +1,352 @@
|
||||
diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
|
||||
index 45c65f8..2ec4a15 100644
|
||||
--- a/drivers/gpio/gpio-mvebu.c
|
||||
+++ b/drivers/gpio/gpio-mvebu.c
|
||||
@@ -93,20 +93,41 @@
|
||||
|
||||
#define MVEBU_MAX_GPIO_PER_BANK 32
|
||||
|
||||
-struct mvebu_pwm {
|
||||
+enum mvebu_pwm_ctrl {
|
||||
+ MVEBU_PWM_CTRL_SET_A = 0,
|
||||
+ MVEBU_PWM_CTRL_SET_B,
|
||||
+ MVEBU_PWM_CTRL_MAX
|
||||
+};
|
||||
+
|
||||
+struct mvebu_pwmchip {
|
||||
void __iomem *membase;
|
||||
unsigned long clk_rate;
|
||||
+ spinlock_t lock;
|
||||
+ bool in_use;
|
||||
+
|
||||
+ /* Used to preserve GPIO/PWM registers across suspend/resume */
|
||||
+ u32 blink_on_duration;
|
||||
+ u32 blink_off_duration;
|
||||
+};
|
||||
+
|
||||
+struct mvebu_pwm_chip_drv {
|
||||
+ enum mvebu_pwm_ctrl ctrl;
|
||||
struct gpio_desc *gpiod;
|
||||
+ bool master;
|
||||
+};
|
||||
+
|
||||
+struct mvebu_pwm {
|
||||
struct pwm_chip chip;
|
||||
- spinlock_t lock;
|
||||
struct mvebu_gpio_chip *mvchip;
|
||||
+ struct mvebu_pwmchip controller;
|
||||
+ enum mvebu_pwm_ctrl default_counter;
|
||||
|
||||
/* Used to preserve GPIO/PWM registers across suspend/resume */
|
||||
u32 blink_select;
|
||||
- u32 blink_on_duration;
|
||||
- u32 blink_off_duration;
|
||||
};
|
||||
|
||||
+static struct mvebu_pwmchip *mvebu_pwm_list[MVEBU_PWM_CTRL_MAX];
|
||||
+
|
||||
struct mvebu_gpio_chip {
|
||||
struct gpio_chip chip;
|
||||
struct regmap *regs;
|
||||
@@ -283,12 +304,12 @@ mvebu_gpio_write_level_mask(struct mvebu_gpio_chip *mvchip, u32 val)
|
||||
* Functions returning addresses of individual registers for a given
|
||||
* PWM controller.
|
||||
*/
|
||||
-static void __iomem *mvebu_pwmreg_blink_on_duration(struct mvebu_pwm *mvpwm)
|
||||
+static void __iomem *mvebu_pwmreg_blink_on_duration(struct mvebu_pwmchip *mvpwm)
|
||||
{
|
||||
return mvpwm->membase + PWM_BLINK_ON_DURATION_OFF;
|
||||
}
|
||||
|
||||
-static void __iomem *mvebu_pwmreg_blink_off_duration(struct mvebu_pwm *mvpwm)
|
||||
+static void __iomem *mvebu_pwmreg_blink_off_duration(struct mvebu_pwmchip *mvpwm)
|
||||
{
|
||||
return mvpwm->membase + PWM_BLINK_OFF_DURATION_OFF;
|
||||
}
|
||||
@@ -600,46 +621,80 @@ static int mvebu_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
struct mvebu_pwm *mvpwm = to_mvebu_pwm(chip);
|
||||
struct mvebu_gpio_chip *mvchip = mvpwm->mvchip;
|
||||
struct gpio_desc *desc;
|
||||
+ enum mvebu_pwm_ctrl id;
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
+ struct mvebu_pwm_chip_drv *chip_data;
|
||||
|
||||
- spin_lock_irqsave(&mvpwm->lock, flags);
|
||||
+ spin_lock_irqsave(&mvpwm->controller.lock, flags);
|
||||
|
||||
- if (mvpwm->gpiod) {
|
||||
- ret = -EBUSY;
|
||||
- } else {
|
||||
- desc = gpio_to_desc(mvchip->chip.base + pwm->hwpwm);
|
||||
- if (!desc) {
|
||||
- ret = -ENODEV;
|
||||
- goto out;
|
||||
- }
|
||||
+ regmap_read(mvchip->regs, GPIO_BLINK_EN_OFF + mvchip->offset,
|
||||
+ &mvchip->blink_en_reg);
|
||||
+ if (pwm->chip_data || (mvchip->blink_en_reg & BIT(pwm->hwpwm)))
|
||||
+ return -EBUSY;
|
||||
|
||||
- ret = gpiod_request(desc, "mvebu-pwm");
|
||||
- if (ret)
|
||||
- goto out;
|
||||
+ desc = gpio_to_desc(mvchip->chip.base + pwm->hwpwm);
|
||||
+ if (!desc) {
|
||||
+ ret = -ENODEV;
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
- ret = gpiod_direction_output(desc, 0);
|
||||
- if (ret) {
|
||||
- gpiod_free(desc);
|
||||
- goto out;
|
||||
- }
|
||||
+ ret = gpiod_request(desc, "mvebu-pwm");
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
|
||||
- mvpwm->gpiod = desc;
|
||||
+ ret = gpiod_direction_output(desc, 0);
|
||||
+ if (ret) {
|
||||
+ gpiod_free(desc);
|
||||
+ goto out;
|
||||
}
|
||||
+
|
||||
+ chip_data = kzalloc(sizeof(struct mvebu_pwm_chip_drv), GFP_KERNEL);
|
||||
+ if (!chip_data) {
|
||||
+ gpiod_free(desc);
|
||||
+ ret = -ENOMEM;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ for (id = MVEBU_PWM_CTRL_SET_A;id < MVEBU_PWM_CTRL_MAX; id++) {
|
||||
+ if (!mvebu_pwm_list[id]->in_use) {
|
||||
+ chip_data->ctrl = id;
|
||||
+ chip_data->master = true;
|
||||
+ mvebu_pwm_list[id]->in_use = true;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!chip_data->master)
|
||||
+ chip_data->ctrl = mvpwm->default_counter;
|
||||
+
|
||||
+ regmap_update_bits(mvchip->regs, GPIO_BLINK_CNT_SELECT_OFF + mvchip->offset,
|
||||
+ BIT(pwm->hwpwm), chip_data->ctrl ? BIT(pwm->hwpwm) : 0);
|
||||
+
|
||||
+ chip_data->gpiod = desc;
|
||||
+ pwm->chip_data = chip_data;
|
||||
+
|
||||
+ regmap_read(mvchip->regs, GPIO_BLINK_CNT_SELECT_OFF + mvchip->offset,
|
||||
+ &mvpwm->blink_select);
|
||||
out:
|
||||
- spin_unlock_irqrestore(&mvpwm->lock, flags);
|
||||
+ spin_unlock_irqrestore(&mvpwm->controller.lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void mvebu_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
{
|
||||
struct mvebu_pwm *mvpwm = to_mvebu_pwm(chip);
|
||||
+ struct mvebu_pwm_chip_drv *chip_data = (struct mvebu_pwm_chip_drv*) pwm->chip_data;
|
||||
unsigned long flags;
|
||||
|
||||
- spin_lock_irqsave(&mvpwm->lock, flags);
|
||||
- gpiod_free(mvpwm->gpiod);
|
||||
- mvpwm->gpiod = NULL;
|
||||
- spin_unlock_irqrestore(&mvpwm->lock, flags);
|
||||
+ spin_lock_irqsave(&mvpwm->controller.lock, flags);
|
||||
+ if (chip_data->master)
|
||||
+ mvebu_pwm_list[chip_data->ctrl]->in_use = false;
|
||||
+
|
||||
+ gpiod_free(chip_data->gpiod);
|
||||
+ kfree(chip_data);
|
||||
+ pwm->chip_data = NULL;
|
||||
+ spin_unlock_irqrestore(&mvpwm->controller.lock, flags);
|
||||
}
|
||||
|
||||
static void mvebu_pwm_get_state(struct pwm_chip *chip,
|
||||
@@ -647,17 +702,24 @@ static void mvebu_pwm_get_state(struct pwm_chip *chip,
|
||||
struct pwm_state *state) {
|
||||
|
||||
struct mvebu_pwm *mvpwm = to_mvebu_pwm(chip);
|
||||
+ struct mvebu_pwm_chip_drv *chip_data = (struct mvebu_pwm_chip_drv*) pwm->chip_data;
|
||||
+ struct mvebu_pwmchip *controller;
|
||||
struct mvebu_gpio_chip *mvchip = mvpwm->mvchip;
|
||||
unsigned long long val;
|
||||
unsigned long flags;
|
||||
u32 u;
|
||||
|
||||
- spin_lock_irqsave(&mvpwm->lock, flags);
|
||||
+ if (chip_data)
|
||||
+ controller = mvebu_pwm_list[chip_data->ctrl];
|
||||
+ else
|
||||
+ controller = &mvpwm->controller;
|
||||
+
|
||||
+ spin_lock_irqsave(&controller->lock, flags);
|
||||
|
||||
val = (unsigned long long)
|
||||
- readl_relaxed(mvebu_pwmreg_blink_on_duration(mvpwm));
|
||||
+ readl_relaxed(mvebu_pwmreg_blink_on_duration(controller));
|
||||
val *= NSEC_PER_SEC;
|
||||
- do_div(val, mvpwm->clk_rate);
|
||||
+ do_div(val, controller->clk_rate);
|
||||
if (val > UINT_MAX)
|
||||
state->duty_cycle = UINT_MAX;
|
||||
else if (val)
|
||||
@@ -666,9 +728,9 @@ static void mvebu_pwm_get_state(struct pwm_chip *chip,
|
||||
state->duty_cycle = 1;
|
||||
|
||||
val = (unsigned long long)
|
||||
- readl_relaxed(mvebu_pwmreg_blink_off_duration(mvpwm));
|
||||
+ readl_relaxed(mvebu_pwmreg_blink_off_duration(controller));
|
||||
val *= NSEC_PER_SEC;
|
||||
- do_div(val, mvpwm->clk_rate);
|
||||
+ do_div(val, controller->clk_rate);
|
||||
if (val < state->duty_cycle) {
|
||||
state->period = 1;
|
||||
} else {
|
||||
@@ -687,19 +749,21 @@ static void mvebu_pwm_get_state(struct pwm_chip *chip,
|
||||
else
|
||||
state->enabled = false;
|
||||
|
||||
- spin_unlock_irqrestore(&mvpwm->lock, flags);
|
||||
+ spin_unlock_irqrestore(&controller->lock, flags);
|
||||
}
|
||||
|
||||
static int mvebu_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct mvebu_pwm *mvpwm = to_mvebu_pwm(chip);
|
||||
+ struct mvebu_pwm_chip_drv *chip_data = (struct mvebu_pwm_chip_drv*) pwm->chip_data;
|
||||
+ struct mvebu_pwmchip *controller = mvebu_pwm_list[chip_data->ctrl];
|
||||
struct mvebu_gpio_chip *mvchip = mvpwm->mvchip;
|
||||
unsigned long long val;
|
||||
unsigned long flags;
|
||||
unsigned int on, off;
|
||||
|
||||
- val = (unsigned long long) mvpwm->clk_rate * state->duty_cycle;
|
||||
+ val = (unsigned long long) controller->clk_rate * state->duty_cycle;
|
||||
do_div(val, NSEC_PER_SEC);
|
||||
if (val > UINT_MAX)
|
||||
return -EINVAL;
|
||||
@@ -708,7 +772,7 @@ static int mvebu_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
else
|
||||
on = 1;
|
||||
|
||||
- val = (unsigned long long) mvpwm->clk_rate *
|
||||
+ val = (unsigned long long) controller->clk_rate *
|
||||
(state->period - state->duty_cycle);
|
||||
do_div(val, NSEC_PER_SEC);
|
||||
if (val > UINT_MAX)
|
||||
@@ -718,16 +782,16 @@ static int mvebu_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
else
|
||||
off = 1;
|
||||
|
||||
- spin_lock_irqsave(&mvpwm->lock, flags);
|
||||
+ spin_lock_irqsave(&controller->lock, flags);
|
||||
|
||||
- writel_relaxed(on, mvebu_pwmreg_blink_on_duration(mvpwm));
|
||||
- writel_relaxed(off, mvebu_pwmreg_blink_off_duration(mvpwm));
|
||||
+ writel_relaxed(on, mvebu_pwmreg_blink_on_duration(controller));
|
||||
+ writel_relaxed(off, mvebu_pwmreg_blink_off_duration(controller));
|
||||
if (state->enabled)
|
||||
mvebu_gpio_blink(&mvchip->chip, pwm->hwpwm, 1);
|
||||
else
|
||||
mvebu_gpio_blink(&mvchip->chip, pwm->hwpwm, 0);
|
||||
|
||||
- spin_unlock_irqrestore(&mvpwm->lock, flags);
|
||||
+ spin_unlock_irqrestore(&controller->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -746,10 +810,10 @@ static void __maybe_unused mvebu_pwm_suspend(struct mvebu_gpio_chip *mvchip)
|
||||
|
||||
regmap_read(mvchip->regs, GPIO_BLINK_CNT_SELECT_OFF + mvchip->offset,
|
||||
&mvpwm->blink_select);
|
||||
- mvpwm->blink_on_duration =
|
||||
- readl_relaxed(mvebu_pwmreg_blink_on_duration(mvpwm));
|
||||
- mvpwm->blink_off_duration =
|
||||
- readl_relaxed(mvebu_pwmreg_blink_off_duration(mvpwm));
|
||||
+ mvpwm->controller.blink_on_duration =
|
||||
+ readl_relaxed(mvebu_pwmreg_blink_on_duration(&mvpwm->controller));
|
||||
+ mvpwm->controller.blink_off_duration =
|
||||
+ readl_relaxed(mvebu_pwmreg_blink_off_duration(&mvpwm->controller));
|
||||
}
|
||||
|
||||
static void __maybe_unused mvebu_pwm_resume(struct mvebu_gpio_chip *mvchip)
|
||||
@@ -758,10 +822,10 @@ static void __maybe_unused mvebu_pwm_resume(struct mvebu_gpio_chip *mvchip)
|
||||
|
||||
regmap_write(mvchip->regs, GPIO_BLINK_CNT_SELECT_OFF + mvchip->offset,
|
||||
mvpwm->blink_select);
|
||||
- writel_relaxed(mvpwm->blink_on_duration,
|
||||
- mvebu_pwmreg_blink_on_duration(mvpwm));
|
||||
- writel_relaxed(mvpwm->blink_off_duration,
|
||||
- mvebu_pwmreg_blink_off_duration(mvpwm));
|
||||
+ writel_relaxed(mvpwm->controller.blink_on_duration,
|
||||
+ mvebu_pwmreg_blink_on_duration(&mvpwm->controller));
|
||||
+ writel_relaxed(mvpwm->controller.blink_off_duration,
|
||||
+ mvebu_pwmreg_blink_off_duration(&mvpwm->controller));
|
||||
}
|
||||
|
||||
static int mvebu_pwm_probe(struct platform_device *pdev,
|
||||
@@ -772,6 +836,7 @@ static int mvebu_pwm_probe(struct platform_device *pdev,
|
||||
struct mvebu_pwm *mvpwm;
|
||||
struct resource *res;
|
||||
u32 set;
|
||||
+ enum mvebu_pwm_ctrl ctrl_set;
|
||||
|
||||
if (!of_device_is_compatible(mvchip->chip.of_node,
|
||||
"marvell,armada-370-gpio"))
|
||||
@@ -794,12 +859,15 @@ static int mvebu_pwm_probe(struct platform_device *pdev,
|
||||
* Use set A for lines of GPIO chip with id 0, B for GPIO chip
|
||||
* with id 1. Don't allow further GPIO chips to be used for PWM.
|
||||
*/
|
||||
- if (id == 0)
|
||||
+ if (id == 0) {
|
||||
set = 0;
|
||||
- else if (id == 1)
|
||||
+ ctrl_set = MVEBU_PWM_CTRL_SET_A;
|
||||
+ } else if (id == 1) {
|
||||
set = U32_MAX;
|
||||
- else
|
||||
+ ctrl_set = MVEBU_PWM_CTRL_SET_B;
|
||||
+ } else {
|
||||
return -EINVAL;
|
||||
+ }
|
||||
regmap_write(mvchip->regs,
|
||||
GPIO_BLINK_CNT_SELECT_OFF + mvchip->offset, set);
|
||||
|
||||
@@ -809,15 +877,13 @@ static int mvebu_pwm_probe(struct platform_device *pdev,
|
||||
mvchip->mvpwm = mvpwm;
|
||||
mvpwm->mvchip = mvchip;
|
||||
|
||||
- mvpwm->membase = devm_ioremap_resource(dev, res);
|
||||
- if (IS_ERR(mvpwm->membase))
|
||||
- return PTR_ERR(mvpwm->membase);
|
||||
+ mvpwm->controller.membase = devm_ioremap_resource(dev, res);
|
||||
+ if (IS_ERR(mvpwm->controller.membase))
|
||||
+ return PTR_ERR(mvpwm->controller.membase);
|
||||
|
||||
- mvpwm->clk_rate = clk_get_rate(mvchip->clk);
|
||||
- if (!mvpwm->clk_rate) {
|
||||
- dev_err(dev, "failed to get clock rate\n");
|
||||
+ mvpwm->controller.clk_rate = clk_get_rate(mvchip->clk);
|
||||
+ if (!mvpwm->controller.clk_rate)
|
||||
return -EINVAL;
|
||||
- }
|
||||
|
||||
mvpwm->chip.dev = dev;
|
||||
mvpwm->chip.ops = &mvebu_pwm_ops;
|
||||
@@ -830,7 +896,9 @@ static int mvebu_pwm_probe(struct platform_device *pdev,
|
||||
*/
|
||||
mvpwm->chip.base = -1;
|
||||
|
||||
- spin_lock_init(&mvpwm->lock);
|
||||
+ spin_lock_init(&mvpwm->controller.lock);
|
||||
+ mvpwm->default_counter = ctrl_set;
|
||||
+ mvebu_pwm_list[ctrl_set] = &mvpwm->controller;
|
||||
|
||||
return pwmchip_add(&mvpwm->chip);
|
||||
}
|
||||
331
patch/kernel/mvebu-next/93-helios4-device-tree.patch
Normal file
331
patch/kernel/mvebu-next/93-helios4-device-tree.patch
Normal file
@ -0,0 +1,331 @@
|
||||
arch/arm/boot/dts/Makefile | 1 +
|
||||
arch/arm/boot/dts/armada-388-helios4.dts | 309 +++++++++++++++++++++
|
||||
2 files changed, 310 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
|
||||
index 4b17f35..c6b6038 100644
|
||||
--- a/arch/arm/boot/dts/Makefile
|
||||
+++ b/arch/arm/boot/dts/Makefile
|
||||
@@ -1020,6 +1020,7 @@ dtb-$(CONFIG_MACH_ARMADA_38X) += \
|
||||
armada-388-clearfog.dtb \
|
||||
armada-388-clearfog-base.dtb \
|
||||
armada-388-clearfog-pro.dtb \
|
||||
+ armada-388-helios4.dtb \
|
||||
armada-388-db.dtb \
|
||||
armada-388-gp.dtb \
|
||||
armada-388-rd.dtb
|
||||
diff --git a/arch/arm/boot/dts/armada-388-helios4.dts b/arch/arm/boot/dts/armada-388-helios4.dts
|
||||
new file mode 100644
|
||||
index 0000000..93d0132
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/boot/dts/armada-388-helios4.dts
|
||||
@@ -0,0 +1,309 @@
|
||||
+/*
|
||||
+ * Device Tree file for Helios4
|
||||
+ * based on SolidRun Clearfog revision A1 rev 2.0 (88F6828)
|
||||
+ *
|
||||
+ * Copyright (C) 2017 Kobol.io
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+#include "armada-388.dtsi"
|
||||
+#include "armada-38x-solidrun-microsom.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ model = "Helios4";
|
||||
+ compatible = "marvell,armada388",
|
||||
+ "marvell,armada385", "marvell,armada380";
|
||||
+
|
||||
+ memory {
|
||||
+ device_type = "memory";
|
||||
+ reg = <0x00000000 0x80000000>; /* 2 GB */
|
||||
+ };
|
||||
+
|
||||
+ aliases {
|
||||
+ /* So that mvebu u-boot can update the MAC addresses */
|
||||
+ ethernet1 = ð0;
|
||||
+ };
|
||||
+
|
||||
+ chosen {
|
||||
+ stdout-path = "serial0:115200n8";
|
||||
+ };
|
||||
+
|
||||
+ reg_12v: regulator-12v {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ regulator-name = "power_brick_12V";
|
||||
+ regulator-min-microvolt = <12000000>;
|
||||
+ regulator-max-microvolt = <12000000>;
|
||||
+ regulator-always-on;
|
||||
+ };
|
||||
+
|
||||
+ reg_3p3v: regulator-3p3v {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ regulator-name = "3P3V";
|
||||
+ regulator-min-microvolt = <3300000>;
|
||||
+ regulator-max-microvolt = <3300000>;
|
||||
+ regulator-always-on;
|
||||
+ vin-supply = <®_12v>;
|
||||
+ };
|
||||
+
|
||||
+ reg_5p0v_hdd: regulator-5v-hdd {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ regulator-name = "5V_HDD";
|
||||
+ regulator-min-microvolt = <5000000>;
|
||||
+ regulator-max-microvolt = <5000000>;
|
||||
+ regulator-always-on;
|
||||
+ vin-supply = <®_12v>;
|
||||
+ };
|
||||
+
|
||||
+ reg_5p0v_usb: regulator-5v-usb {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ regulator-name = "USB-PWR";
|
||||
+ regulator-min-microvolt = <5000000>;
|
||||
+ regulator-max-microvolt = <5000000>;
|
||||
+ regulator-boot-on;
|
||||
+ regulator-always-on;
|
||||
+ enable-active-high;
|
||||
+ gpio = <&expander0 6 GPIO_ACTIVE_HIGH>;
|
||||
+ vin-supply = <®_12v>;
|
||||
+ };
|
||||
+
|
||||
+ system-leds {
|
||||
+ compatible = "gpio-leds";
|
||||
+ status-led {
|
||||
+ label = "helios4:green:status";
|
||||
+ gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
|
||||
+ linux,default-trigger = "heartbeat";
|
||||
+ default-state = "on";
|
||||
+ };
|
||||
+
|
||||
+ fault-led {
|
||||
+ label = "helios4:red:fault";
|
||||
+ gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
|
||||
+ default-state = "keep";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ io-leds {
|
||||
+ compatible = "gpio-leds";
|
||||
+ sata1-led {
|
||||
+ label = "helios4:green:ata1";
|
||||
+ gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
|
||||
+ linux,default-trigger = "ata1";
|
||||
+ default-state = "off";
|
||||
+ };
|
||||
+ sata2-led {
|
||||
+ label = "helios4:green:ata2";
|
||||
+ gpios = <&gpio1 18 GPIO_ACTIVE_LOW>;
|
||||
+ linux,default-trigger = "ata2";
|
||||
+ default-state = "off";
|
||||
+ };
|
||||
+ sata3-led {
|
||||
+ label = "helios4:green:ata3";
|
||||
+ gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
|
||||
+ linux,default-trigger = "ata3";
|
||||
+ default-state = "off";
|
||||
+ };
|
||||
+ sata4-led {
|
||||
+ label = "helios4:green:ata4";
|
||||
+ gpios = <&gpio1 21 GPIO_ACTIVE_LOW>;
|
||||
+ linux,default-trigger = "ata4";
|
||||
+ default-state = "off";
|
||||
+ };
|
||||
+ usb-led {
|
||||
+ label = "helios4:green:usb";
|
||||
+ gpios = <&gpio1 22 GPIO_ACTIVE_LOW>;
|
||||
+ linux,default-trigger = "usb-host";
|
||||
+ default-state = "off";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ fan1: j10-pwm {
|
||||
+ compatible = "pwm-fan";
|
||||
+ pwms = <&gpio1 9 40000>; /* Target freq:25 kHz */
|
||||
+ };
|
||||
+
|
||||
+ fan2: j17-pwm {
|
||||
+ compatible = "pwm-fan";
|
||||
+ pwms = <&gpio1 23 40000>; /* Target freq:25 kHz */
|
||||
+ };
|
||||
+
|
||||
+ usb2_phy: usb2-phy {
|
||||
+ compatible = "usb-nop-xceiv";
|
||||
+ vbus-regulator = <®_5p0v_usb>;
|
||||
+ };
|
||||
+
|
||||
+ usb3_phy: usb3-phy {
|
||||
+ compatible = "usb-nop-xceiv";
|
||||
+ //vbus-regulator = <®_5p0v_usb>;
|
||||
+ };
|
||||
+
|
||||
+ soc {
|
||||
+ internal-regs {
|
||||
+ sata@a8000 {
|
||||
+ status = "okay";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ sata0: sata-port@0 {
|
||||
+ reg = <0>;
|
||||
+ };
|
||||
+
|
||||
+ sata1: sata-port@1 {
|
||||
+ reg = <1>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ sata@e0000 {
|
||||
+ status = "okay";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ sata2: sata-port@0 {
|
||||
+ reg = <0>;
|
||||
+ };
|
||||
+
|
||||
+ sata3: sata-port@1 {
|
||||
+ reg = <1>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ sdhci@d8000 {
|
||||
+ bus-width = <4>;
|
||||
+ cd-gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
|
||||
+ no-1-8-v;
|
||||
+ pinctrl-0 = <µsom_sdhci_pins
|
||||
+ &helios_sdhci_cd_pins>;
|
||||
+ pinctrl-names = "default";
|
||||
+ status = "okay";
|
||||
+ vmmc = <®_3p3v>;
|
||||
+ wp-inverted;
|
||||
+ max-frequency = <50000000>;
|
||||
+ cap-sd-highspeed;
|
||||
+ sd-uhs-sdr12;
|
||||
+ sd-uhs-sdr25;
|
||||
+ sd-uhs-sdr50;
|
||||
+ };
|
||||
+
|
||||
+ usb@58000 {
|
||||
+ //vcc-supply = <®_5p0v_usb>;
|
||||
+ usb-phy = <&usb2_phy>;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ usb3@f0000 {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ usb3@f8000 {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&i2c0 {
|
||||
+ clock-frequency = <400000>;
|
||||
+ pinctrl-0 = <&i2c0_pins>;
|
||||
+ pinctrl-names = "default";
|
||||
+ status = "okay";
|
||||
+
|
||||
+ /*
|
||||
+ * PCA9655 GPIO expander, up to 1MHz clock.
|
||||
+ * 0-Board Revision bit 0 #
|
||||
+ * 1-Board Revision bit 1 #
|
||||
+ * 5-USB3 overcurrent
|
||||
+ * 6-USB3 power
|
||||
+ */
|
||||
+ expander0: gpio-expander@20 {
|
||||
+ /*
|
||||
+ * This is how it should be:
|
||||
+ * compatible = "onnn,pca9655", "nxp,pca9555";
|
||||
+ * but you can't do this because of the way I2C works.
|
||||
+ */
|
||||
+ compatible = "nxp,pca9555";
|
||||
+ gpio-controller;
|
||||
+ #gpio-cells = <2>;
|
||||
+ reg = <0x20>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&pca0_pins>;
|
||||
+ interrupt-parent = <&gpio0>;
|
||||
+ interrupts = <23 IRQ_TYPE_EDGE_FALLING>;
|
||||
+ interrupt-controller;
|
||||
+ #interrupt-cells = <2>;
|
||||
+
|
||||
+ board_rev_bit_0 {
|
||||
+ gpio-hog;
|
||||
+ gpios = <0 GPIO_ACTIVE_LOW>;
|
||||
+ input;
|
||||
+ line-name = "board-rev-0";
|
||||
+ };
|
||||
+ board_rev_bit_1 {
|
||||
+ gpio-hog;
|
||||
+ gpios = <1 GPIO_ACTIVE_LOW>;
|
||||
+ input;
|
||||
+ line-name = "board-rev-1";
|
||||
+ };
|
||||
+ usb3_ilimit {
|
||||
+ gpio-hog;
|
||||
+ gpios = <5 GPIO_ACTIVE_HIGH>;
|
||||
+ input;
|
||||
+ line-name = "usb-overcurrent-status";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ temp_sensor: temp@4c {
|
||||
+ compatible = "ti,lm75";
|
||||
+ reg = <0x4c>;
|
||||
+ vcc-supply = <®_3p3v>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&i2c1 {
|
||||
+ /*
|
||||
+ * External I2C Bus for user peripheral
|
||||
+ */
|
||||
+ clock-frequency = <400000>;
|
||||
+ pinctrl-0 = <&helios_i2c1_pins>;
|
||||
+ pinctrl-names = "default";
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&pinctrl {
|
||||
+ pca0_pins: pca0_pins {
|
||||
+ marvell,pins = "mpp23";
|
||||
+ marvell,function = "gpio";
|
||||
+ };
|
||||
+ microsom_phy0_int_pins: microsom-phy0-int-pins {
|
||||
+ marvell,pins = "mpp18";
|
||||
+ marvell,function = "gpio";
|
||||
+ };
|
||||
+ helios_i2c1_pins: i2c1-pins {
|
||||
+ marvell,pins = "mpp26", "mpp27";
|
||||
+ marvell,function = "i2c1";
|
||||
+ };
|
||||
+ helios_sdhci_cd_pins: helios-sdhci-cd-pins {
|
||||
+ marvell,pins = "mpp20";
|
||||
+ marvell,function = "gpio";
|
||||
+ };
|
||||
+ helios_led_pins: helios-led-pins {
|
||||
+ marvell,pins = "mpp24", "mpp25",
|
||||
+ "mpp49", "mpp50",
|
||||
+ "mpp52", "mpp53",
|
||||
+ "mpp54";
|
||||
+ marvell,function = "gpio";
|
||||
+ };
|
||||
+ helios_fan_pins: helios-fan-pins {
|
||||
+ marvell,pins = "mpp41", "mpp43",
|
||||
+ "mpp48", "mpp55";
|
||||
+ marvell,function = "gpio";
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&spi1 {
|
||||
+ status = "okay";
|
||||
+
|
||||
+ spi-flash@0 {
|
||||
+ spi-max-frequency = <104000000>;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+};
|
||||
@ -0,0 +1,17 @@
|
||||
diff --git a/arch/arm/boot/dts/armada-388-helios4.dts b/arch/arm/boot/dts/armada-388-helios4.dts
|
||||
index 93d0132..47699bd 100644
|
||||
--- a/arch/arm/boot/dts/armada-388-helios4.dts
|
||||
+++ b/arch/arm/boot/dts/armada-388-helios4.dts
|
||||
@@ -298,12 +298,3 @@
|
||||
marvell,function = "gpio";
|
||||
};
|
||||
};
|
||||
-
|
||||
-&spi1 {
|
||||
- status = "okay";
|
||||
-
|
||||
- spi-flash@0 {
|
||||
- spi-max-frequency = <104000000>;
|
||||
- status = "okay";
|
||||
- };
|
||||
-};
|
||||
@ -0,0 +1,16 @@
|
||||
diff --git a/arch/arm/boot/dts/armada-388-helios4.dts b/arch/arm/boot/dts/armada-388-helios4.dts
|
||||
index 47699bd..4a5e8fc 100644
|
||||
--- a/arch/arm/boot/dts/armada-388-helios4.dts
|
||||
+++ b/arch/arm/boot/dts/armada-388-helios4.dts
|
||||
@@ -177,11 +177,6 @@
|
||||
status = "okay";
|
||||
vmmc = <®_3p3v>;
|
||||
wp-inverted;
|
||||
- max-frequency = <50000000>;
|
||||
- cap-sd-highspeed;
|
||||
- sd-uhs-sdr12;
|
||||
- sd-uhs-sdr25;
|
||||
- sd-uhs-sdr50;
|
||||
};
|
||||
|
||||
usb@58000 {
|
||||
357
patch/kernel/mvebu-next/add-helios4.patch
Normal file
357
patch/kernel/mvebu-next/add-helios4.patch
Normal file
@ -0,0 +1,357 @@
|
||||
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
|
||||
index eff87a3..3efb92f
|
||||
--- a/arch/arm/boot/dts/Makefile
|
||||
+++ b/arch/arm/boot/dts/Makefile
|
||||
@@ -1028,6 +1028,7 @@ dtb-$(CONFIG_MACH_ARMADA_38X) += \
|
||||
armada-385-linksys-rango.dtb \
|
||||
armada-385-linksys-shelby.dtb \
|
||||
armada-385-synology-ds116.dtb \
|
||||
+ armada-388-helios4.dtb \
|
||||
armada-385-turris-omnia.dtb \
|
||||
armada-388-clearfog.dtb \
|
||||
armada-388-clearfog-base.dtb \
|
||||
diff --git a/arch/arm/boot/dts/armada-388-helios4.dts b/arch/arm/boot/dts/armada-388-helios4.dts
|
||||
new file mode 100644
|
||||
index 0000000..4edb552
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/boot/dts/armada-388-helios4.dts
|
||||
@@ -0,0 +1,339 @@
|
||||
+/*
|
||||
+ * Device Tree file for Helios-4
|
||||
+ * based on SolidRun Clearfog revision A1 rev 2.0 (88F6828)
|
||||
+ *
|
||||
+ * Copyright (C) 2017
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+#include "armada-388.dtsi"
|
||||
+#include "armada-38x-solidrun-microsom.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ model = "Helios4";
|
||||
+ compatible = "marvell,armada388",
|
||||
+ "marvell,armada385", "marvell,armada380";
|
||||
+
|
||||
+ memory {
|
||||
+ device_type = "memory";
|
||||
+ reg = <0x00000000 0x40000000>; /* 1 GB */
|
||||
+ };
|
||||
+
|
||||
+ aliases {
|
||||
+ /* So that mvebu u-boot can update the MAC addresses */
|
||||
+ ethernet1 = ð0;
|
||||
+ };
|
||||
+
|
||||
+ chosen {
|
||||
+ stdout-path = "serial0:115200n8";
|
||||
+ };
|
||||
+
|
||||
+ reg_12v: regulator-12v {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ regulator-name = "power_brick_12V";
|
||||
+ regulator-min-microvolt = <12000000>;
|
||||
+ regulator-max-microvolt = <12000000>;
|
||||
+ regulator-always-on;
|
||||
+ };
|
||||
+
|
||||
+ reg_3p3v: regulator-3p3v {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ regulator-name = "3P3V";
|
||||
+ regulator-min-microvolt = <3300000>;
|
||||
+ regulator-max-microvolt = <3300000>;
|
||||
+ regulator-always-on;
|
||||
+ vin-supply = <®_12v>;
|
||||
+ };
|
||||
+
|
||||
+ reg_5p0v_hdd: regulator-5v-hdd {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ regulator-name = "5V_HDD";
|
||||
+ regulator-min-microvolt = <5000000>;
|
||||
+ regulator-max-microvolt = <5000000>;
|
||||
+ regulator-always-on;
|
||||
+ vin-supply = <®_12v>;
|
||||
+ };
|
||||
+
|
||||
+ reg_5p0v_usb: regulator-5v-usb {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ regulator-name = "USB-PWR";
|
||||
+ regulator-min-microvolt = <5000000>;
|
||||
+ regulator-max-microvolt = <5000000>;
|
||||
+ regulator-boot-on;
|
||||
+ regulator-always-on;
|
||||
+ enable-active-high;
|
||||
+ gpio = <&expander0 6 GPIO_ACTIVE_HIGH>;
|
||||
+ vin-supply = <®_12v>;
|
||||
+ };
|
||||
+
|
||||
+ gpio-keys {
|
||||
+ compatible = "gpio-keys";
|
||||
+ pinctrl-0 = <&user_button_pins>;
|
||||
+ pinctrl-names = "default";
|
||||
+
|
||||
+ button_0 {
|
||||
+ label = "User Button";
|
||||
+ gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
|
||||
+ linux,can-disable;
|
||||
+ linux,code = <BTN_0>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ system-leds {
|
||||
+ compatible = "gpio-leds";
|
||||
+ status-led {
|
||||
+ label = "helios4:green:status";
|
||||
+ gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
|
||||
+ linux,default-trigger = "heartbeat";
|
||||
+ default-state = "on";
|
||||
+ };
|
||||
+
|
||||
+ fault-led {
|
||||
+ label = "helios4:red:fault";
|
||||
+ gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
|
||||
+ default-state = "keep";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ io-leds {
|
||||
+ compatible = "gpio-leds";
|
||||
+ sata1-led {
|
||||
+ label = "helios4:green:ata1";
|
||||
+ gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
|
||||
+ linux,default-trigger = "ata1";
|
||||
+ default-state = "off";
|
||||
+ };
|
||||
+ sata2-led {
|
||||
+ label = "helios4:green:ata2";
|
||||
+ gpios = <&gpio1 18 GPIO_ACTIVE_LOW>;
|
||||
+ linux,default-trigger = "ata2";
|
||||
+ default-state = "off";
|
||||
+ };
|
||||
+ sata3-led {
|
||||
+ label = "helios4:green:ata3";
|
||||
+ gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
|
||||
+ linux,default-trigger = "ata3";
|
||||
+ default-state = "off";
|
||||
+ };
|
||||
+ sata4-led {
|
||||
+ label = "helios4:green:ata4";
|
||||
+ gpios = <&gpio1 21 GPIO_ACTIVE_LOW>;
|
||||
+ linux,default-trigger = "ata4";
|
||||
+ default-state = "off";
|
||||
+ };
|
||||
+ usb-led {
|
||||
+ label = "helios4:green:usb";
|
||||
+ gpios = <&gpio1 22 GPIO_ACTIVE_LOW>;
|
||||
+ linux,default-trigger = "usb-host";
|
||||
+ default-state = "off";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ fan1: j10-pwm {
|
||||
+ compatible = "pwm-fan";
|
||||
+ pwms = <&gpio1 9 3000>;
|
||||
+ };
|
||||
+
|
||||
+ fan2: j17-pwm {
|
||||
+ compatible = "pwm-fan";
|
||||
+ pwms = <&gpio1 4 4500>;
|
||||
+ };
|
||||
+
|
||||
+ usb2_phy: usb2-phy {
|
||||
+ compatible = "usb-nop-xceiv";
|
||||
+ vbus-regulator = <®_5p0v_usb>;
|
||||
+ };
|
||||
+
|
||||
+ usb3_phy: usb3-phy {
|
||||
+ compatible = "usb-nop-xceiv";
|
||||
+ //vbus-regulator = <®_5p0v_usb>;
|
||||
+ };
|
||||
+
|
||||
+ soc {
|
||||
+ internal-regs {
|
||||
+ i2c@11000 {
|
||||
+ clock-frequency = <100000>;
|
||||
+ pinctrl-0 = <&i2c0_pins>;
|
||||
+ pinctrl-names = "default";
|
||||
+ status = "okay";
|
||||
+
|
||||
+ /*
|
||||
+ * PCA9655 GPIO expander, up to 1MHz clock.
|
||||
+ * 0-Board Revision bit 0 #
|
||||
+ * 1-Board Revision bit 1 #
|
||||
+ * 5-USB3 overcurrent
|
||||
+ * 6-USB3 power
|
||||
+ */
|
||||
+ expander0: gpio-expander@20 {
|
||||
+ /*
|
||||
+ * This is how it should be:
|
||||
+ * compatible = "onnn,pca9655",
|
||||
+ * "nxp,pca9555";
|
||||
+ * but you can't do this because of
|
||||
+ * the way I2C works.
|
||||
+ */
|
||||
+ compatible = "nxp,pca9555";
|
||||
+ gpio-controller;
|
||||
+ #gpio-cells = <2>;
|
||||
+ reg = <0x20>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&pca0_pins>;
|
||||
+ interrupt-parent = <&gpio0>;
|
||||
+ interrupts = <18 IRQ_TYPE_EDGE_FALLING>;
|
||||
+ interrupt-controller;
|
||||
+ #interrupt-cells = <2>;
|
||||
+
|
||||
+ board_rev_bit_0 {
|
||||
+ gpio-hog;
|
||||
+ gpios = <0 GPIO_ACTIVE_LOW>;
|
||||
+ input;
|
||||
+ line-name = "board-rev-0";
|
||||
+ };
|
||||
+ board_rev_bit_1 {
|
||||
+ gpio-hog;
|
||||
+ gpios = <1 GPIO_ACTIVE_LOW>;
|
||||
+ input;
|
||||
+ line-name = "board-rev-1";
|
||||
+ };
|
||||
+ usb3_ilimit {
|
||||
+ gpio-hog;
|
||||
+ gpios = <5 GPIO_ACTIVE_HIGH>;
|
||||
+ input;
|
||||
+ line-name = "usb-overcurrent-status";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ temp_sensor: temp@4c {
|
||||
+ compatible = "ti,lm75";
|
||||
+ reg = <0x4c>;
|
||||
+ vcc-supply = <®_3p3v>;
|
||||
+ };
|
||||
+
|
||||
+ /* What device at 0x64 ? */
|
||||
+ };
|
||||
+
|
||||
+ i2c@11100 {
|
||||
+ /*
|
||||
+ * External I2C Bus for user peripheral
|
||||
+ */
|
||||
+ clock-frequency = <400000>;
|
||||
+ pinctrl-0 = <&helios_i2c1_pins>;
|
||||
+ pinctrl-names = "default";
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ sata@a8000 {
|
||||
+ status = "okay";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ sata0: sata-port@0 {
|
||||
+ reg = <0>;
|
||||
+ };
|
||||
+
|
||||
+ sata1: sata-port@1 {
|
||||
+ reg = <1>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ sata@e0000 {
|
||||
+ status = "okay";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ sata2: sata-port@0 {
|
||||
+ reg = <0>;
|
||||
+ };
|
||||
+
|
||||
+ sata3: sata-port@1 {
|
||||
+ reg = <1>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ spi@10680 {
|
||||
+ pinctrl-0 = <&spi1_pins
|
||||
+ µsom_spi1_cs_pins>;
|
||||
+ pinctrl-names = "default";
|
||||
+ status = "okay";
|
||||
+
|
||||
+ spi-flash@0 {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+ compatible = "w25q32", "jedec,spi-nor";
|
||||
+ reg = <0>; /* Chip select 0 */
|
||||
+ spi-max-frequency = <104000000>;
|
||||
+ spi-cpha;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ sdhci@d8000 {
|
||||
+ bus-width = <4>;
|
||||
+ cd-gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
|
||||
+ no-1-8-v;
|
||||
+ pinctrl-0 = <&helios_sdhci_pins
|
||||
+ &helios_sdhci_cd_pins>;
|
||||
+ pinctrl-names = "default";
|
||||
+ status = "okay";
|
||||
+ vmmc = <®_3p3v>;
|
||||
+ wp-inverted;
|
||||
+ };
|
||||
+
|
||||
+ usb@58000 {
|
||||
+ //vcc-supply = <®_5p0v_usb>;
|
||||
+ usb-phy = <&usb2_phy>;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ usb3@f0000 {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ usb3@f8000 {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ pinctrl@18000 {
|
||||
+ pca0_pins: pca0_pins {
|
||||
+ marvell,pins = "mpp18";
|
||||
+ marvell,function = "gpio";
|
||||
+ };
|
||||
+ helios_i2c1_pins: i2c1-pins {
|
||||
+ marvell,pins = "mpp26", "mpp27";
|
||||
+ marvell,function = "i2c1";
|
||||
+ };
|
||||
+ helios_sdhci_cd_pins: helios-sdhci-cd-pins {
|
||||
+ marvell,pins = "mpp20";
|
||||
+ marvell,function = "gpio";
|
||||
+ };
|
||||
+ helios_sdhci_pins: helios-sdhci-pins {
|
||||
+ marvell,pins = "mpp21", "mpp28",
|
||||
+ "mpp37", "mpp38",
|
||||
+ "mpp39", "mpp40";
|
||||
+ marvell,function = "sd0";
|
||||
+ };
|
||||
+ helios_led_pins: helios-led-pins {
|
||||
+ marvell,pins = "mpp24", "mpp25",
|
||||
+ "mpp49", "mpp50",
|
||||
+ "mpp52", "mpp53",
|
||||
+ "mpp54";
|
||||
+ marvell,function = "gpio";
|
||||
+ };
|
||||
+ helios_fan_pins: helios-fan-pins {
|
||||
+ marvell,pins = "mpp41", "mpp43",
|
||||
+ "mpp48", "mpp55";
|
||||
+ marvell,function = "gpio";
|
||||
+ };
|
||||
+ microsom_spi1_cs_pins: spi1-cs-pins {
|
||||
+ marvell,pins = "mpp59";
|
||||
+ marvell,function = "spi1";
|
||||
+ };
|
||||
+ user_button_pins: user-button-pins {
|
||||
+ marvell,pins = "mpp23";
|
||||
+ marvell,function = "gpio";
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2623
patch/kernel/mvebu64-default/04-patch-4.4.107-108.patch
Normal file
2623
patch/kernel/mvebu64-default/04-patch-4.4.107-108.patch
Normal file
File diff suppressed because it is too large
Load Diff
2275
patch/kernel/mvebu64-default/04-patch-4.4.108-109.patch
Normal file
2275
patch/kernel/mvebu64-default/04-patch-4.4.108-109.patch
Normal file
File diff suppressed because it is too large
Load Diff
2814
patch/kernel/mvebu64-default/04-patch-4.4.109-110.patch
Normal file
2814
patch/kernel/mvebu64-default/04-patch-4.4.109-110.patch
Normal file
File diff suppressed because it is too large
Load Diff
2623
patch/kernel/rockchip-default/04-patch-4.4.107-108.patch
Normal file
2623
patch/kernel/rockchip-default/04-patch-4.4.107-108.patch
Normal file
File diff suppressed because it is too large
Load Diff
2275
patch/kernel/rockchip-default/04-patch-4.4.108-109.patch
Normal file
2275
patch/kernel/rockchip-default/04-patch-4.4.108-109.patch
Normal file
File diff suppressed because it is too large
Load Diff
2814
patch/kernel/rockchip-default/04-patch-4.4.109-110.patch
Normal file
2814
patch/kernel/rockchip-default/04-patch-4.4.109-110.patch
Normal file
File diff suppressed because it is too large
Load Diff
763
patch/kernel/s5p6818-default/03-patch-4.4.49-50.patch
Normal file
763
patch/kernel/s5p6818-default/03-patch-4.4.49-50.patch
Normal file
@ -0,0 +1,763 @@
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 5fab6d4068b5..10993715abb8 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 4
|
||||
-SUBLEVEL = 49
|
||||
+SUBLEVEL = 50
|
||||
EXTRAVERSION =
|
||||
NAME = Blurry Fish Butt
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
|
||||
index bbff8ec6713e..28a4b34310b2 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
|
||||
@@ -502,8 +502,11 @@ void mlx4_en_recover_from_oom(struct mlx4_en_priv *priv)
|
||||
return;
|
||||
|
||||
for (ring = 0; ring < priv->rx_ring_num; ring++) {
|
||||
- if (mlx4_en_is_ring_empty(priv->rx_ring[ring]))
|
||||
+ if (mlx4_en_is_ring_empty(priv->rx_ring[ring])) {
|
||||
+ local_bh_disable();
|
||||
napi_reschedule(&priv->rx_cq[ring]->napi);
|
||||
+ local_bh_enable();
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
|
||||
index dc7d970bd1c0..effcdbfb06e9 100644
|
||||
--- a/drivers/net/loopback.c
|
||||
+++ b/drivers/net/loopback.c
|
||||
@@ -164,6 +164,7 @@ static void loopback_setup(struct net_device *dev)
|
||||
{
|
||||
dev->mtu = 64 * 1024;
|
||||
dev->hard_header_len = ETH_HLEN; /* 14 */
|
||||
+ dev->min_header_len = ETH_HLEN; /* 14 */
|
||||
dev->addr_len = ETH_ALEN; /* 6 */
|
||||
dev->type = ARPHRD_LOOPBACK; /* 0x0001*/
|
||||
dev->flags = IFF_LOOPBACK;
|
||||
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
|
||||
index 159a68782bec..79de9608ac48 100644
|
||||
--- a/drivers/net/macvtap.c
|
||||
+++ b/drivers/net/macvtap.c
|
||||
@@ -725,7 +725,7 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
|
||||
ssize_t n;
|
||||
|
||||
if (q->flags & IFF_VNET_HDR) {
|
||||
- vnet_hdr_len = q->vnet_hdr_sz;
|
||||
+ vnet_hdr_len = READ_ONCE(q->vnet_hdr_sz);
|
||||
|
||||
err = -EINVAL;
|
||||
if (len < vnet_hdr_len)
|
||||
@@ -865,7 +865,7 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q,
|
||||
|
||||
if (q->flags & IFF_VNET_HDR) {
|
||||
struct virtio_net_hdr vnet_hdr;
|
||||
- vnet_hdr_len = q->vnet_hdr_sz;
|
||||
+ vnet_hdr_len = READ_ONCE(q->vnet_hdr_sz);
|
||||
if (iov_iter_count(iter) < vnet_hdr_len)
|
||||
return -EINVAL;
|
||||
|
||||
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
|
||||
index 111b972e3053..c31d8e74f131 100644
|
||||
--- a/drivers/net/tun.c
|
||||
+++ b/drivers/net/tun.c
|
||||
@@ -1108,9 +1108,11 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
|
||||
}
|
||||
|
||||
if (tun->flags & IFF_VNET_HDR) {
|
||||
- if (len < tun->vnet_hdr_sz)
|
||||
+ int vnet_hdr_sz = READ_ONCE(tun->vnet_hdr_sz);
|
||||
+
|
||||
+ if (len < vnet_hdr_sz)
|
||||
return -EINVAL;
|
||||
- len -= tun->vnet_hdr_sz;
|
||||
+ len -= vnet_hdr_sz;
|
||||
|
||||
n = copy_from_iter(&gso, sizeof(gso), from);
|
||||
if (n != sizeof(gso))
|
||||
@@ -1122,7 +1124,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
|
||||
|
||||
if (tun16_to_cpu(tun, gso.hdr_len) > len)
|
||||
return -EINVAL;
|
||||
- iov_iter_advance(from, tun->vnet_hdr_sz - sizeof(gso));
|
||||
+ iov_iter_advance(from, vnet_hdr_sz - sizeof(gso));
|
||||
}
|
||||
|
||||
if ((tun->flags & TUN_TYPE_MASK) == IFF_TAP) {
|
||||
@@ -1301,7 +1303,7 @@ static ssize_t tun_put_user(struct tun_struct *tun,
|
||||
vlan_hlen = VLAN_HLEN;
|
||||
|
||||
if (tun->flags & IFF_VNET_HDR)
|
||||
- vnet_hdr_sz = tun->vnet_hdr_sz;
|
||||
+ vnet_hdr_sz = READ_ONCE(tun->vnet_hdr_sz);
|
||||
|
||||
total = skb->len + vlan_hlen + vnet_hdr_sz;
|
||||
|
||||
diff --git a/include/linux/can/core.h b/include/linux/can/core.h
|
||||
index a0875001b13c..df08a41d5be5 100644
|
||||
--- a/include/linux/can/core.h
|
||||
+++ b/include/linux/can/core.h
|
||||
@@ -45,10 +45,9 @@ struct can_proto {
|
||||
extern int can_proto_register(const struct can_proto *cp);
|
||||
extern void can_proto_unregister(const struct can_proto *cp);
|
||||
|
||||
-extern int can_rx_register(struct net_device *dev, canid_t can_id,
|
||||
- canid_t mask,
|
||||
- void (*func)(struct sk_buff *, void *),
|
||||
- void *data, char *ident);
|
||||
+int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask,
|
||||
+ void (*func)(struct sk_buff *, void *),
|
||||
+ void *data, char *ident, struct sock *sk);
|
||||
|
||||
extern void can_rx_unregister(struct net_device *dev, canid_t can_id,
|
||||
canid_t mask,
|
||||
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
|
||||
index 93a6a2c66d15..4035bbe40971 100644
|
||||
--- a/include/linux/netdevice.h
|
||||
+++ b/include/linux/netdevice.h
|
||||
@@ -1399,6 +1399,7 @@ enum netdev_priv_flags {
|
||||
* @mtu: Interface MTU value
|
||||
* @type: Interface hardware type
|
||||
* @hard_header_len: Maximum hardware header length.
|
||||
+ * @min_header_len: Minimum hardware header length
|
||||
*
|
||||
* @needed_headroom: Extra headroom the hardware may need, but not in all
|
||||
* cases can this be guaranteed
|
||||
@@ -1619,6 +1620,7 @@ struct net_device {
|
||||
unsigned int mtu;
|
||||
unsigned short type;
|
||||
unsigned short hard_header_len;
|
||||
+ unsigned short min_header_len;
|
||||
|
||||
unsigned short needed_headroom;
|
||||
unsigned short needed_tailroom;
|
||||
@@ -2541,6 +2543,8 @@ static inline bool dev_validate_header(const struct net_device *dev,
|
||||
{
|
||||
if (likely(len >= dev->hard_header_len))
|
||||
return true;
|
||||
+ if (len < dev->min_header_len)
|
||||
+ return false;
|
||||
|
||||
if (capable(CAP_SYS_RAWIO)) {
|
||||
memset(ll_header + len, 0, dev->hard_header_len - len);
|
||||
diff --git a/include/net/cipso_ipv4.h b/include/net/cipso_ipv4.h
|
||||
index 3ebb168b9afc..a34b141f125f 100644
|
||||
--- a/include/net/cipso_ipv4.h
|
||||
+++ b/include/net/cipso_ipv4.h
|
||||
@@ -309,6 +309,10 @@ static inline int cipso_v4_validate(const struct sk_buff *skb,
|
||||
}
|
||||
|
||||
for (opt_iter = 6; opt_iter < opt_len;) {
|
||||
+ if (opt_iter + 1 == opt_len) {
|
||||
+ err_offset = opt_iter;
|
||||
+ goto out;
|
||||
+ }
|
||||
tag_len = opt[opt_iter + 1];
|
||||
if ((tag_len == 0) || (tag_len > (opt_len - opt_iter))) {
|
||||
err_offset = opt_iter + 1;
|
||||
diff --git a/net/can/af_can.c b/net/can/af_can.c
|
||||
index 166d436196c1..928f58064098 100644
|
||||
--- a/net/can/af_can.c
|
||||
+++ b/net/can/af_can.c
|
||||
@@ -445,6 +445,7 @@ static struct hlist_head *find_rcv_list(canid_t *can_id, canid_t *mask,
|
||||
* @func: callback function on filter match
|
||||
* @data: returned parameter for callback function
|
||||
* @ident: string for calling module identification
|
||||
+ * @sk: socket pointer (might be NULL)
|
||||
*
|
||||
* Description:
|
||||
* Invokes the callback function with the received sk_buff and the given
|
||||
@@ -468,7 +469,7 @@ static struct hlist_head *find_rcv_list(canid_t *can_id, canid_t *mask,
|
||||
*/
|
||||
int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask,
|
||||
void (*func)(struct sk_buff *, void *), void *data,
|
||||
- char *ident)
|
||||
+ char *ident, struct sock *sk)
|
||||
{
|
||||
struct receiver *r;
|
||||
struct hlist_head *rl;
|
||||
@@ -496,6 +497,7 @@ int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask,
|
||||
r->func = func;
|
||||
r->data = data;
|
||||
r->ident = ident;
|
||||
+ r->sk = sk;
|
||||
|
||||
hlist_add_head_rcu(&r->list, rl);
|
||||
d->entries++;
|
||||
@@ -520,8 +522,11 @@ EXPORT_SYMBOL(can_rx_register);
|
||||
static void can_rx_delete_receiver(struct rcu_head *rp)
|
||||
{
|
||||
struct receiver *r = container_of(rp, struct receiver, rcu);
|
||||
+ struct sock *sk = r->sk;
|
||||
|
||||
kmem_cache_free(rcv_cache, r);
|
||||
+ if (sk)
|
||||
+ sock_put(sk);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -596,8 +601,11 @@ void can_rx_unregister(struct net_device *dev, canid_t can_id, canid_t mask,
|
||||
spin_unlock(&can_rcvlists_lock);
|
||||
|
||||
/* schedule the receiver item for deletion */
|
||||
- if (r)
|
||||
+ if (r) {
|
||||
+ if (r->sk)
|
||||
+ sock_hold(r->sk);
|
||||
call_rcu(&r->rcu, can_rx_delete_receiver);
|
||||
+ }
|
||||
}
|
||||
EXPORT_SYMBOL(can_rx_unregister);
|
||||
|
||||
diff --git a/net/can/af_can.h b/net/can/af_can.h
|
||||
index fca0fe9fc45a..b86f5129e838 100644
|
||||
--- a/net/can/af_can.h
|
||||
+++ b/net/can/af_can.h
|
||||
@@ -50,13 +50,14 @@
|
||||
|
||||
struct receiver {
|
||||
struct hlist_node list;
|
||||
- struct rcu_head rcu;
|
||||
canid_t can_id;
|
||||
canid_t mask;
|
||||
unsigned long matches;
|
||||
void (*func)(struct sk_buff *, void *);
|
||||
void *data;
|
||||
char *ident;
|
||||
+ struct sock *sk;
|
||||
+ struct rcu_head rcu;
|
||||
};
|
||||
|
||||
#define CAN_SFF_RCV_ARRAY_SZ (1 << CAN_SFF_ID_BITS)
|
||||
diff --git a/net/can/bcm.c b/net/can/bcm.c
|
||||
index 24d66c1cc0cd..4ccfd356baed 100644
|
||||
--- a/net/can/bcm.c
|
||||
+++ b/net/can/bcm.c
|
||||
@@ -1179,7 +1179,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
|
||||
err = can_rx_register(dev, op->can_id,
|
||||
REGMASK(op->can_id),
|
||||
bcm_rx_handler, op,
|
||||
- "bcm");
|
||||
+ "bcm", sk);
|
||||
|
||||
op->rx_reg_dev = dev;
|
||||
dev_put(dev);
|
||||
@@ -1188,7 +1188,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
|
||||
} else
|
||||
err = can_rx_register(NULL, op->can_id,
|
||||
REGMASK(op->can_id),
|
||||
- bcm_rx_handler, op, "bcm");
|
||||
+ bcm_rx_handler, op, "bcm", sk);
|
||||
if (err) {
|
||||
/* this bcm rx op is broken -> remove it */
|
||||
list_del(&op->list);
|
||||
diff --git a/net/can/gw.c b/net/can/gw.c
|
||||
index 455168718c2e..77c8af4047ef 100644
|
||||
--- a/net/can/gw.c
|
||||
+++ b/net/can/gw.c
|
||||
@@ -442,7 +442,7 @@ static inline int cgw_register_filter(struct cgw_job *gwj)
|
||||
{
|
||||
return can_rx_register(gwj->src.dev, gwj->ccgw.filter.can_id,
|
||||
gwj->ccgw.filter.can_mask, can_can_gw_rcv,
|
||||
- gwj, "gw");
|
||||
+ gwj, "gw", NULL);
|
||||
}
|
||||
|
||||
static inline void cgw_unregister_filter(struct cgw_job *gwj)
|
||||
diff --git a/net/can/raw.c b/net/can/raw.c
|
||||
index 56af689ca999..e9403a26a1d5 100644
|
||||
--- a/net/can/raw.c
|
||||
+++ b/net/can/raw.c
|
||||
@@ -190,7 +190,7 @@ static int raw_enable_filters(struct net_device *dev, struct sock *sk,
|
||||
for (i = 0; i < count; i++) {
|
||||
err = can_rx_register(dev, filter[i].can_id,
|
||||
filter[i].can_mask,
|
||||
- raw_rcv, sk, "raw");
|
||||
+ raw_rcv, sk, "raw", sk);
|
||||
if (err) {
|
||||
/* clean up successfully registered filters */
|
||||
while (--i >= 0)
|
||||
@@ -211,7 +211,7 @@ static int raw_enable_errfilter(struct net_device *dev, struct sock *sk,
|
||||
|
||||
if (err_mask)
|
||||
err = can_rx_register(dev, 0, err_mask | CAN_ERR_FLAG,
|
||||
- raw_rcv, sk, "raw");
|
||||
+ raw_rcv, sk, "raw", sk);
|
||||
|
||||
return err;
|
||||
}
|
||||
diff --git a/net/core/dev.c b/net/core/dev.c
|
||||
index 0798a0f1b395..08215a85c742 100644
|
||||
--- a/net/core/dev.c
|
||||
+++ b/net/core/dev.c
|
||||
@@ -1676,24 +1676,19 @@ EXPORT_SYMBOL_GPL(net_dec_ingress_queue);
|
||||
|
||||
static struct static_key netstamp_needed __read_mostly;
|
||||
#ifdef HAVE_JUMP_LABEL
|
||||
-/* We are not allowed to call static_key_slow_dec() from irq context
|
||||
- * If net_disable_timestamp() is called from irq context, defer the
|
||||
- * static_key_slow_dec() calls.
|
||||
- */
|
||||
static atomic_t netstamp_needed_deferred;
|
||||
-#endif
|
||||
-
|
||||
-void net_enable_timestamp(void)
|
||||
+static void netstamp_clear(struct work_struct *work)
|
||||
{
|
||||
-#ifdef HAVE_JUMP_LABEL
|
||||
int deferred = atomic_xchg(&netstamp_needed_deferred, 0);
|
||||
|
||||
- if (deferred) {
|
||||
- while (--deferred)
|
||||
- static_key_slow_dec(&netstamp_needed);
|
||||
- return;
|
||||
- }
|
||||
+ while (deferred--)
|
||||
+ static_key_slow_dec(&netstamp_needed);
|
||||
+}
|
||||
+static DECLARE_WORK(netstamp_work, netstamp_clear);
|
||||
#endif
|
||||
+
|
||||
+void net_enable_timestamp(void)
|
||||
+{
|
||||
static_key_slow_inc(&netstamp_needed);
|
||||
}
|
||||
EXPORT_SYMBOL(net_enable_timestamp);
|
||||
@@ -1701,12 +1696,12 @@ EXPORT_SYMBOL(net_enable_timestamp);
|
||||
void net_disable_timestamp(void)
|
||||
{
|
||||
#ifdef HAVE_JUMP_LABEL
|
||||
- if (in_interrupt()) {
|
||||
- atomic_inc(&netstamp_needed_deferred);
|
||||
- return;
|
||||
- }
|
||||
-#endif
|
||||
+ /* net_disable_timestamp() can be called from non process context */
|
||||
+ atomic_inc(&netstamp_needed_deferred);
|
||||
+ schedule_work(&netstamp_work);
|
||||
+#else
|
||||
static_key_slow_dec(&netstamp_needed);
|
||||
+#endif
|
||||
}
|
||||
EXPORT_SYMBOL(net_disable_timestamp);
|
||||
|
||||
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
|
||||
index de85d4e1cf43..52dcd414c2af 100644
|
||||
--- a/net/ethernet/eth.c
|
||||
+++ b/net/ethernet/eth.c
|
||||
@@ -353,6 +353,7 @@ void ether_setup(struct net_device *dev)
|
||||
dev->header_ops = ð_header_ops;
|
||||
dev->type = ARPHRD_ETHER;
|
||||
dev->hard_header_len = ETH_HLEN;
|
||||
+ dev->min_header_len = ETH_HLEN;
|
||||
dev->mtu = ETH_DATA_LEN;
|
||||
dev->addr_len = ETH_ALEN;
|
||||
dev->tx_queue_len = 1000; /* Ethernet wants good queues */
|
||||
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
|
||||
index bdb2a07ec363..6cc3e1d602fb 100644
|
||||
--- a/net/ipv4/cipso_ipv4.c
|
||||
+++ b/net/ipv4/cipso_ipv4.c
|
||||
@@ -1657,6 +1657,10 @@ int cipso_v4_validate(const struct sk_buff *skb, unsigned char **option)
|
||||
goto validate_return_locked;
|
||||
}
|
||||
|
||||
+ if (opt_iter + 1 == opt_len) {
|
||||
+ err_offset = opt_iter;
|
||||
+ goto validate_return_locked;
|
||||
+ }
|
||||
tag_len = tag[1];
|
||||
if (tag_len > (opt_len - opt_iter)) {
|
||||
err_offset = opt_iter + 1;
|
||||
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
|
||||
index 9ce202549e7a..bc14c5bb124b 100644
|
||||
--- a/net/ipv4/ip_sockglue.c
|
||||
+++ b/net/ipv4/ip_sockglue.c
|
||||
@@ -1192,7 +1192,14 @@ void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb)
|
||||
pktinfo->ipi_ifindex = 0;
|
||||
pktinfo->ipi_spec_dst.s_addr = 0;
|
||||
}
|
||||
- skb_dst_drop(skb);
|
||||
+ /* We need to keep the dst for __ip_options_echo()
|
||||
+ * We could restrict the test to opt.ts_needtime || opt.srr,
|
||||
+ * but the following is good enough as IP options are not often used.
|
||||
+ */
|
||||
+ if (unlikely(IPCB(skb)->opt.optlen))
|
||||
+ skb_dst_force(skb);
|
||||
+ else
|
||||
+ skb_dst_drop(skb);
|
||||
}
|
||||
|
||||
int ip_setsockopt(struct sock *sk, int level,
|
||||
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
|
||||
index 23160d2b3f71..3a00512addbc 100644
|
||||
--- a/net/ipv4/ping.c
|
||||
+++ b/net/ipv4/ping.c
|
||||
@@ -645,6 +645,8 @@ static int ping_v4_push_pending_frames(struct sock *sk, struct pingfakehdr *pfh,
|
||||
{
|
||||
struct sk_buff *skb = skb_peek(&sk->sk_write_queue);
|
||||
|
||||
+ if (!skb)
|
||||
+ return 0;
|
||||
pfh->wcheck = csum_partial((char *)&pfh->icmph,
|
||||
sizeof(struct icmphdr), pfh->wcheck);
|
||||
pfh->icmph.checksum = csum_fold(pfh->wcheck);
|
||||
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
|
||||
index 69daa81736f6..600dcda840d1 100644
|
||||
--- a/net/ipv4/tcp.c
|
||||
+++ b/net/ipv4/tcp.c
|
||||
@@ -783,6 +783,12 @@ ssize_t tcp_splice_read(struct socket *sock, loff_t *ppos,
|
||||
ret = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
+ /* if __tcp_splice_read() got nothing while we have
|
||||
+ * an skb in receive queue, we do not want to loop.
|
||||
+ * This might happen with URG data.
|
||||
+ */
|
||||
+ if (!skb_queue_empty(&sk->sk_receive_queue))
|
||||
+ break;
|
||||
sk_wait_data(sk, &timeo, NULL);
|
||||
if (signal_pending(current)) {
|
||||
ret = sock_intr_errno(timeo);
|
||||
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
|
||||
index 0795647e94c6..de95714d021c 100644
|
||||
--- a/net/ipv4/tcp_output.c
|
||||
+++ b/net/ipv4/tcp_output.c
|
||||
@@ -2383,9 +2383,11 @@ u32 __tcp_select_window(struct sock *sk)
|
||||
int full_space = min_t(int, tp->window_clamp, allowed_space);
|
||||
int window;
|
||||
|
||||
- if (mss > full_space)
|
||||
+ if (unlikely(mss > full_space)) {
|
||||
mss = full_space;
|
||||
-
|
||||
+ if (mss <= 0)
|
||||
+ return 0;
|
||||
+ }
|
||||
if (free_space < (full_space >> 1)) {
|
||||
icsk->icsk_ack.quick = 0;
|
||||
|
||||
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
|
||||
index 17430f341073..e89135828c3d 100644
|
||||
--- a/net/ipv6/ip6_gre.c
|
||||
+++ b/net/ipv6/ip6_gre.c
|
||||
@@ -55,6 +55,7 @@
|
||||
#include <net/ip6_fib.h>
|
||||
#include <net/ip6_route.h>
|
||||
#include <net/ip6_tunnel.h>
|
||||
+#include <net/gre.h>
|
||||
|
||||
|
||||
static bool log_ecn_error = true;
|
||||
@@ -367,35 +368,37 @@ static void ip6gre_tunnel_uninit(struct net_device *dev)
|
||||
|
||||
|
||||
static void ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
|
||||
- u8 type, u8 code, int offset, __be32 info)
|
||||
+ u8 type, u8 code, int offset, __be32 info)
|
||||
{
|
||||
- const struct ipv6hdr *ipv6h = (const struct ipv6hdr *)skb->data;
|
||||
- __be16 *p = (__be16 *)(skb->data + offset);
|
||||
- int grehlen = offset + 4;
|
||||
+ const struct gre_base_hdr *greh;
|
||||
+ const struct ipv6hdr *ipv6h;
|
||||
+ int grehlen = sizeof(*greh);
|
||||
struct ip6_tnl *t;
|
||||
+ int key_off = 0;
|
||||
__be16 flags;
|
||||
+ __be32 key;
|
||||
|
||||
- flags = p[0];
|
||||
- if (flags&(GRE_CSUM|GRE_KEY|GRE_SEQ|GRE_ROUTING|GRE_VERSION)) {
|
||||
- if (flags&(GRE_VERSION|GRE_ROUTING))
|
||||
- return;
|
||||
- if (flags&GRE_KEY) {
|
||||
- grehlen += 4;
|
||||
- if (flags&GRE_CSUM)
|
||||
- grehlen += 4;
|
||||
- }
|
||||
+ if (!pskb_may_pull(skb, offset + grehlen))
|
||||
+ return;
|
||||
+ greh = (const struct gre_base_hdr *)(skb->data + offset);
|
||||
+ flags = greh->flags;
|
||||
+ if (flags & (GRE_VERSION | GRE_ROUTING))
|
||||
+ return;
|
||||
+ if (flags & GRE_CSUM)
|
||||
+ grehlen += 4;
|
||||
+ if (flags & GRE_KEY) {
|
||||
+ key_off = grehlen + offset;
|
||||
+ grehlen += 4;
|
||||
}
|
||||
|
||||
- /* If only 8 bytes returned, keyed message will be dropped here */
|
||||
- if (!pskb_may_pull(skb, grehlen))
|
||||
+ if (!pskb_may_pull(skb, offset + grehlen))
|
||||
return;
|
||||
ipv6h = (const struct ipv6hdr *)skb->data;
|
||||
- p = (__be16 *)(skb->data + offset);
|
||||
+ greh = (const struct gre_base_hdr *)(skb->data + offset);
|
||||
+ key = key_off ? *(__be32 *)(skb->data + key_off) : 0;
|
||||
|
||||
t = ip6gre_tunnel_lookup(skb->dev, &ipv6h->daddr, &ipv6h->saddr,
|
||||
- flags & GRE_KEY ?
|
||||
- *(((__be32 *)p) + (grehlen / 4) - 1) : 0,
|
||||
- p[1]);
|
||||
+ key, greh->protocol);
|
||||
if (!t)
|
||||
return;
|
||||
|
||||
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
|
||||
index 2994d1f1a661..6c6161763c2f 100644
|
||||
--- a/net/ipv6/ip6_tunnel.c
|
||||
+++ b/net/ipv6/ip6_tunnel.c
|
||||
@@ -479,18 +479,19 @@ ip6_tnl_dev_uninit(struct net_device *dev)
|
||||
|
||||
__u16 ip6_tnl_parse_tlv_enc_lim(struct sk_buff *skb, __u8 *raw)
|
||||
{
|
||||
- const struct ipv6hdr *ipv6h = (const struct ipv6hdr *) raw;
|
||||
- __u8 nexthdr = ipv6h->nexthdr;
|
||||
- __u16 off = sizeof(*ipv6h);
|
||||
+ const struct ipv6hdr *ipv6h = (const struct ipv6hdr *)raw;
|
||||
+ unsigned int nhoff = raw - skb->data;
|
||||
+ unsigned int off = nhoff + sizeof(*ipv6h);
|
||||
+ u8 next, nexthdr = ipv6h->nexthdr;
|
||||
|
||||
while (ipv6_ext_hdr(nexthdr) && nexthdr != NEXTHDR_NONE) {
|
||||
- __u16 optlen = 0;
|
||||
struct ipv6_opt_hdr *hdr;
|
||||
- if (raw + off + sizeof(*hdr) > skb->data &&
|
||||
- !pskb_may_pull(skb, raw - skb->data + off + sizeof (*hdr)))
|
||||
+ u16 optlen;
|
||||
+
|
||||
+ if (!pskb_may_pull(skb, off + sizeof(*hdr)))
|
||||
break;
|
||||
|
||||
- hdr = (struct ipv6_opt_hdr *) (raw + off);
|
||||
+ hdr = (struct ipv6_opt_hdr *)(skb->data + off);
|
||||
if (nexthdr == NEXTHDR_FRAGMENT) {
|
||||
struct frag_hdr *frag_hdr = (struct frag_hdr *) hdr;
|
||||
if (frag_hdr->frag_off)
|
||||
@@ -501,20 +502,29 @@ __u16 ip6_tnl_parse_tlv_enc_lim(struct sk_buff *skb, __u8 *raw)
|
||||
} else {
|
||||
optlen = ipv6_optlen(hdr);
|
||||
}
|
||||
+ /* cache hdr->nexthdr, since pskb_may_pull() might
|
||||
+ * invalidate hdr
|
||||
+ */
|
||||
+ next = hdr->nexthdr;
|
||||
if (nexthdr == NEXTHDR_DEST) {
|
||||
- __u16 i = off + 2;
|
||||
+ u16 i = 2;
|
||||
+
|
||||
+ /* Remember : hdr is no longer valid at this point. */
|
||||
+ if (!pskb_may_pull(skb, off + optlen))
|
||||
+ break;
|
||||
+
|
||||
while (1) {
|
||||
struct ipv6_tlv_tnl_enc_lim *tel;
|
||||
|
||||
/* No more room for encapsulation limit */
|
||||
- if (i + sizeof (*tel) > off + optlen)
|
||||
+ if (i + sizeof(*tel) > optlen)
|
||||
break;
|
||||
|
||||
- tel = (struct ipv6_tlv_tnl_enc_lim *) &raw[i];
|
||||
+ tel = (struct ipv6_tlv_tnl_enc_lim *)(skb->data + off + i);
|
||||
/* return index of option if found and valid */
|
||||
if (tel->type == IPV6_TLV_TNL_ENCAP_LIMIT &&
|
||||
tel->length == 1)
|
||||
- return i;
|
||||
+ return i + off - nhoff;
|
||||
/* else jump to next option */
|
||||
if (tel->type)
|
||||
i += tel->length + 2;
|
||||
@@ -522,7 +532,7 @@ __u16 ip6_tnl_parse_tlv_enc_lim(struct sk_buff *skb, __u8 *raw)
|
||||
i++;
|
||||
}
|
||||
}
|
||||
- nexthdr = hdr->nexthdr;
|
||||
+ nexthdr = next;
|
||||
off += optlen;
|
||||
}
|
||||
return 0;
|
||||
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
|
||||
index 3da2b16356eb..184f0fe35dc6 100644
|
||||
--- a/net/ipv6/sit.c
|
||||
+++ b/net/ipv6/sit.c
|
||||
@@ -1389,6 +1389,7 @@ static int ipip6_tunnel_init(struct net_device *dev)
|
||||
tunnel->dst_cache = alloc_percpu(struct ip_tunnel_dst);
|
||||
if (!tunnel->dst_cache) {
|
||||
free_percpu(dev->tstats);
|
||||
+ dev->tstats = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
|
||||
index 5f581616bf6a..76a8c8057a23 100644
|
||||
--- a/net/ipv6/tcp_ipv6.c
|
||||
+++ b/net/ipv6/tcp_ipv6.c
|
||||
@@ -974,6 +974,16 @@ drop:
|
||||
return 0; /* don't send reset */
|
||||
}
|
||||
|
||||
+static void tcp_v6_restore_cb(struct sk_buff *skb)
|
||||
+{
|
||||
+ /* We need to move header back to the beginning if xfrm6_policy_check()
|
||||
+ * and tcp_v6_fill_cb() are going to be called again.
|
||||
+ * ip6_datagram_recv_specific_ctl() also expects IP6CB to be there.
|
||||
+ */
|
||||
+ memmove(IP6CB(skb), &TCP_SKB_CB(skb)->header.h6,
|
||||
+ sizeof(struct inet6_skb_parm));
|
||||
+}
|
||||
+
|
||||
static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
|
||||
struct request_sock *req,
|
||||
struct dst_entry *dst,
|
||||
@@ -1163,8 +1173,10 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
|
||||
sk_gfp_atomic(sk, GFP_ATOMIC));
|
||||
consume_skb(ireq->pktopts);
|
||||
ireq->pktopts = NULL;
|
||||
- if (newnp->pktoptions)
|
||||
+ if (newnp->pktoptions) {
|
||||
+ tcp_v6_restore_cb(newnp->pktoptions);
|
||||
skb_set_owner_r(newnp->pktoptions, newsk);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1179,16 +1191,6 @@ out:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-static void tcp_v6_restore_cb(struct sk_buff *skb)
|
||||
-{
|
||||
- /* We need to move header back to the beginning if xfrm6_policy_check()
|
||||
- * and tcp_v6_fill_cb() are going to be called again.
|
||||
- * ip6_datagram_recv_specific_ctl() also expects IP6CB to be there.
|
||||
- */
|
||||
- memmove(IP6CB(skb), &TCP_SKB_CB(skb)->header.h6,
|
||||
- sizeof(struct inet6_skb_parm));
|
||||
-}
|
||||
-
|
||||
/* The socket must have it's spinlock held when we get
|
||||
* here, unless it is a TCP_LISTEN socket.
|
||||
*
|
||||
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h
|
||||
index 5871537af387..763e8e241ce3 100644
|
||||
--- a/net/l2tp/l2tp_core.h
|
||||
+++ b/net/l2tp/l2tp_core.h
|
||||
@@ -273,6 +273,7 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb,
|
||||
int l2tp_nl_register_ops(enum l2tp_pwtype pw_type,
|
||||
const struct l2tp_nl_cmd_ops *ops);
|
||||
void l2tp_nl_unregister_ops(enum l2tp_pwtype pw_type);
|
||||
+int l2tp_ioctl(struct sock *sk, int cmd, unsigned long arg);
|
||||
|
||||
/* Session reference counts. Incremented when code obtains a reference
|
||||
* to a session.
|
||||
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c
|
||||
index d0e906d39642..445b7cd0826a 100644
|
||||
--- a/net/l2tp/l2tp_ip.c
|
||||
+++ b/net/l2tp/l2tp_ip.c
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
+#include <asm/ioctls.h>
|
||||
#include <linux/icmp.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
@@ -555,6 +556,30 @@ out:
|
||||
return err ? err : copied;
|
||||
}
|
||||
|
||||
+int l2tp_ioctl(struct sock *sk, int cmd, unsigned long arg)
|
||||
+{
|
||||
+ struct sk_buff *skb;
|
||||
+ int amount;
|
||||
+
|
||||
+ switch (cmd) {
|
||||
+ case SIOCOUTQ:
|
||||
+ amount = sk_wmem_alloc_get(sk);
|
||||
+ break;
|
||||
+ case SIOCINQ:
|
||||
+ spin_lock_bh(&sk->sk_receive_queue.lock);
|
||||
+ skb = skb_peek(&sk->sk_receive_queue);
|
||||
+ amount = skb ? skb->len : 0;
|
||||
+ spin_unlock_bh(&sk->sk_receive_queue.lock);
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ return -ENOIOCTLCMD;
|
||||
+ }
|
||||
+
|
||||
+ return put_user(amount, (int __user *)arg);
|
||||
+}
|
||||
+EXPORT_SYMBOL(l2tp_ioctl);
|
||||
+
|
||||
static struct proto l2tp_ip_prot = {
|
||||
.name = "L2TP/IP",
|
||||
.owner = THIS_MODULE,
|
||||
@@ -563,7 +588,7 @@ static struct proto l2tp_ip_prot = {
|
||||
.bind = l2tp_ip_bind,
|
||||
.connect = l2tp_ip_connect,
|
||||
.disconnect = l2tp_ip_disconnect,
|
||||
- .ioctl = udp_ioctl,
|
||||
+ .ioctl = l2tp_ioctl,
|
||||
.destroy = l2tp_ip_destroy_sock,
|
||||
.setsockopt = ip_setsockopt,
|
||||
.getsockopt = ip_getsockopt,
|
||||
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
|
||||
index 3c4f867d3633..bcdab1cba773 100644
|
||||
--- a/net/l2tp/l2tp_ip6.c
|
||||
+++ b/net/l2tp/l2tp_ip6.c
|
||||
@@ -714,7 +714,7 @@ static struct proto l2tp_ip6_prot = {
|
||||
.bind = l2tp_ip6_bind,
|
||||
.connect = l2tp_ip6_connect,
|
||||
.disconnect = l2tp_ip6_disconnect,
|
||||
- .ioctl = udp_ioctl,
|
||||
+ .ioctl = l2tp_ioctl,
|
||||
.destroy = l2tp_ip6_destroy_sock,
|
||||
.setsockopt = ipv6_setsockopt,
|
||||
.getsockopt = ipv6_getsockopt,
|
||||
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
|
||||
index f223d1c80ccf..f2d28ed74a0a 100644
|
||||
--- a/net/packet/af_packet.c
|
||||
+++ b/net/packet/af_packet.c
|
||||
@@ -2637,7 +2637,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
|
||||
int vnet_hdr_len;
|
||||
struct packet_sock *po = pkt_sk(sk);
|
||||
unsigned short gso_type = 0;
|
||||
- int hlen, tlen;
|
||||
+ int hlen, tlen, linear;
|
||||
int extra_len = 0;
|
||||
ssize_t n;
|
||||
|
||||
@@ -2741,8 +2741,9 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
|
||||
err = -ENOBUFS;
|
||||
hlen = LL_RESERVED_SPACE(dev);
|
||||
tlen = dev->needed_tailroom;
|
||||
- skb = packet_alloc_skb(sk, hlen + tlen, hlen, len,
|
||||
- __virtio16_to_cpu(vio_le(), vnet_hdr.hdr_len),
|
||||
+ linear = __virtio16_to_cpu(vio_le(), vnet_hdr.hdr_len);
|
||||
+ linear = max(linear, min_t(int, len, dev->hard_header_len));
|
||||
+ skb = packet_alloc_skb(sk, hlen + tlen, hlen, len, linear,
|
||||
msg->msg_flags & MSG_DONTWAIT, &err);
|
||||
if (skb == NULL)
|
||||
goto out_unlock;
|
||||
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
|
||||
index b5fd4ab56156..138f2d667212 100644
|
||||
--- a/net/sctp/socket.c
|
||||
+++ b/net/sctp/socket.c
|
||||
@@ -6960,7 +6960,8 @@ static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p,
|
||||
*/
|
||||
release_sock(sk);
|
||||
current_timeo = schedule_timeout(current_timeo);
|
||||
- BUG_ON(sk != asoc->base.sk);
|
||||
+ if (sk != asoc->base.sk)
|
||||
+ goto do_error;
|
||||
lock_sock(sk);
|
||||
|
||||
*timeo_p = current_timeo;
|
||||
369
patch/kernel/s5p6818-default/03-patch-4.4.50-51.patch
Normal file
369
patch/kernel/s5p6818-default/03-patch-4.4.50-51.patch
Normal file
@ -0,0 +1,369 @@
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 10993715abb8..117357188f01 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 4
|
||||
-SUBLEVEL = 50
|
||||
+SUBLEVEL = 51
|
||||
EXTRAVERSION =
|
||||
NAME = Blurry Fish Butt
|
||||
|
||||
diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S
|
||||
index 8ecfd15c3a02..df73914e81c8 100644
|
||||
--- a/arch/arm/lib/getuser.S
|
||||
+++ b/arch/arm/lib/getuser.S
|
||||
@@ -67,7 +67,7 @@ ENTRY(__get_user_4)
|
||||
ENDPROC(__get_user_4)
|
||||
|
||||
ENTRY(__get_user_8)
|
||||
- check_uaccess r0, 8, r1, r2, __get_user_bad
|
||||
+ check_uaccess r0, 8, r1, r2, __get_user_bad8
|
||||
#ifdef CONFIG_THUMB2_KERNEL
|
||||
5: TUSER(ldr) r2, [r0]
|
||||
6: TUSER(ldr) r3, [r0, #4]
|
||||
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
|
||||
index 7cb2815e815e..a3b96d691ac9 100644
|
||||
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
|
||||
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
|
||||
@@ -1812,7 +1812,7 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
|
||||
mgr->payloads[i].num_slots = req_payload.num_slots;
|
||||
} else if (mgr->payloads[i].num_slots) {
|
||||
mgr->payloads[i].num_slots = 0;
|
||||
- drm_dp_destroy_payload_step1(mgr, port, port->vcpi.vcpi, &mgr->payloads[i]);
|
||||
+ drm_dp_destroy_payload_step1(mgr, port, mgr->payloads[i].vcpi, &mgr->payloads[i]);
|
||||
req_payload.payload_state = mgr->payloads[i].payload_state;
|
||||
mgr->payloads[i].start_slot = 0;
|
||||
}
|
||||
diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c
|
||||
index 04cec0da5d1e..8901228b5d5d 100644
|
||||
--- a/drivers/gpu/drm/radeon/radeon_cursor.c
|
||||
+++ b/drivers/gpu/drm/radeon/radeon_cursor.c
|
||||
@@ -205,8 +205,8 @@ static int radeon_cursor_move_locked(struct drm_crtc *crtc, int x, int y)
|
||||
}
|
||||
|
||||
if (x <= (crtc->x - w) || y <= (crtc->y - radeon_crtc->cursor_height) ||
|
||||
- x >= (crtc->x + crtc->mode.crtc_hdisplay) ||
|
||||
- y >= (crtc->y + crtc->mode.crtc_vdisplay))
|
||||
+ x >= (crtc->x + crtc->mode.hdisplay) ||
|
||||
+ y >= (crtc->y + crtc->mode.vdisplay))
|
||||
goto out_of_bounds;
|
||||
|
||||
x += xorigin;
|
||||
diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c
|
||||
index d15b33813021..ed1935f300a7 100644
|
||||
--- a/drivers/input/mouse/elan_i2c_core.c
|
||||
+++ b/drivers/input/mouse/elan_i2c_core.c
|
||||
@@ -1232,6 +1232,7 @@ static const struct acpi_device_id elan_acpi_id[] = {
|
||||
{ "ELAN0000", 0 },
|
||||
{ "ELAN0100", 0 },
|
||||
{ "ELAN0600", 0 },
|
||||
+ { "ELAN0605", 0 },
|
||||
{ "ELAN1000", 0 },
|
||||
{ }
|
||||
};
|
||||
diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
|
||||
index 6b420a55c745..c3ea03c9a1a8 100644
|
||||
--- a/drivers/md/bcache/bcache.h
|
||||
+++ b/drivers/md/bcache/bcache.h
|
||||
@@ -425,7 +425,7 @@ struct cache {
|
||||
* until a gc finishes - otherwise we could pointlessly burn a ton of
|
||||
* cpu
|
||||
*/
|
||||
- unsigned invalidate_needs_gc:1;
|
||||
+ unsigned invalidate_needs_gc;
|
||||
|
||||
bool discard; /* Get rid of? */
|
||||
|
||||
@@ -593,8 +593,8 @@ struct cache_set {
|
||||
|
||||
/* Counts how many sectors bio_insert has added to the cache */
|
||||
atomic_t sectors_to_gc;
|
||||
+ wait_queue_head_t gc_wait;
|
||||
|
||||
- wait_queue_head_t moving_gc_wait;
|
||||
struct keybuf moving_gc_keys;
|
||||
/* Number of moving GC bios in flight */
|
||||
struct semaphore moving_in_flight;
|
||||
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c
|
||||
index 22b9e34ceb75..5b815e64c1c9 100644
|
||||
--- a/drivers/md/bcache/btree.c
|
||||
+++ b/drivers/md/bcache/btree.c
|
||||
@@ -1762,33 +1762,34 @@ static void bch_btree_gc(struct cache_set *c)
|
||||
bch_moving_gc(c);
|
||||
}
|
||||
|
||||
-static int bch_gc_thread(void *arg)
|
||||
+static bool gc_should_run(struct cache_set *c)
|
||||
{
|
||||
- struct cache_set *c = arg;
|
||||
struct cache *ca;
|
||||
unsigned i;
|
||||
|
||||
- while (1) {
|
||||
-again:
|
||||
- bch_btree_gc(c);
|
||||
+ for_each_cache(ca, c, i)
|
||||
+ if (ca->invalidate_needs_gc)
|
||||
+ return true;
|
||||
|
||||
- set_current_state(TASK_INTERRUPTIBLE);
|
||||
- if (kthread_should_stop())
|
||||
- break;
|
||||
+ if (atomic_read(&c->sectors_to_gc) < 0)
|
||||
+ return true;
|
||||
|
||||
- mutex_lock(&c->bucket_lock);
|
||||
+ return false;
|
||||
+}
|
||||
|
||||
- for_each_cache(ca, c, i)
|
||||
- if (ca->invalidate_needs_gc) {
|
||||
- mutex_unlock(&c->bucket_lock);
|
||||
- set_current_state(TASK_RUNNING);
|
||||
- goto again;
|
||||
- }
|
||||
+static int bch_gc_thread(void *arg)
|
||||
+{
|
||||
+ struct cache_set *c = arg;
|
||||
|
||||
- mutex_unlock(&c->bucket_lock);
|
||||
+ while (1) {
|
||||
+ wait_event_interruptible(c->gc_wait,
|
||||
+ kthread_should_stop() || gc_should_run(c));
|
||||
|
||||
- try_to_freeze();
|
||||
- schedule();
|
||||
+ if (kthread_should_stop())
|
||||
+ break;
|
||||
+
|
||||
+ set_gc_sectors(c);
|
||||
+ bch_btree_gc(c);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1796,11 +1797,10 @@ again:
|
||||
|
||||
int bch_gc_thread_start(struct cache_set *c)
|
||||
{
|
||||
- c->gc_thread = kthread_create(bch_gc_thread, c, "bcache_gc");
|
||||
+ c->gc_thread = kthread_run(bch_gc_thread, c, "bcache_gc");
|
||||
if (IS_ERR(c->gc_thread))
|
||||
return PTR_ERR(c->gc_thread);
|
||||
|
||||
- set_task_state(c->gc_thread, TASK_INTERRUPTIBLE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/drivers/md/bcache/btree.h b/drivers/md/bcache/btree.h
|
||||
index 5c391fa01bed..9b80417cd547 100644
|
||||
--- a/drivers/md/bcache/btree.h
|
||||
+++ b/drivers/md/bcache/btree.h
|
||||
@@ -260,8 +260,7 @@ void bch_initial_mark_key(struct cache_set *, int, struct bkey *);
|
||||
|
||||
static inline void wake_up_gc(struct cache_set *c)
|
||||
{
|
||||
- if (c->gc_thread)
|
||||
- wake_up_process(c->gc_thread);
|
||||
+ wake_up(&c->gc_wait);
|
||||
}
|
||||
|
||||
#define MAP_DONE 0
|
||||
diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c
|
||||
index 25fa8445bb24..2410df1c2a05 100644
|
||||
--- a/drivers/md/bcache/request.c
|
||||
+++ b/drivers/md/bcache/request.c
|
||||
@@ -196,10 +196,8 @@ static void bch_data_insert_start(struct closure *cl)
|
||||
struct data_insert_op *op = container_of(cl, struct data_insert_op, cl);
|
||||
struct bio *bio = op->bio, *n;
|
||||
|
||||
- if (atomic_sub_return(bio_sectors(bio), &op->c->sectors_to_gc) < 0) {
|
||||
- set_gc_sectors(op->c);
|
||||
+ if (atomic_sub_return(bio_sectors(bio), &op->c->sectors_to_gc) < 0)
|
||||
wake_up_gc(op->c);
|
||||
- }
|
||||
|
||||
if (op->bypass)
|
||||
return bch_data_invalidate(cl);
|
||||
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
|
||||
index 3d5c0ba13181..7b5880b8874c 100644
|
||||
--- a/drivers/md/bcache/super.c
|
||||
+++ b/drivers/md/bcache/super.c
|
||||
@@ -1489,6 +1489,7 @@ struct cache_set *bch_cache_set_alloc(struct cache_sb *sb)
|
||||
mutex_init(&c->bucket_lock);
|
||||
init_waitqueue_head(&c->btree_cache_wait);
|
||||
init_waitqueue_head(&c->bucket_wait);
|
||||
+ init_waitqueue_head(&c->gc_wait);
|
||||
sema_init(&c->uuid_write_mutex, 1);
|
||||
|
||||
spin_lock_init(&c->btree_gc_time.lock);
|
||||
@@ -1547,6 +1548,7 @@ static void run_cache_set(struct cache_set *c)
|
||||
|
||||
for_each_cache(ca, c, i)
|
||||
c->nbuckets += ca->sb.nbuckets;
|
||||
+ set_gc_sectors(c);
|
||||
|
||||
if (CACHE_SYNC(&c->sb)) {
|
||||
LIST_HEAD(journal);
|
||||
diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c
|
||||
index c945e4c2fbd4..ec30a004f319 100644
|
||||
--- a/drivers/media/usb/siano/smsusb.c
|
||||
+++ b/drivers/media/usb/siano/smsusb.c
|
||||
@@ -200,22 +200,30 @@ static int smsusb_start_streaming(struct smsusb_device_t *dev)
|
||||
static int smsusb_sendrequest(void *context, void *buffer, size_t size)
|
||||
{
|
||||
struct smsusb_device_t *dev = (struct smsusb_device_t *) context;
|
||||
- struct sms_msg_hdr *phdr = (struct sms_msg_hdr *) buffer;
|
||||
- int dummy;
|
||||
+ struct sms_msg_hdr *phdr;
|
||||
+ int dummy, ret;
|
||||
|
||||
if (dev->state != SMSUSB_ACTIVE) {
|
||||
pr_debug("Device not active yet\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
+ phdr = kmalloc(size, GFP_KERNEL);
|
||||
+ if (!phdr)
|
||||
+ return -ENOMEM;
|
||||
+ memcpy(phdr, buffer, size);
|
||||
+
|
||||
pr_debug("sending %s(%d) size: %d\n",
|
||||
smscore_translate_msg(phdr->msg_type), phdr->msg_type,
|
||||
phdr->msg_length);
|
||||
|
||||
smsendian_handle_tx_message((struct sms_msg_data *) phdr);
|
||||
- smsendian_handle_message_header((struct sms_msg_hdr *)buffer);
|
||||
- return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2),
|
||||
- buffer, size, &dummy, 1000);
|
||||
+ smsendian_handle_message_header((struct sms_msg_hdr *)phdr);
|
||||
+ ret = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2),
|
||||
+ phdr, size, &dummy, 1000);
|
||||
+
|
||||
+ kfree(phdr);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static char *smsusb1_fw_lkup[] = {
|
||||
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
|
||||
index 78187699467a..79a0c26e1419 100644
|
||||
--- a/drivers/mmc/core/mmc.c
|
||||
+++ b/drivers/mmc/core/mmc.c
|
||||
@@ -1581,10 +1581,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
|
||||
err = mmc_select_hs400(card);
|
||||
if (err)
|
||||
goto free_card;
|
||||
- } else if (mmc_card_hs(card)) {
|
||||
+ } else {
|
||||
/* Select the desired bus width optionally */
|
||||
err = mmc_select_bus_width(card);
|
||||
- if (!IS_ERR_VALUE(err)) {
|
||||
+ if (!IS_ERR_VALUE(err) && mmc_card_hs(card)) {
|
||||
err = mmc_select_hs_ddr(card);
|
||||
if (err)
|
||||
goto free_card;
|
||||
diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c
|
||||
index 60654d524858..ecc6fb9ca92f 100644
|
||||
--- a/drivers/ntb/ntb_transport.c
|
||||
+++ b/drivers/ntb/ntb_transport.c
|
||||
@@ -1623,7 +1623,7 @@ ntb_transport_create_queue(void *data, struct device *client_dev,
|
||||
|
||||
node = dev_to_node(&ndev->dev);
|
||||
|
||||
- free_queue = ffs(nt->qp_bitmap);
|
||||
+ free_queue = ffs(nt->qp_bitmap_free);
|
||||
if (!free_queue)
|
||||
goto err;
|
||||
|
||||
@@ -2082,9 +2082,8 @@ module_init(ntb_transport_init);
|
||||
|
||||
static void __exit ntb_transport_exit(void)
|
||||
{
|
||||
- debugfs_remove_recursive(nt_debugfs_dir);
|
||||
-
|
||||
ntb_unregister_client(&ntb_transport_client);
|
||||
bus_unregister(&ntb_transport_bus);
|
||||
+ debugfs_remove_recursive(nt_debugfs_dir);
|
||||
}
|
||||
module_exit(ntb_transport_exit);
|
||||
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
|
||||
index cf5b99e1f12b..8558e3886960 100644
|
||||
--- a/drivers/scsi/scsi_lib.c
|
||||
+++ b/drivers/scsi/scsi_lib.c
|
||||
@@ -1120,7 +1120,8 @@ int scsi_init_io(struct scsi_cmnd *cmd)
|
||||
bool is_mq = (rq->mq_ctx != NULL);
|
||||
int error;
|
||||
|
||||
- BUG_ON(!rq->nr_phys_segments);
|
||||
+ if (WARN_ON_ONCE(!rq->nr_phys_segments))
|
||||
+ return -EINVAL;
|
||||
|
||||
error = scsi_init_sgtable(rq, &cmd->sdb);
|
||||
if (error)
|
||||
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
|
||||
index a1c29b0afb22..dedcff9cabb5 100644
|
||||
--- a/drivers/scsi/sg.c
|
||||
+++ b/drivers/scsi/sg.c
|
||||
@@ -1763,6 +1763,10 @@ sg_start_req(Sg_request *srp, unsigned char *cmd)
|
||||
return res;
|
||||
|
||||
iov_iter_truncate(&i, hp->dxfer_len);
|
||||
+ if (!iov_iter_count(&i)) {
|
||||
+ kfree(iov);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
|
||||
res = blk_rq_map_user_iov(q, rq, md, &i, GFP_ATOMIC);
|
||||
kfree(iov);
|
||||
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
|
||||
index 9096d44eb221..d0cf1f010fbe 100644
|
||||
--- a/fs/fuse/dev.c
|
||||
+++ b/fs/fuse/dev.c
|
||||
@@ -418,6 +418,10 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
|
||||
static void queue_interrupt(struct fuse_iqueue *fiq, struct fuse_req *req)
|
||||
{
|
||||
spin_lock(&fiq->waitq.lock);
|
||||
+ if (test_bit(FR_FINISHED, &req->flags)) {
|
||||
+ spin_unlock(&fiq->waitq.lock);
|
||||
+ return;
|
||||
+ }
|
||||
if (list_empty(&req->intr_entry)) {
|
||||
list_add_tail(&req->intr_entry, &fiq->interrupts);
|
||||
wake_up_locked(&fiq->waitq);
|
||||
diff --git a/fs/splice.c b/fs/splice.c
|
||||
index 0f77e9682857..8398974e1538 100644
|
||||
--- a/fs/splice.c
|
||||
+++ b/fs/splice.c
|
||||
@@ -211,6 +211,7 @@ ssize_t splice_to_pipe(struct pipe_inode_info *pipe,
|
||||
buf->len = spd->partial[page_nr].len;
|
||||
buf->private = spd->partial[page_nr].private;
|
||||
buf->ops = spd->ops;
|
||||
+ buf->flags = 0;
|
||||
if (spd->flags & SPLICE_F_GIFT)
|
||||
buf->flags |= PIPE_BUF_FLAG_GIFT;
|
||||
|
||||
diff --git a/kernel/futex.c b/kernel/futex.c
|
||||
index 9d8163afd87c..9d251dc3ec40 100644
|
||||
--- a/kernel/futex.c
|
||||
+++ b/kernel/futex.c
|
||||
@@ -3202,5 +3202,5 @@ static int __init futex_init(void)
|
||||
#ifdef CONFIG_FUTEX_INIT_LEVEL_UP
|
||||
fs_initcall(futex_init);
|
||||
#else
|
||||
-__initcall(futex_init);
|
||||
+core_initcall(futex_init);
|
||||
#endif
|
||||
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
|
||||
index c048e34b177f..0b5613554769 100644
|
||||
--- a/kernel/printk/printk.c
|
||||
+++ b/kernel/printk/printk.c
|
||||
@@ -1436,7 +1436,7 @@ static void call_console_drivers(int level,
|
||||
{
|
||||
struct console *con;
|
||||
|
||||
- trace_console(text, len);
|
||||
+ trace_console_rcuidle(text, len);
|
||||
|
||||
if (level >= console_loglevel && !ignore_loglevel)
|
||||
return;
|
||||
817
patch/kernel/s5p6818-default/03-patch-4.4.51-52.patch
Normal file
817
patch/kernel/s5p6818-default/03-patch-4.4.51-52.patch
Normal file
@ -0,0 +1,817 @@
|
||||
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
|
||||
index c360f80c3473..ca64ca566099 100644
|
||||
--- a/Documentation/kernel-parameters.txt
|
||||
+++ b/Documentation/kernel-parameters.txt
|
||||
@@ -1255,6 +1255,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||
When zero, profiling data is discarded and associated
|
||||
debugfs files are removed at module unload time.
|
||||
|
||||
+ goldfish [X86] Enable the goldfish android emulator platform.
|
||||
+ Don't use this when you are not running on the
|
||||
+ android emulator
|
||||
+
|
||||
gpt [EFI] Forces disk with valid GPT signature but
|
||||
invalid Protective MBR to be treated as GPT. If the
|
||||
primary GPT is corrupted, it enables the backup/alternate
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 117357188f01..671e183bd507 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 4
|
||||
-SUBLEVEL = 51
|
||||
+SUBLEVEL = 52
|
||||
EXTRAVERSION =
|
||||
NAME = Blurry Fish Butt
|
||||
|
||||
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
|
||||
index bb620df05d0d..64f60a48def1 100644
|
||||
--- a/arch/x86/kvm/vmx.c
|
||||
+++ b/arch/x86/kvm/vmx.c
|
||||
@@ -4867,6 +4867,12 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
|
||||
if (vmx_xsaves_supported())
|
||||
vmcs_write64(XSS_EXIT_BITMAP, VMX_XSS_EXIT_BITMAP);
|
||||
|
||||
+ if (enable_pml) {
|
||||
+ ASSERT(vmx->pml_pg);
|
||||
+ vmcs_write64(PML_ADDRESS, page_to_phys(vmx->pml_pg));
|
||||
+ vmcs_write16(GUEST_PML_INDEX, PML_ENTITY_NUM - 1);
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -7839,22 +7845,6 @@ static void vmx_get_exit_info(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2)
|
||||
*info2 = vmcs_read32(VM_EXIT_INTR_INFO);
|
||||
}
|
||||
|
||||
-static int vmx_create_pml_buffer(struct vcpu_vmx *vmx)
|
||||
-{
|
||||
- struct page *pml_pg;
|
||||
-
|
||||
- pml_pg = alloc_page(GFP_KERNEL | __GFP_ZERO);
|
||||
- if (!pml_pg)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- vmx->pml_pg = pml_pg;
|
||||
-
|
||||
- vmcs_write64(PML_ADDRESS, page_to_phys(vmx->pml_pg));
|
||||
- vmcs_write16(GUEST_PML_INDEX, PML_ENTITY_NUM - 1);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
static void vmx_destroy_pml_buffer(struct vcpu_vmx *vmx)
|
||||
{
|
||||
if (vmx->pml_pg) {
|
||||
@@ -8789,14 +8779,26 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
|
||||
if (err)
|
||||
goto free_vcpu;
|
||||
|
||||
+ err = -ENOMEM;
|
||||
+
|
||||
+ /*
|
||||
+ * If PML is turned on, failure on enabling PML just results in failure
|
||||
+ * of creating the vcpu, therefore we can simplify PML logic (by
|
||||
+ * avoiding dealing with cases, such as enabling PML partially on vcpus
|
||||
+ * for the guest, etc.
|
||||
+ */
|
||||
+ if (enable_pml) {
|
||||
+ vmx->pml_pg = alloc_page(GFP_KERNEL | __GFP_ZERO);
|
||||
+ if (!vmx->pml_pg)
|
||||
+ goto uninit_vcpu;
|
||||
+ }
|
||||
+
|
||||
vmx->guest_msrs = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
BUILD_BUG_ON(ARRAY_SIZE(vmx_msr_index) * sizeof(vmx->guest_msrs[0])
|
||||
> PAGE_SIZE);
|
||||
|
||||
- err = -ENOMEM;
|
||||
- if (!vmx->guest_msrs) {
|
||||
- goto uninit_vcpu;
|
||||
- }
|
||||
+ if (!vmx->guest_msrs)
|
||||
+ goto free_pml;
|
||||
|
||||
vmx->loaded_vmcs = &vmx->vmcs01;
|
||||
vmx->loaded_vmcs->vmcs = alloc_vmcs();
|
||||
@@ -8840,18 +8842,6 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
|
||||
vmx->nested.current_vmptr = -1ull;
|
||||
vmx->nested.current_vmcs12 = NULL;
|
||||
|
||||
- /*
|
||||
- * If PML is turned on, failure on enabling PML just results in failure
|
||||
- * of creating the vcpu, therefore we can simplify PML logic (by
|
||||
- * avoiding dealing with cases, such as enabling PML partially on vcpus
|
||||
- * for the guest, etc.
|
||||
- */
|
||||
- if (enable_pml) {
|
||||
- err = vmx_create_pml_buffer(vmx);
|
||||
- if (err)
|
||||
- goto free_vmcs;
|
||||
- }
|
||||
-
|
||||
return &vmx->vcpu;
|
||||
|
||||
free_vmcs:
|
||||
@@ -8859,6 +8849,8 @@ free_vmcs:
|
||||
free_loaded_vmcs(vmx->loaded_vmcs);
|
||||
free_msrs:
|
||||
kfree(vmx->guest_msrs);
|
||||
+free_pml:
|
||||
+ vmx_destroy_pml_buffer(vmx);
|
||||
uninit_vcpu:
|
||||
kvm_vcpu_uninit(&vmx->vcpu);
|
||||
free_vcpu:
|
||||
diff --git a/arch/x86/platform/goldfish/goldfish.c b/arch/x86/platform/goldfish/goldfish.c
|
||||
index 1693107a518e..0d17c0aafeb1 100644
|
||||
--- a/arch/x86/platform/goldfish/goldfish.c
|
||||
+++ b/arch/x86/platform/goldfish/goldfish.c
|
||||
@@ -42,10 +42,22 @@ static struct resource goldfish_pdev_bus_resources[] = {
|
||||
}
|
||||
};
|
||||
|
||||
+static bool goldfish_enable __initdata;
|
||||
+
|
||||
+static int __init goldfish_setup(char *str)
|
||||
+{
|
||||
+ goldfish_enable = true;
|
||||
+ return 0;
|
||||
+}
|
||||
+__setup("goldfish", goldfish_setup);
|
||||
+
|
||||
static int __init goldfish_init(void)
|
||||
{
|
||||
+ if (!goldfish_enable)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
platform_device_register_simple("goldfish_pdev_bus", -1,
|
||||
- goldfish_pdev_bus_resources, 2);
|
||||
+ goldfish_pdev_bus_resources, 2);
|
||||
return 0;
|
||||
}
|
||||
device_initcall(goldfish_init);
|
||||
diff --git a/block/blk-mq.c b/block/blk-mq.c
|
||||
index 6cfc6b200366..d8d63c38bf29 100644
|
||||
--- a/block/blk-mq.c
|
||||
+++ b/block/blk-mq.c
|
||||
@@ -1259,12 +1259,9 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio)
|
||||
|
||||
blk_queue_split(q, &bio, q->bio_split);
|
||||
|
||||
- if (!is_flush_fua && !blk_queue_nomerges(q)) {
|
||||
- if (blk_attempt_plug_merge(q, bio, &request_count,
|
||||
- &same_queue_rq))
|
||||
- return BLK_QC_T_NONE;
|
||||
- } else
|
||||
- request_count = blk_plug_queued_count(q);
|
||||
+ if (!is_flush_fua && !blk_queue_nomerges(q) &&
|
||||
+ blk_attempt_plug_merge(q, bio, &request_count, &same_queue_rq))
|
||||
+ return BLK_QC_T_NONE;
|
||||
|
||||
rq = blk_mq_map_request(q, bio, &data);
|
||||
if (unlikely(!rq))
|
||||
@@ -1355,9 +1352,11 @@ static blk_qc_t blk_sq_make_request(struct request_queue *q, struct bio *bio)
|
||||
|
||||
blk_queue_split(q, &bio, q->bio_split);
|
||||
|
||||
- if (!is_flush_fua && !blk_queue_nomerges(q) &&
|
||||
- blk_attempt_plug_merge(q, bio, &request_count, NULL))
|
||||
- return BLK_QC_T_NONE;
|
||||
+ if (!is_flush_fua && !blk_queue_nomerges(q)) {
|
||||
+ if (blk_attempt_plug_merge(q, bio, &request_count, NULL))
|
||||
+ return BLK_QC_T_NONE;
|
||||
+ } else
|
||||
+ request_count = blk_plug_queued_count(q);
|
||||
|
||||
rq = blk_mq_map_request(q, bio, &data);
|
||||
if (unlikely(!rq))
|
||||
diff --git a/drivers/net/wireless/realtek/rtlwifi/usb.c b/drivers/net/wireless/realtek/rtlwifi/usb.c
|
||||
index aac1ed3f7bb4..ad8390d2997b 100644
|
||||
--- a/drivers/net/wireless/realtek/rtlwifi/usb.c
|
||||
+++ b/drivers/net/wireless/realtek/rtlwifi/usb.c
|
||||
@@ -834,12 +834,30 @@ static void rtl_usb_stop(struct ieee80211_hw *hw)
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
|
||||
+ struct urb *urb;
|
||||
|
||||
/* should after adapter start and interrupt enable. */
|
||||
set_hal_stop(rtlhal);
|
||||
cancel_work_sync(&rtlpriv->works.fill_h2c_cmd);
|
||||
/* Enable software */
|
||||
SET_USB_STOP(rtlusb);
|
||||
+
|
||||
+ /* free pre-allocated URBs from rtl_usb_start() */
|
||||
+ usb_kill_anchored_urbs(&rtlusb->rx_submitted);
|
||||
+
|
||||
+ tasklet_kill(&rtlusb->rx_work_tasklet);
|
||||
+ cancel_work_sync(&rtlpriv->works.lps_change_work);
|
||||
+
|
||||
+ flush_workqueue(rtlpriv->works.rtl_wq);
|
||||
+
|
||||
+ skb_queue_purge(&rtlusb->rx_queue);
|
||||
+
|
||||
+ while ((urb = usb_get_from_anchor(&rtlusb->rx_cleanup_urbs))) {
|
||||
+ usb_free_coherent(urb->dev, urb->transfer_buffer_length,
|
||||
+ urb->transfer_buffer, urb->transfer_dma);
|
||||
+ usb_free_urb(urb);
|
||||
+ }
|
||||
+
|
||||
rtlpriv->cfg->ops->hw_disable(hw);
|
||||
}
|
||||
|
||||
@@ -1073,6 +1091,7 @@ int rtl_usb_probe(struct usb_interface *intf,
|
||||
return -ENOMEM;
|
||||
}
|
||||
rtlpriv = hw->priv;
|
||||
+ rtlpriv->hw = hw;
|
||||
rtlpriv->usb_data = kzalloc(RTL_USB_MAX_RX_COUNT * sizeof(u32),
|
||||
GFP_KERNEL);
|
||||
if (!rtlpriv->usb_data)
|
||||
diff --git a/drivers/platform/goldfish/pdev_bus.c b/drivers/platform/goldfish/pdev_bus.c
|
||||
index 1f52462f4cdd..dd9ea463c2a4 100644
|
||||
--- a/drivers/platform/goldfish/pdev_bus.c
|
||||
+++ b/drivers/platform/goldfish/pdev_bus.c
|
||||
@@ -157,23 +157,26 @@ static int goldfish_new_pdev(void)
|
||||
static irqreturn_t goldfish_pdev_bus_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
irqreturn_t ret = IRQ_NONE;
|
||||
+
|
||||
while (1) {
|
||||
u32 op = readl(pdev_bus_base + PDEV_BUS_OP);
|
||||
- switch (op) {
|
||||
- case PDEV_BUS_OP_DONE:
|
||||
- return IRQ_NONE;
|
||||
|
||||
+ switch (op) {
|
||||
case PDEV_BUS_OP_REMOVE_DEV:
|
||||
goldfish_pdev_remove();
|
||||
+ ret = IRQ_HANDLED;
|
||||
break;
|
||||
|
||||
case PDEV_BUS_OP_ADD_DEV:
|
||||
goldfish_new_pdev();
|
||||
+ ret = IRQ_HANDLED;
|
||||
break;
|
||||
+
|
||||
+ case PDEV_BUS_OP_DONE:
|
||||
+ default:
|
||||
+ return ret;
|
||||
}
|
||||
- ret = IRQ_HANDLED;
|
||||
}
|
||||
- return ret;
|
||||
}
|
||||
|
||||
static int goldfish_pdev_bus_probe(struct platform_device *pdev)
|
||||
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
|
||||
index 5836751b8203..9bb934ed2a7a 100644
|
||||
--- a/drivers/rtc/interface.c
|
||||
+++ b/drivers/rtc/interface.c
|
||||
@@ -748,9 +748,23 @@ EXPORT_SYMBOL_GPL(rtc_irq_set_freq);
|
||||
*/
|
||||
static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer)
|
||||
{
|
||||
+ struct timerqueue_node *next = timerqueue_getnext(&rtc->timerqueue);
|
||||
+ struct rtc_time tm;
|
||||
+ ktime_t now;
|
||||
+
|
||||
timer->enabled = 1;
|
||||
+ __rtc_read_time(rtc, &tm);
|
||||
+ now = rtc_tm_to_ktime(tm);
|
||||
+
|
||||
+ /* Skip over expired timers */
|
||||
+ while (next) {
|
||||
+ if (next->expires.tv64 >= now.tv64)
|
||||
+ break;
|
||||
+ next = timerqueue_iterate_next(next);
|
||||
+ }
|
||||
+
|
||||
timerqueue_add(&rtc->timerqueue, &timer->node);
|
||||
- if (&timer->node == timerqueue_getnext(&rtc->timerqueue)) {
|
||||
+ if (!next) {
|
||||
struct rtc_wkalrm alarm;
|
||||
int err;
|
||||
alarm.time = rtc_ktime_to_tm(timer->node.expires);
|
||||
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
|
||||
index e1de4944e0ce..8c4707d5778e 100644
|
||||
--- a/drivers/tty/serial/msm_serial.c
|
||||
+++ b/drivers/tty/serial/msm_serial.c
|
||||
@@ -1615,6 +1615,7 @@ static const struct of_device_id msm_match_table[] = {
|
||||
{ .compatible = "qcom,msm-uartdm" },
|
||||
{}
|
||||
};
|
||||
+MODULE_DEVICE_TABLE(of, msm_match_table);
|
||||
|
||||
static struct platform_driver msm_platform_driver = {
|
||||
.remove = msm_serial_remove,
|
||||
diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
|
||||
index 5a048b7b92e8..2949289bb3c5 100644
|
||||
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
|
||||
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
|
||||
@@ -244,7 +244,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
|
||||
struct ci_hdrc_platform_data pdata = {
|
||||
.name = dev_name(&pdev->dev),
|
||||
.capoffset = DEF_CAPOFFSET,
|
||||
- .flags = CI_HDRC_SET_NON_ZERO_TTHA,
|
||||
};
|
||||
int ret;
|
||||
const struct of_device_id *of_id;
|
||||
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c
|
||||
index 1532cde8a437..7812052dc700 100644
|
||||
--- a/drivers/usb/serial/ark3116.c
|
||||
+++ b/drivers/usb/serial/ark3116.c
|
||||
@@ -99,10 +99,17 @@ static int ark3116_read_reg(struct usb_serial *serial,
|
||||
usb_rcvctrlpipe(serial->dev, 0),
|
||||
0xfe, 0xc0, 0, reg,
|
||||
buf, 1, ARK_TIMEOUT);
|
||||
- if (result < 0)
|
||||
+ if (result < 1) {
|
||||
+ dev_err(&serial->interface->dev,
|
||||
+ "failed to read register %u: %d\n",
|
||||
+ reg, result);
|
||||
+ if (result >= 0)
|
||||
+ result = -EIO;
|
||||
+
|
||||
return result;
|
||||
- else
|
||||
- return buf[0];
|
||||
+ }
|
||||
+
|
||||
+ return buf[0];
|
||||
}
|
||||
|
||||
static inline int calc_divisor(int bps)
|
||||
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
|
||||
index fe7452f0f38a..33cec50978b8 100644
|
||||
--- a/drivers/usb/serial/cp210x.c
|
||||
+++ b/drivers/usb/serial/cp210x.c
|
||||
@@ -171,6 +171,8 @@ static const struct usb_device_id id_table[] = {
|
||||
{ USB_DEVICE(0x1901, 0x0190) }, /* GE B850 CP2105 Recorder interface */
|
||||
{ USB_DEVICE(0x1901, 0x0193) }, /* GE B650 CP2104 PMC interface */
|
||||
{ USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */
|
||||
+ { USB_DEVICE(0x1901, 0x0195) }, /* GE B850/B650/B450 CP2104 DP UART interface */
|
||||
+ { USB_DEVICE(0x1901, 0x0196) }, /* GE B850 CP2105 DP UART interface */
|
||||
{ USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */
|
||||
{ USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */
|
||||
{ USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */
|
||||
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
|
||||
index d3d6ec455151..19a98116c2ab 100644
|
||||
--- a/drivers/usb/serial/ftdi_sio.c
|
||||
+++ b/drivers/usb/serial/ftdi_sio.c
|
||||
@@ -1807,8 +1807,6 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
|
||||
|
||||
mutex_init(&priv->cfg_lock);
|
||||
|
||||
- priv->flags = ASYNC_LOW_LATENCY;
|
||||
-
|
||||
if (quirk && quirk->port_probe)
|
||||
quirk->port_probe(priv);
|
||||
|
||||
@@ -2072,6 +2070,20 @@ static int ftdi_process_packet(struct usb_serial_port *port,
|
||||
priv->prev_status = status;
|
||||
}
|
||||
|
||||
+ /* save if the transmitter is empty or not */
|
||||
+ if (packet[1] & FTDI_RS_TEMT)
|
||||
+ priv->transmit_empty = 1;
|
||||
+ else
|
||||
+ priv->transmit_empty = 0;
|
||||
+
|
||||
+ len -= 2;
|
||||
+ if (!len)
|
||||
+ return 0; /* status only */
|
||||
+
|
||||
+ /*
|
||||
+ * Break and error status must only be processed for packets with
|
||||
+ * data payload to avoid over-reporting.
|
||||
+ */
|
||||
flag = TTY_NORMAL;
|
||||
if (packet[1] & FTDI_RS_ERR_MASK) {
|
||||
/* Break takes precedence over parity, which takes precedence
|
||||
@@ -2094,15 +2106,6 @@ static int ftdi_process_packet(struct usb_serial_port *port,
|
||||
}
|
||||
}
|
||||
|
||||
- /* save if the transmitter is empty or not */
|
||||
- if (packet[1] & FTDI_RS_TEMT)
|
||||
- priv->transmit_empty = 1;
|
||||
- else
|
||||
- priv->transmit_empty = 0;
|
||||
-
|
||||
- len -= 2;
|
||||
- if (!len)
|
||||
- return 0; /* status only */
|
||||
port->icount.rx += len;
|
||||
ch = packet + 2;
|
||||
|
||||
@@ -2433,8 +2436,12 @@ static int ftdi_get_modem_status(struct usb_serial_port *port,
|
||||
FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
|
||||
0, priv->interface,
|
||||
buf, len, WDR_TIMEOUT);
|
||||
- if (ret < 0) {
|
||||
+
|
||||
+ /* NOTE: We allow short responses and handle that below. */
|
||||
+ if (ret < 1) {
|
||||
dev_err(&port->dev, "failed to get modem status: %d\n", ret);
|
||||
+ if (ret >= 0)
|
||||
+ ret = -EIO;
|
||||
ret = usb_translate_errors(ret);
|
||||
goto out;
|
||||
}
|
||||
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
|
||||
index 97ea52b5cfd4..d17685cc00c9 100644
|
||||
--- a/drivers/usb/serial/mos7840.c
|
||||
+++ b/drivers/usb/serial/mos7840.c
|
||||
@@ -1024,6 +1024,7 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port)
|
||||
* (can't set it up in mos7840_startup as the structures *
|
||||
* were not set up at that time.) */
|
||||
if (port0->open_ports == 1) {
|
||||
+ /* FIXME: Buffer never NULL, so URB is not submitted. */
|
||||
if (serial->port[0]->interrupt_in_buffer == NULL) {
|
||||
/* set up interrupt urb */
|
||||
usb_fill_int_urb(serial->port[0]->interrupt_in_urb,
|
||||
@@ -2119,7 +2120,8 @@ static int mos7840_calc_num_ports(struct usb_serial *serial)
|
||||
static int mos7840_attach(struct usb_serial *serial)
|
||||
{
|
||||
if (serial->num_bulk_in < serial->num_ports ||
|
||||
- serial->num_bulk_out < serial->num_ports) {
|
||||
+ serial->num_bulk_out < serial->num_ports ||
|
||||
+ serial->num_interrupt_in < 1) {
|
||||
dev_err(&serial->interface->dev, "missing endpoints\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c
|
||||
index 4b7bfb394a32..64bf258e7e00 100644
|
||||
--- a/drivers/usb/serial/opticon.c
|
||||
+++ b/drivers/usb/serial/opticon.c
|
||||
@@ -142,7 +142,7 @@ static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port)
|
||||
usb_clear_halt(port->serial->dev, port->read_urb->pipe);
|
||||
|
||||
res = usb_serial_generic_open(tty, port);
|
||||
- if (!res)
|
||||
+ if (res)
|
||||
return res;
|
||||
|
||||
/* Request CTS line state, sometimes during opening the current
|
||||
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c
|
||||
index 475e6c31b266..ddfd787c461c 100644
|
||||
--- a/drivers/usb/serial/spcp8x5.c
|
||||
+++ b/drivers/usb/serial/spcp8x5.c
|
||||
@@ -232,11 +232,17 @@ static int spcp8x5_get_msr(struct usb_serial_port *port, u8 *status)
|
||||
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
|
||||
GET_UART_STATUS, GET_UART_STATUS_TYPE,
|
||||
0, GET_UART_STATUS_MSR, buf, 1, 100);
|
||||
- if (ret < 0)
|
||||
+ if (ret < 1) {
|
||||
dev_err(&port->dev, "failed to get modem status: %d\n", ret);
|
||||
+ if (ret >= 0)
|
||||
+ ret = -EIO;
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
dev_dbg(&port->dev, "0xc0:0x22:0:6 %d - 0x02%x\n", ret, *buf);
|
||||
*status = *buf;
|
||||
+ ret = 0;
|
||||
+out:
|
||||
kfree(buf);
|
||||
|
||||
return ret;
|
||||
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
|
||||
index 9ef80bf441b3..a988d4ef39da 100644
|
||||
--- a/mm/backing-dev.c
|
||||
+++ b/mm/backing-dev.c
|
||||
@@ -757,15 +757,20 @@ static int cgwb_bdi_init(struct backing_dev_info *bdi)
|
||||
if (!bdi->wb_congested)
|
||||
return -ENOMEM;
|
||||
|
||||
+ atomic_set(&bdi->wb_congested->refcnt, 1);
|
||||
+
|
||||
err = wb_init(&bdi->wb, bdi, 1, GFP_KERNEL);
|
||||
if (err) {
|
||||
- kfree(bdi->wb_congested);
|
||||
+ wb_congested_put(bdi->wb_congested);
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void cgwb_bdi_destroy(struct backing_dev_info *bdi) { }
|
||||
+static void cgwb_bdi_destroy(struct backing_dev_info *bdi)
|
||||
+{
|
||||
+ wb_congested_put(bdi->wb_congested);
|
||||
+}
|
||||
|
||||
#endif /* CONFIG_CGROUP_WRITEBACK */
|
||||
|
||||
diff --git a/net/dccp/input.c b/net/dccp/input.c
|
||||
index 3bd14e885396..dbe2573f6ba1 100644
|
||||
--- a/net/dccp/input.c
|
||||
+++ b/net/dccp/input.c
|
||||
@@ -606,7 +606,8 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
|
||||
if (inet_csk(sk)->icsk_af_ops->conn_request(sk,
|
||||
skb) < 0)
|
||||
return 1;
|
||||
- goto discard;
|
||||
+ consume_skb(skb);
|
||||
+ return 0;
|
||||
}
|
||||
if (dh->dccph_type == DCCP_PKT_RESET)
|
||||
goto discard;
|
||||
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
|
||||
index bc14c5bb124b..f300d1cbfa91 100644
|
||||
--- a/net/ipv4/ip_sockglue.c
|
||||
+++ b/net/ipv4/ip_sockglue.c
|
||||
@@ -105,10 +105,10 @@ static void ip_cmsg_recv_checksum(struct msghdr *msg, struct sk_buff *skb,
|
||||
if (skb->ip_summed != CHECKSUM_COMPLETE)
|
||||
return;
|
||||
|
||||
- if (offset != 0)
|
||||
- csum = csum_sub(csum,
|
||||
- csum_partial(skb->data + tlen,
|
||||
- offset, 0));
|
||||
+ if (offset != 0) {
|
||||
+ int tend_off = skb_transport_offset(skb) + tlen;
|
||||
+ csum = csum_sub(csum, skb_checksum(skb, tend_off, offset, 0));
|
||||
+ }
|
||||
|
||||
put_cmsg(msg, SOL_IP, IP_CHECKSUM, sizeof(__wsum), &csum);
|
||||
}
|
||||
diff --git a/net/irda/irqueue.c b/net/irda/irqueue.c
|
||||
index acbe61c7e683..160dc89335e2 100644
|
||||
--- a/net/irda/irqueue.c
|
||||
+++ b/net/irda/irqueue.c
|
||||
@@ -383,9 +383,6 @@ EXPORT_SYMBOL(hashbin_new);
|
||||
* for deallocating this structure if it's complex. If not the user can
|
||||
* just supply kfree, which should take care of the job.
|
||||
*/
|
||||
-#ifdef CONFIG_LOCKDEP
|
||||
-static int hashbin_lock_depth = 0;
|
||||
-#endif
|
||||
int hashbin_delete( hashbin_t* hashbin, FREE_FUNC free_func)
|
||||
{
|
||||
irda_queue_t* queue;
|
||||
@@ -396,22 +393,27 @@ int hashbin_delete( hashbin_t* hashbin, FREE_FUNC free_func)
|
||||
IRDA_ASSERT(hashbin->magic == HB_MAGIC, return -1;);
|
||||
|
||||
/* Synchronize */
|
||||
- if ( hashbin->hb_type & HB_LOCK ) {
|
||||
- spin_lock_irqsave_nested(&hashbin->hb_spinlock, flags,
|
||||
- hashbin_lock_depth++);
|
||||
- }
|
||||
+ if (hashbin->hb_type & HB_LOCK)
|
||||
+ spin_lock_irqsave(&hashbin->hb_spinlock, flags);
|
||||
|
||||
/*
|
||||
* Free the entries in the hashbin, TODO: use hashbin_clear when
|
||||
* it has been shown to work
|
||||
*/
|
||||
for (i = 0; i < HASHBIN_SIZE; i ++ ) {
|
||||
- queue = dequeue_first((irda_queue_t**) &hashbin->hb_queue[i]);
|
||||
- while (queue ) {
|
||||
- if (free_func)
|
||||
- (*free_func)(queue);
|
||||
- queue = dequeue_first(
|
||||
- (irda_queue_t**) &hashbin->hb_queue[i]);
|
||||
+ while (1) {
|
||||
+ queue = dequeue_first((irda_queue_t**) &hashbin->hb_queue[i]);
|
||||
+
|
||||
+ if (!queue)
|
||||
+ break;
|
||||
+
|
||||
+ if (free_func) {
|
||||
+ if (hashbin->hb_type & HB_LOCK)
|
||||
+ spin_unlock_irqrestore(&hashbin->hb_spinlock, flags);
|
||||
+ free_func(queue);
|
||||
+ if (hashbin->hb_type & HB_LOCK)
|
||||
+ spin_lock_irqsave(&hashbin->hb_spinlock, flags);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -420,12 +422,8 @@ int hashbin_delete( hashbin_t* hashbin, FREE_FUNC free_func)
|
||||
hashbin->magic = ~HB_MAGIC;
|
||||
|
||||
/* Release lock */
|
||||
- if ( hashbin->hb_type & HB_LOCK) {
|
||||
+ if (hashbin->hb_type & HB_LOCK)
|
||||
spin_unlock_irqrestore(&hashbin->hb_spinlock, flags);
|
||||
-#ifdef CONFIG_LOCKDEP
|
||||
- hashbin_lock_depth--;
|
||||
-#endif
|
||||
- }
|
||||
|
||||
/*
|
||||
* Free the hashbin structure
|
||||
diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c
|
||||
index 3e821daf9dd4..8bc5a1bd2d45 100644
|
||||
--- a/net/llc/llc_conn.c
|
||||
+++ b/net/llc/llc_conn.c
|
||||
@@ -821,7 +821,10 @@ void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb)
|
||||
* another trick required to cope with how the PROCOM state
|
||||
* machine works. -acme
|
||||
*/
|
||||
+ skb_orphan(skb);
|
||||
+ sock_hold(sk);
|
||||
skb->sk = sk;
|
||||
+ skb->destructor = sock_efree;
|
||||
}
|
||||
if (!sock_owned_by_user(sk))
|
||||
llc_conn_rcv(sk, skb);
|
||||
diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c
|
||||
index d0e1e804ebd7..5404d0d195cc 100644
|
||||
--- a/net/llc/llc_sap.c
|
||||
+++ b/net/llc/llc_sap.c
|
||||
@@ -290,7 +290,10 @@ static void llc_sap_rcv(struct llc_sap *sap, struct sk_buff *skb,
|
||||
|
||||
ev->type = LLC_SAP_EV_TYPE_PDU;
|
||||
ev->reason = 0;
|
||||
+ skb_orphan(skb);
|
||||
+ sock_hold(sk);
|
||||
skb->sk = sk;
|
||||
+ skb->destructor = sock_efree;
|
||||
llc_sap_state_process(sap, skb);
|
||||
}
|
||||
|
||||
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
|
||||
index f2d28ed74a0a..d805cd577a60 100644
|
||||
--- a/net/packet/af_packet.c
|
||||
+++ b/net/packet/af_packet.c
|
||||
@@ -1497,6 +1497,8 @@ static void __fanout_link(struct sock *sk, struct packet_sock *po)
|
||||
f->arr[f->num_members] = sk;
|
||||
smp_wmb();
|
||||
f->num_members++;
|
||||
+ if (f->num_members == 1)
|
||||
+ dev_add_pack(&f->prot_hook);
|
||||
spin_unlock(&f->lock);
|
||||
}
|
||||
|
||||
@@ -1513,6 +1515,8 @@ static void __fanout_unlink(struct sock *sk, struct packet_sock *po)
|
||||
BUG_ON(i >= f->num_members);
|
||||
f->arr[i] = f->arr[f->num_members - 1];
|
||||
f->num_members--;
|
||||
+ if (f->num_members == 0)
|
||||
+ __dev_remove_pack(&f->prot_hook);
|
||||
spin_unlock(&f->lock);
|
||||
}
|
||||
|
||||
@@ -1623,6 +1627,7 @@ static void fanout_release_data(struct packet_fanout *f)
|
||||
|
||||
static int fanout_add(struct sock *sk, u16 id, u16 type_flags)
|
||||
{
|
||||
+ struct packet_rollover *rollover = NULL;
|
||||
struct packet_sock *po = pkt_sk(sk);
|
||||
struct packet_fanout *f, *match;
|
||||
u8 type = type_flags & 0xff;
|
||||
@@ -1645,23 +1650,28 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+ mutex_lock(&fanout_mutex);
|
||||
+
|
||||
+ err = -EINVAL;
|
||||
if (!po->running)
|
||||
- return -EINVAL;
|
||||
+ goto out;
|
||||
|
||||
+ err = -EALREADY;
|
||||
if (po->fanout)
|
||||
- return -EALREADY;
|
||||
+ goto out;
|
||||
|
||||
if (type == PACKET_FANOUT_ROLLOVER ||
|
||||
(type_flags & PACKET_FANOUT_FLAG_ROLLOVER)) {
|
||||
- po->rollover = kzalloc(sizeof(*po->rollover), GFP_KERNEL);
|
||||
- if (!po->rollover)
|
||||
- return -ENOMEM;
|
||||
- atomic_long_set(&po->rollover->num, 0);
|
||||
- atomic_long_set(&po->rollover->num_huge, 0);
|
||||
- atomic_long_set(&po->rollover->num_failed, 0);
|
||||
+ err = -ENOMEM;
|
||||
+ rollover = kzalloc(sizeof(*rollover), GFP_KERNEL);
|
||||
+ if (!rollover)
|
||||
+ goto out;
|
||||
+ atomic_long_set(&rollover->num, 0);
|
||||
+ atomic_long_set(&rollover->num_huge, 0);
|
||||
+ atomic_long_set(&rollover->num_failed, 0);
|
||||
+ po->rollover = rollover;
|
||||
}
|
||||
|
||||
- mutex_lock(&fanout_mutex);
|
||||
match = NULL;
|
||||
list_for_each_entry(f, &fanout_list, list) {
|
||||
if (f->id == id &&
|
||||
@@ -1691,7 +1701,6 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags)
|
||||
match->prot_hook.func = packet_rcv_fanout;
|
||||
match->prot_hook.af_packet_priv = match;
|
||||
match->prot_hook.id_match = match_fanout_group;
|
||||
- dev_add_pack(&match->prot_hook);
|
||||
list_add(&match->list, &fanout_list);
|
||||
}
|
||||
err = -EINVAL;
|
||||
@@ -1708,36 +1717,40 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags)
|
||||
}
|
||||
}
|
||||
out:
|
||||
- mutex_unlock(&fanout_mutex);
|
||||
- if (err) {
|
||||
- kfree(po->rollover);
|
||||
+ if (err && rollover) {
|
||||
+ kfree(rollover);
|
||||
po->rollover = NULL;
|
||||
}
|
||||
+ mutex_unlock(&fanout_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
-static void fanout_release(struct sock *sk)
|
||||
+/* If pkt_sk(sk)->fanout->sk_ref is zero, this function removes
|
||||
+ * pkt_sk(sk)->fanout from fanout_list and returns pkt_sk(sk)->fanout.
|
||||
+ * It is the responsibility of the caller to call fanout_release_data() and
|
||||
+ * free the returned packet_fanout (after synchronize_net())
|
||||
+ */
|
||||
+static struct packet_fanout *fanout_release(struct sock *sk)
|
||||
{
|
||||
struct packet_sock *po = pkt_sk(sk);
|
||||
struct packet_fanout *f;
|
||||
|
||||
+ mutex_lock(&fanout_mutex);
|
||||
f = po->fanout;
|
||||
- if (!f)
|
||||
- return;
|
||||
+ if (f) {
|
||||
+ po->fanout = NULL;
|
||||
|
||||
- mutex_lock(&fanout_mutex);
|
||||
- po->fanout = NULL;
|
||||
+ if (atomic_dec_and_test(&f->sk_ref))
|
||||
+ list_del(&f->list);
|
||||
+ else
|
||||
+ f = NULL;
|
||||
|
||||
- if (atomic_dec_and_test(&f->sk_ref)) {
|
||||
- list_del(&f->list);
|
||||
- dev_remove_pack(&f->prot_hook);
|
||||
- fanout_release_data(f);
|
||||
- kfree(f);
|
||||
+ if (po->rollover)
|
||||
+ kfree_rcu(po->rollover, rcu);
|
||||
}
|
||||
mutex_unlock(&fanout_mutex);
|
||||
|
||||
- if (po->rollover)
|
||||
- kfree_rcu(po->rollover, rcu);
|
||||
+ return f;
|
||||
}
|
||||
|
||||
static bool packet_extra_vlan_len_allowed(const struct net_device *dev,
|
||||
@@ -2846,6 +2859,7 @@ static int packet_release(struct socket *sock)
|
||||
{
|
||||
struct sock *sk = sock->sk;
|
||||
struct packet_sock *po;
|
||||
+ struct packet_fanout *f;
|
||||
struct net *net;
|
||||
union tpacket_req_u req_u;
|
||||
|
||||
@@ -2885,9 +2899,14 @@ static int packet_release(struct socket *sock)
|
||||
packet_set_ring(sk, &req_u, 1, 1);
|
||||
}
|
||||
|
||||
- fanout_release(sk);
|
||||
+ f = fanout_release(sk);
|
||||
|
||||
synchronize_net();
|
||||
+
|
||||
+ if (f) {
|
||||
+ fanout_release_data(f);
|
||||
+ kfree(f);
|
||||
+ }
|
||||
/*
|
||||
* Now the socket is dead. No more input will appear.
|
||||
*/
|
||||
@@ -3861,7 +3880,6 @@ static int packet_notifier(struct notifier_block *this,
|
||||
}
|
||||
if (msg == NETDEV_UNREGISTER) {
|
||||
packet_cached_dev_reset(po);
|
||||
- fanout_release(sk);
|
||||
po->ifindex = -1;
|
||||
if (po->prot_hook.dev)
|
||||
dev_put(po->prot_hook.dev);
|
||||
diff --git a/net/socket.c b/net/socket.c
|
||||
index 0090225eeb1e..fbfa9d2492cf 100644
|
||||
--- a/net/socket.c
|
||||
+++ b/net/socket.c
|
||||
@@ -2185,8 +2185,10 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
|
||||
return err;
|
||||
|
||||
err = sock_error(sock->sk);
|
||||
- if (err)
|
||||
+ if (err) {
|
||||
+ datagrams = err;
|
||||
goto out_put;
|
||||
+ }
|
||||
|
||||
entry = mmsg;
|
||||
compat_entry = (struct compat_mmsghdr __user *)mmsg;
|
||||
8420
patch/kernel/s5p6818-default/03-patch-4.4.52-53.patch
Normal file
8420
patch/kernel/s5p6818-default/03-patch-4.4.52-53.patch
Normal file
File diff suppressed because it is too large
Load Diff
1611
patch/kernel/s5p6818-default/03-patch-4.4.53-54.patch
Normal file
1611
patch/kernel/s5p6818-default/03-patch-4.4.53-54.patch
Normal file
File diff suppressed because it is too large
Load Diff
1178
patch/kernel/s5p6818-default/03-patch-4.4.54-55.patch
Normal file
1178
patch/kernel/s5p6818-default/03-patch-4.4.54-55.patch
Normal file
File diff suppressed because it is too large
Load Diff
2116
patch/kernel/s5p6818-default/03-patch-4.4.55-56.patch
Normal file
2116
patch/kernel/s5p6818-default/03-patch-4.4.55-56.patch
Normal file
File diff suppressed because it is too large
Load Diff
1172
patch/kernel/s5p6818-default/03-patch-4.4.56-57.patch
Normal file
1172
patch/kernel/s5p6818-default/03-patch-4.4.56-57.patch
Normal file
File diff suppressed because it is too large
Load Diff
2653
patch/kernel/s5p6818-default/03-patch-4.4.57-58.patch
Normal file
2653
patch/kernel/s5p6818-default/03-patch-4.4.57-58.patch
Normal file
File diff suppressed because it is too large
Load Diff
548
patch/kernel/s5p6818-default/03-patch-4.4.58-59.patch
Normal file
548
patch/kernel/s5p6818-default/03-patch-4.4.58-59.patch
Normal file
@ -0,0 +1,548 @@
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 3efe2ea99e2d..083724c6ca4d 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 4
|
||||
-SUBLEVEL = 58
|
||||
+SUBLEVEL = 59
|
||||
EXTRAVERSION =
|
||||
NAME = Blurry Fish Butt
|
||||
|
||||
diff --git a/arch/c6x/kernel/ptrace.c b/arch/c6x/kernel/ptrace.c
|
||||
index 3c494e84444d..a511ac16a8e3 100644
|
||||
--- a/arch/c6x/kernel/ptrace.c
|
||||
+++ b/arch/c6x/kernel/ptrace.c
|
||||
@@ -69,46 +69,6 @@ static int gpr_get(struct task_struct *target,
|
||||
0, sizeof(*regs));
|
||||
}
|
||||
|
||||
-static int gpr_set(struct task_struct *target,
|
||||
- const struct user_regset *regset,
|
||||
- unsigned int pos, unsigned int count,
|
||||
- const void *kbuf, const void __user *ubuf)
|
||||
-{
|
||||
- int ret;
|
||||
- struct pt_regs *regs = task_pt_regs(target);
|
||||
-
|
||||
- /* Don't copyin TSR or CSR */
|
||||
- ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
||||
- ®s,
|
||||
- 0, PT_TSR * sizeof(long));
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
|
||||
- PT_TSR * sizeof(long),
|
||||
- (PT_TSR + 1) * sizeof(long));
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
||||
- ®s,
|
||||
- (PT_TSR + 1) * sizeof(long),
|
||||
- PT_CSR * sizeof(long));
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
|
||||
- PT_CSR * sizeof(long),
|
||||
- (PT_CSR + 1) * sizeof(long));
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
||||
- ®s,
|
||||
- (PT_CSR + 1) * sizeof(long), -1);
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
enum c6x_regset {
|
||||
REGSET_GPR,
|
||||
};
|
||||
@@ -120,7 +80,6 @@ static const struct user_regset c6x_regsets[] = {
|
||||
.size = sizeof(u32),
|
||||
.align = sizeof(u32),
|
||||
.get = gpr_get,
|
||||
- .set = gpr_set
|
||||
},
|
||||
};
|
||||
|
||||
diff --git a/arch/h8300/kernel/ptrace.c b/arch/h8300/kernel/ptrace.c
|
||||
index 92075544a19a..0dc1c8f622bc 100644
|
||||
--- a/arch/h8300/kernel/ptrace.c
|
||||
+++ b/arch/h8300/kernel/ptrace.c
|
||||
@@ -95,7 +95,8 @@ static int regs_get(struct task_struct *target,
|
||||
long *reg = (long *)®s;
|
||||
|
||||
/* build user regs in buffer */
|
||||
- for (r = 0; r < ARRAY_SIZE(register_offset); r++)
|
||||
+ BUILD_BUG_ON(sizeof(regs) % sizeof(long) != 0);
|
||||
+ for (r = 0; r < sizeof(regs) / sizeof(long); r++)
|
||||
*reg++ = h8300_get_reg(target, r);
|
||||
|
||||
return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
|
||||
@@ -113,7 +114,8 @@ static int regs_set(struct task_struct *target,
|
||||
long *reg;
|
||||
|
||||
/* build user regs in buffer */
|
||||
- for (reg = (long *)®s, r = 0; r < ARRAY_SIZE(register_offset); r++)
|
||||
+ BUILD_BUG_ON(sizeof(regs) % sizeof(long) != 0);
|
||||
+ for (reg = (long *)®s, r = 0; r < sizeof(regs) / sizeof(long); r++)
|
||||
*reg++ = h8300_get_reg(target, r);
|
||||
|
||||
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
||||
@@ -122,7 +124,7 @@ static int regs_set(struct task_struct *target,
|
||||
return ret;
|
||||
|
||||
/* write back to pt_regs */
|
||||
- for (reg = (long *)®s, r = 0; r < ARRAY_SIZE(register_offset); r++)
|
||||
+ for (reg = (long *)®s, r = 0; r < sizeof(regs) / sizeof(long); r++)
|
||||
h8300_put_reg(target, r, *reg++);
|
||||
return 0;
|
||||
}
|
||||
diff --git a/arch/metag/kernel/ptrace.c b/arch/metag/kernel/ptrace.c
|
||||
index 7563628822bd..5e2dc7defd2c 100644
|
||||
--- a/arch/metag/kernel/ptrace.c
|
||||
+++ b/arch/metag/kernel/ptrace.c
|
||||
@@ -24,6 +24,16 @@
|
||||
* user_regset definitions.
|
||||
*/
|
||||
|
||||
+static unsigned long user_txstatus(const struct pt_regs *regs)
|
||||
+{
|
||||
+ unsigned long data = (unsigned long)regs->ctx.Flags;
|
||||
+
|
||||
+ if (regs->ctx.SaveMask & TBICTX_CBUF_BIT)
|
||||
+ data |= USER_GP_REGS_STATUS_CATCH_BIT;
|
||||
+
|
||||
+ return data;
|
||||
+}
|
||||
+
|
||||
int metag_gp_regs_copyout(const struct pt_regs *regs,
|
||||
unsigned int pos, unsigned int count,
|
||||
void *kbuf, void __user *ubuf)
|
||||
@@ -62,9 +72,7 @@ int metag_gp_regs_copyout(const struct pt_regs *regs,
|
||||
if (ret)
|
||||
goto out;
|
||||
/* TXSTATUS */
|
||||
- data = (unsigned long)regs->ctx.Flags;
|
||||
- if (regs->ctx.SaveMask & TBICTX_CBUF_BIT)
|
||||
- data |= USER_GP_REGS_STATUS_CATCH_BIT;
|
||||
+ data = user_txstatus(regs);
|
||||
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
|
||||
&data, 4*25, 4*26);
|
||||
if (ret)
|
||||
@@ -119,6 +127,7 @@ int metag_gp_regs_copyin(struct pt_regs *regs,
|
||||
if (ret)
|
||||
goto out;
|
||||
/* TXSTATUS */
|
||||
+ data = user_txstatus(regs);
|
||||
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
||||
&data, 4*25, 4*26);
|
||||
if (ret)
|
||||
@@ -244,6 +253,8 @@ int metag_rp_state_copyin(struct pt_regs *regs,
|
||||
unsigned long long *ptr;
|
||||
int ret, i;
|
||||
|
||||
+ if (count < 4*13)
|
||||
+ return -EINVAL;
|
||||
/* Read the entire pipeline before making any changes */
|
||||
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
||||
&rp, 0, 4*13);
|
||||
@@ -303,7 +314,7 @@ static int metag_tls_set(struct task_struct *target,
|
||||
const void *kbuf, const void __user *ubuf)
|
||||
{
|
||||
int ret;
|
||||
- void __user *tls;
|
||||
+ void __user *tls = target->thread.tls_ptr;
|
||||
|
||||
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &tls, 0, -1);
|
||||
if (ret)
|
||||
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
|
||||
index 74d581569778..c95bf18260f8 100644
|
||||
--- a/arch/mips/kernel/ptrace.c
|
||||
+++ b/arch/mips/kernel/ptrace.c
|
||||
@@ -485,7 +485,8 @@ static int fpr_set(struct task_struct *target,
|
||||
&target->thread.fpu,
|
||||
0, sizeof(elf_fpregset_t));
|
||||
|
||||
- for (i = 0; i < NUM_FPU_REGS; i++) {
|
||||
+ BUILD_BUG_ON(sizeof(fpr_val) != sizeof(elf_fpreg_t));
|
||||
+ for (i = 0; i < NUM_FPU_REGS && count >= sizeof(elf_fpreg_t); i++) {
|
||||
err = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
||||
&fpr_val, i * sizeof(elf_fpreg_t),
|
||||
(i + 1) * sizeof(elf_fpreg_t));
|
||||
diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c
|
||||
index 9ddc4928a089..c1566170964f 100644
|
||||
--- a/arch/sparc/kernel/ptrace_64.c
|
||||
+++ b/arch/sparc/kernel/ptrace_64.c
|
||||
@@ -311,7 +311,7 @@ static int genregs64_set(struct task_struct *target,
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
- unsigned long y;
|
||||
+ unsigned long y = regs->y;
|
||||
|
||||
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
||||
&y,
|
||||
diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
|
||||
index 146264a41ec8..9736f9be5447 100644
|
||||
--- a/drivers/pinctrl/qcom/pinctrl-msm.c
|
||||
+++ b/drivers/pinctrl/qcom/pinctrl-msm.c
|
||||
@@ -597,10 +597,6 @@ static void msm_gpio_irq_unmask(struct irq_data *d)
|
||||
|
||||
spin_lock_irqsave(&pctrl->lock, flags);
|
||||
|
||||
- val = readl(pctrl->regs + g->intr_status_reg);
|
||||
- val &= ~BIT(g->intr_status_bit);
|
||||
- writel(val, pctrl->regs + g->intr_status_reg);
|
||||
-
|
||||
val = readl(pctrl->regs + g->intr_cfg_reg);
|
||||
val |= BIT(g->intr_enable_bit);
|
||||
writel(val, pctrl->regs + g->intr_cfg_reg);
|
||||
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
|
||||
index 56f7e2521202..01d15dca940e 100644
|
||||
--- a/drivers/virtio/virtio_balloon.c
|
||||
+++ b/drivers/virtio/virtio_balloon.c
|
||||
@@ -416,6 +416,8 @@ static int init_vqs(struct virtio_balloon *vb)
|
||||
* Prime this virtqueue with one buffer so the hypervisor can
|
||||
* use it to signal us later (it can't be broken yet!).
|
||||
*/
|
||||
+ update_balloon_stats(vb);
|
||||
+
|
||||
sg_init_one(&sg, vb->stats, sizeof vb->stats);
|
||||
if (virtqueue_add_outbuf(vb->stats_vq, &sg, 1, vb, GFP_KERNEL)
|
||||
< 0)
|
||||
diff --git a/fs/ext4/crypto_key.c b/fs/ext4/crypto_key.c
|
||||
index 9a16d1e75a49..505f8afde57c 100644
|
||||
--- a/fs/ext4/crypto_key.c
|
||||
+++ b/fs/ext4/crypto_key.c
|
||||
@@ -88,8 +88,6 @@ void ext4_free_crypt_info(struct ext4_crypt_info *ci)
|
||||
if (!ci)
|
||||
return;
|
||||
|
||||
- if (ci->ci_keyring_key)
|
||||
- key_put(ci->ci_keyring_key);
|
||||
crypto_free_ablkcipher(ci->ci_ctfm);
|
||||
kmem_cache_free(ext4_crypt_info_cachep, ci);
|
||||
}
|
||||
@@ -111,7 +109,7 @@ void ext4_free_encryption_info(struct inode *inode,
|
||||
ext4_free_crypt_info(ci);
|
||||
}
|
||||
|
||||
-int _ext4_get_encryption_info(struct inode *inode)
|
||||
+int ext4_get_encryption_info(struct inode *inode)
|
||||
{
|
||||
struct ext4_inode_info *ei = EXT4_I(inode);
|
||||
struct ext4_crypt_info *crypt_info;
|
||||
@@ -128,22 +126,15 @@ int _ext4_get_encryption_info(struct inode *inode)
|
||||
char mode;
|
||||
int res;
|
||||
|
||||
+ if (ei->i_crypt_info)
|
||||
+ return 0;
|
||||
+
|
||||
if (!ext4_read_workqueue) {
|
||||
res = ext4_init_crypto();
|
||||
if (res)
|
||||
return res;
|
||||
}
|
||||
|
||||
-retry:
|
||||
- crypt_info = ACCESS_ONCE(ei->i_crypt_info);
|
||||
- if (crypt_info) {
|
||||
- if (!crypt_info->ci_keyring_key ||
|
||||
- key_validate(crypt_info->ci_keyring_key) == 0)
|
||||
- return 0;
|
||||
- ext4_free_encryption_info(inode, crypt_info);
|
||||
- goto retry;
|
||||
- }
|
||||
-
|
||||
res = ext4_xattr_get(inode, EXT4_XATTR_INDEX_ENCRYPTION,
|
||||
EXT4_XATTR_NAME_ENCRYPTION_CONTEXT,
|
||||
&ctx, sizeof(ctx));
|
||||
@@ -166,7 +157,6 @@ retry:
|
||||
crypt_info->ci_data_mode = ctx.contents_encryption_mode;
|
||||
crypt_info->ci_filename_mode = ctx.filenames_encryption_mode;
|
||||
crypt_info->ci_ctfm = NULL;
|
||||
- crypt_info->ci_keyring_key = NULL;
|
||||
memcpy(crypt_info->ci_master_key, ctx.master_key_descriptor,
|
||||
sizeof(crypt_info->ci_master_key));
|
||||
if (S_ISREG(inode->i_mode))
|
||||
@@ -206,7 +196,6 @@ retry:
|
||||
keyring_key = NULL;
|
||||
goto out;
|
||||
}
|
||||
- crypt_info->ci_keyring_key = keyring_key;
|
||||
if (keyring_key->type != &key_type_logon) {
|
||||
printk_once(KERN_WARNING
|
||||
"ext4: key type must be logon\n");
|
||||
@@ -253,16 +242,13 @@ got_key:
|
||||
ext4_encryption_key_size(mode));
|
||||
if (res)
|
||||
goto out;
|
||||
- memzero_explicit(raw_key, sizeof(raw_key));
|
||||
- if (cmpxchg(&ei->i_crypt_info, NULL, crypt_info) != NULL) {
|
||||
- ext4_free_crypt_info(crypt_info);
|
||||
- goto retry;
|
||||
- }
|
||||
- return 0;
|
||||
|
||||
+ if (cmpxchg(&ei->i_crypt_info, NULL, crypt_info) == NULL)
|
||||
+ crypt_info = NULL;
|
||||
out:
|
||||
if (res == -ENOKEY)
|
||||
res = 0;
|
||||
+ key_put(keyring_key);
|
||||
ext4_free_crypt_info(crypt_info);
|
||||
memzero_explicit(raw_key, sizeof(raw_key));
|
||||
return res;
|
||||
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
|
||||
index cd5914495ad7..362d59b24f1d 100644
|
||||
--- a/fs/ext4/ext4.h
|
||||
+++ b/fs/ext4/ext4.h
|
||||
@@ -2330,23 +2330,11 @@ static inline void ext4_fname_free_filename(struct ext4_filename *fname) { }
|
||||
/* crypto_key.c */
|
||||
void ext4_free_crypt_info(struct ext4_crypt_info *ci);
|
||||
void ext4_free_encryption_info(struct inode *inode, struct ext4_crypt_info *ci);
|
||||
-int _ext4_get_encryption_info(struct inode *inode);
|
||||
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
int ext4_has_encryption_key(struct inode *inode);
|
||||
|
||||
-static inline int ext4_get_encryption_info(struct inode *inode)
|
||||
-{
|
||||
- struct ext4_crypt_info *ci = EXT4_I(inode)->i_crypt_info;
|
||||
-
|
||||
- if (!ci ||
|
||||
- (ci->ci_keyring_key &&
|
||||
- (ci->ci_keyring_key->flags & ((1 << KEY_FLAG_INVALIDATED) |
|
||||
- (1 << KEY_FLAG_REVOKED) |
|
||||
- (1 << KEY_FLAG_DEAD)))))
|
||||
- return _ext4_get_encryption_info(inode);
|
||||
- return 0;
|
||||
-}
|
||||
+int ext4_get_encryption_info(struct inode *inode);
|
||||
|
||||
static inline struct ext4_crypt_info *ext4_encryption_info(struct inode *inode)
|
||||
{
|
||||
diff --git a/fs/ext4/ext4_crypto.h b/fs/ext4/ext4_crypto.h
|
||||
index ac7d4e813796..1b17b05b9f4d 100644
|
||||
--- a/fs/ext4/ext4_crypto.h
|
||||
+++ b/fs/ext4/ext4_crypto.h
|
||||
@@ -78,7 +78,6 @@ struct ext4_crypt_info {
|
||||
char ci_filename_mode;
|
||||
char ci_flags;
|
||||
struct crypto_ablkcipher *ci_ctfm;
|
||||
- struct key *ci_keyring_key;
|
||||
char ci_master_key[EXT4_KEY_DESCRIPTOR_SIZE];
|
||||
};
|
||||
|
||||
diff --git a/fs/f2fs/crypto_key.c b/fs/f2fs/crypto_key.c
|
||||
index 5de2d866a25c..18595d7a0efc 100644
|
||||
--- a/fs/f2fs/crypto_key.c
|
||||
+++ b/fs/f2fs/crypto_key.c
|
||||
@@ -92,7 +92,6 @@ static void f2fs_free_crypt_info(struct f2fs_crypt_info *ci)
|
||||
if (!ci)
|
||||
return;
|
||||
|
||||
- key_put(ci->ci_keyring_key);
|
||||
crypto_free_ablkcipher(ci->ci_ctfm);
|
||||
kmem_cache_free(f2fs_crypt_info_cachep, ci);
|
||||
}
|
||||
@@ -113,7 +112,7 @@ void f2fs_free_encryption_info(struct inode *inode, struct f2fs_crypt_info *ci)
|
||||
f2fs_free_crypt_info(ci);
|
||||
}
|
||||
|
||||
-int _f2fs_get_encryption_info(struct inode *inode)
|
||||
+int f2fs_get_encryption_info(struct inode *inode)
|
||||
{
|
||||
struct f2fs_inode_info *fi = F2FS_I(inode);
|
||||
struct f2fs_crypt_info *crypt_info;
|
||||
@@ -129,18 +128,12 @@ int _f2fs_get_encryption_info(struct inode *inode)
|
||||
char mode;
|
||||
int res;
|
||||
|
||||
+ if (fi->i_crypt_info)
|
||||
+ return 0;
|
||||
+
|
||||
res = f2fs_crypto_initialize();
|
||||
if (res)
|
||||
return res;
|
||||
-retry:
|
||||
- crypt_info = ACCESS_ONCE(fi->i_crypt_info);
|
||||
- if (crypt_info) {
|
||||
- if (!crypt_info->ci_keyring_key ||
|
||||
- key_validate(crypt_info->ci_keyring_key) == 0)
|
||||
- return 0;
|
||||
- f2fs_free_encryption_info(inode, crypt_info);
|
||||
- goto retry;
|
||||
- }
|
||||
|
||||
res = f2fs_getxattr(inode, F2FS_XATTR_INDEX_ENCRYPTION,
|
||||
F2FS_XATTR_NAME_ENCRYPTION_CONTEXT,
|
||||
@@ -159,7 +152,6 @@ retry:
|
||||
crypt_info->ci_data_mode = ctx.contents_encryption_mode;
|
||||
crypt_info->ci_filename_mode = ctx.filenames_encryption_mode;
|
||||
crypt_info->ci_ctfm = NULL;
|
||||
- crypt_info->ci_keyring_key = NULL;
|
||||
memcpy(crypt_info->ci_master_key, ctx.master_key_descriptor,
|
||||
sizeof(crypt_info->ci_master_key));
|
||||
if (S_ISREG(inode->i_mode))
|
||||
@@ -197,7 +189,6 @@ retry:
|
||||
keyring_key = NULL;
|
||||
goto out;
|
||||
}
|
||||
- crypt_info->ci_keyring_key = keyring_key;
|
||||
BUG_ON(keyring_key->type != &key_type_logon);
|
||||
ukp = user_key_payload(keyring_key);
|
||||
if (ukp->datalen != sizeof(struct f2fs_encryption_key)) {
|
||||
@@ -230,17 +221,12 @@ retry:
|
||||
if (res)
|
||||
goto out;
|
||||
|
||||
- memzero_explicit(raw_key, sizeof(raw_key));
|
||||
- if (cmpxchg(&fi->i_crypt_info, NULL, crypt_info) != NULL) {
|
||||
- f2fs_free_crypt_info(crypt_info);
|
||||
- goto retry;
|
||||
- }
|
||||
- return 0;
|
||||
-
|
||||
+ if (cmpxchg(&fi->i_crypt_info, NULL, crypt_info) == NULL)
|
||||
+ crypt_info = NULL;
|
||||
out:
|
||||
if (res == -ENOKEY && !S_ISREG(inode->i_mode))
|
||||
res = 0;
|
||||
-
|
||||
+ key_put(keyring_key);
|
||||
f2fs_free_crypt_info(crypt_info);
|
||||
memzero_explicit(raw_key, sizeof(raw_key));
|
||||
return res;
|
||||
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
|
||||
index 9db5500d63d9..b1aeca83f4be 100644
|
||||
--- a/fs/f2fs/f2fs.h
|
||||
+++ b/fs/f2fs/f2fs.h
|
||||
@@ -2149,7 +2149,6 @@ void f2fs_end_io_crypto_work(struct f2fs_crypto_ctx *, struct bio *);
|
||||
|
||||
/* crypto_key.c */
|
||||
void f2fs_free_encryption_info(struct inode *, struct f2fs_crypt_info *);
|
||||
-int _f2fs_get_encryption_info(struct inode *inode);
|
||||
|
||||
/* crypto_fname.c */
|
||||
bool f2fs_valid_filenames_enc_mode(uint32_t);
|
||||
@@ -2170,18 +2169,7 @@ void f2fs_exit_crypto(void);
|
||||
|
||||
int f2fs_has_encryption_key(struct inode *);
|
||||
|
||||
-static inline int f2fs_get_encryption_info(struct inode *inode)
|
||||
-{
|
||||
- struct f2fs_crypt_info *ci = F2FS_I(inode)->i_crypt_info;
|
||||
-
|
||||
- if (!ci ||
|
||||
- (ci->ci_keyring_key &&
|
||||
- (ci->ci_keyring_key->flags & ((1 << KEY_FLAG_INVALIDATED) |
|
||||
- (1 << KEY_FLAG_REVOKED) |
|
||||
- (1 << KEY_FLAG_DEAD)))))
|
||||
- return _f2fs_get_encryption_info(inode);
|
||||
- return 0;
|
||||
-}
|
||||
+int f2fs_get_encryption_info(struct inode *inode);
|
||||
|
||||
void f2fs_fname_crypto_free_buffer(struct f2fs_str *);
|
||||
int f2fs_fname_setup_filename(struct inode *, const struct qstr *,
|
||||
diff --git a/fs/f2fs/f2fs_crypto.h b/fs/f2fs/f2fs_crypto.h
|
||||
index c2c1c2b63b25..f113f1a1e8c1 100644
|
||||
--- a/fs/f2fs/f2fs_crypto.h
|
||||
+++ b/fs/f2fs/f2fs_crypto.h
|
||||
@@ -79,7 +79,6 @@ struct f2fs_crypt_info {
|
||||
char ci_filename_mode;
|
||||
char ci_flags;
|
||||
struct crypto_ablkcipher *ci_ctfm;
|
||||
- struct key *ci_keyring_key;
|
||||
char ci_master_key[F2FS_KEY_DESCRIPTOR_SIZE];
|
||||
};
|
||||
|
||||
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
|
||||
index 8b0a15e285f9..e984f059e5fc 100644
|
||||
--- a/kernel/sched/deadline.c
|
||||
+++ b/kernel/sched/deadline.c
|
||||
@@ -1771,12 +1771,11 @@ static void switched_to_dl(struct rq *rq, struct task_struct *p)
|
||||
#ifdef CONFIG_SMP
|
||||
if (p->nr_cpus_allowed > 1 && rq->dl.overloaded)
|
||||
queue_push_tasks(rq);
|
||||
-#else
|
||||
+#endif
|
||||
if (dl_task(rq->curr))
|
||||
check_preempt_curr_dl(rq, p, 0);
|
||||
else
|
||||
resched_curr(rq);
|
||||
-#endif
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
|
||||
index 8ec86abe0ea1..78ae5c1d9412 100644
|
||||
--- a/kernel/sched/rt.c
|
||||
+++ b/kernel/sched/rt.c
|
||||
@@ -2136,10 +2136,9 @@ static void switched_to_rt(struct rq *rq, struct task_struct *p)
|
||||
#ifdef CONFIG_SMP
|
||||
if (p->nr_cpus_allowed > 1 && rq->rt.overloaded)
|
||||
queue_push_tasks(rq);
|
||||
-#else
|
||||
+#endif /* CONFIG_SMP */
|
||||
if (p->prio < rq->curr->prio)
|
||||
resched_curr(rq);
|
||||
-#endif /* CONFIG_SMP */
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
|
||||
index b5e665b3cfb0..36a50ef9295d 100644
|
||||
--- a/net/xfrm/xfrm_policy.c
|
||||
+++ b/net/xfrm/xfrm_policy.c
|
||||
@@ -3030,6 +3030,11 @@ static int __net_init xfrm_net_init(struct net *net)
|
||||
{
|
||||
int rv;
|
||||
|
||||
+ /* Initialize the per-net locks here */
|
||||
+ spin_lock_init(&net->xfrm.xfrm_state_lock);
|
||||
+ rwlock_init(&net->xfrm.xfrm_policy_lock);
|
||||
+ mutex_init(&net->xfrm.xfrm_cfg_mutex);
|
||||
+
|
||||
rv = xfrm_statistics_init(net);
|
||||
if (rv < 0)
|
||||
goto out_statistics;
|
||||
@@ -3046,11 +3051,6 @@ static int __net_init xfrm_net_init(struct net *net)
|
||||
if (rv < 0)
|
||||
goto out;
|
||||
|
||||
- /* Initialize the per-net locks here */
|
||||
- spin_lock_init(&net->xfrm.xfrm_state_lock);
|
||||
- rwlock_init(&net->xfrm.xfrm_policy_lock);
|
||||
- mutex_init(&net->xfrm.xfrm_cfg_mutex);
|
||||
-
|
||||
return 0;
|
||||
|
||||
out:
|
||||
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
|
||||
index 805681a7d356..7a5a64e70b4d 100644
|
||||
--- a/net/xfrm/xfrm_user.c
|
||||
+++ b/net/xfrm/xfrm_user.c
|
||||
@@ -412,7 +412,14 @@ static inline int xfrm_replay_verify_len(struct xfrm_replay_state_esn *replay_es
|
||||
up = nla_data(rp);
|
||||
ulen = xfrm_replay_state_esn_len(up);
|
||||
|
||||
- if (nla_len(rp) < ulen || xfrm_replay_state_esn_len(replay_esn) != ulen)
|
||||
+ /* Check the overall length and the internal bitmap length to avoid
|
||||
+ * potential overflow. */
|
||||
+ if (nla_len(rp) < ulen ||
|
||||
+ xfrm_replay_state_esn_len(replay_esn) != ulen ||
|
||||
+ replay_esn->bmp_len != up->bmp_len)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (up->replay_window > up->bmp_len * sizeof(__u32) * 8)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
1175
patch/kernel/s5p6818-default/03-patch-4.4.59-60.patch
Normal file
1175
patch/kernel/s5p6818-default/03-patch-4.4.59-60.patch
Normal file
File diff suppressed because it is too large
Load Diff
1527
patch/kernel/s5p6818-default/03-patch-4.4.60-61.patch
Normal file
1527
patch/kernel/s5p6818-default/03-patch-4.4.60-61.patch
Normal file
File diff suppressed because it is too large
Load Diff
839
patch/kernel/s5p6818-default/03-patch-4.4.61-62.patch
Normal file
839
patch/kernel/s5p6818-default/03-patch-4.4.61-62.patch
Normal file
@ -0,0 +1,839 @@
|
||||
diff --git a/Makefile b/Makefile
|
||||
index ef5045b8201d..0309acc34472 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 4
|
||||
-SUBLEVEL = 61
|
||||
+SUBLEVEL = 62
|
||||
EXTRAVERSION =
|
||||
NAME = Blurry Fish Butt
|
||||
|
||||
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
|
||||
index 75bfca69e418..d5cfa937d622 100644
|
||||
--- a/arch/mips/Kconfig
|
||||
+++ b/arch/mips/Kconfig
|
||||
@@ -9,6 +9,7 @@ config MIPS
|
||||
select HAVE_CONTEXT_TRACKING
|
||||
select HAVE_GENERIC_DMA_COHERENT
|
||||
select HAVE_IDE
|
||||
+ select HAVE_IRQ_EXIT_ON_IRQ_STACK
|
||||
select HAVE_OPROFILE
|
||||
select HAVE_PERF_EVENTS
|
||||
select PERF_USE_VMALLOC
|
||||
diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h
|
||||
index 15e0fecbc300..ebb9efb02502 100644
|
||||
--- a/arch/mips/include/asm/irq.h
|
||||
+++ b/arch/mips/include/asm/irq.h
|
||||
@@ -17,6 +17,18 @@
|
||||
|
||||
#include <irq.h>
|
||||
|
||||
+#define IRQ_STACK_SIZE THREAD_SIZE
|
||||
+
|
||||
+extern void *irq_stack[NR_CPUS];
|
||||
+
|
||||
+static inline bool on_irq_stack(int cpu, unsigned long sp)
|
||||
+{
|
||||
+ unsigned long low = (unsigned long)irq_stack[cpu];
|
||||
+ unsigned long high = low + IRQ_STACK_SIZE;
|
||||
+
|
||||
+ return (low <= sp && sp <= high);
|
||||
+}
|
||||
+
|
||||
#ifdef CONFIG_I8259
|
||||
static inline int irq_canonicalize(int irq)
|
||||
{
|
||||
diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h
|
||||
index a71da576883c..5347f130f536 100644
|
||||
--- a/arch/mips/include/asm/stackframe.h
|
||||
+++ b/arch/mips/include/asm/stackframe.h
|
||||
@@ -216,12 +216,19 @@
|
||||
LONG_S $25, PT_R25(sp)
|
||||
LONG_S $28, PT_R28(sp)
|
||||
LONG_S $31, PT_R31(sp)
|
||||
+
|
||||
+ /* Set thread_info if we're coming from user mode */
|
||||
+ mfc0 k0, CP0_STATUS
|
||||
+ sll k0, 3 /* extract cu0 bit */
|
||||
+ bltz k0, 9f
|
||||
+
|
||||
ori $28, sp, _THREAD_MASK
|
||||
xori $28, _THREAD_MASK
|
||||
#ifdef CONFIG_CPU_CAVIUM_OCTEON
|
||||
.set mips64
|
||||
pref 0, 0($28) /* Prefetch the current pointer */
|
||||
#endif
|
||||
+9:
|
||||
.set pop
|
||||
.endm
|
||||
|
||||
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
|
||||
index 154e2039ea5e..ec053ce7bb38 100644
|
||||
--- a/arch/mips/kernel/asm-offsets.c
|
||||
+++ b/arch/mips/kernel/asm-offsets.c
|
||||
@@ -101,6 +101,7 @@ void output_thread_info_defines(void)
|
||||
OFFSET(TI_REGS, thread_info, regs);
|
||||
DEFINE(_THREAD_SIZE, THREAD_SIZE);
|
||||
DEFINE(_THREAD_MASK, THREAD_MASK);
|
||||
+ DEFINE(_IRQ_STACK_SIZE, IRQ_STACK_SIZE);
|
||||
BLANK();
|
||||
}
|
||||
|
||||
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
|
||||
index baa7b6fc0a60..619e30e2c4f0 100644
|
||||
--- a/arch/mips/kernel/genex.S
|
||||
+++ b/arch/mips/kernel/genex.S
|
||||
@@ -188,9 +188,44 @@ NESTED(handle_int, PT_SIZE, sp)
|
||||
|
||||
LONG_L s0, TI_REGS($28)
|
||||
LONG_S sp, TI_REGS($28)
|
||||
- PTR_LA ra, ret_from_irq
|
||||
- PTR_LA v0, plat_irq_dispatch
|
||||
- jr v0
|
||||
+
|
||||
+ /*
|
||||
+ * SAVE_ALL ensures we are using a valid kernel stack for the thread.
|
||||
+ * Check if we are already using the IRQ stack.
|
||||
+ */
|
||||
+ move s1, sp # Preserve the sp
|
||||
+
|
||||
+ /* Get IRQ stack for this CPU */
|
||||
+ ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG
|
||||
+#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
|
||||
+ lui k1, %hi(irq_stack)
|
||||
+#else
|
||||
+ lui k1, %highest(irq_stack)
|
||||
+ daddiu k1, %higher(irq_stack)
|
||||
+ dsll k1, 16
|
||||
+ daddiu k1, %hi(irq_stack)
|
||||
+ dsll k1, 16
|
||||
+#endif
|
||||
+ LONG_SRL k0, SMP_CPUID_PTRSHIFT
|
||||
+ LONG_ADDU k1, k0
|
||||
+ LONG_L t0, %lo(irq_stack)(k1)
|
||||
+
|
||||
+ # Check if already on IRQ stack
|
||||
+ PTR_LI t1, ~(_THREAD_SIZE-1)
|
||||
+ and t1, t1, sp
|
||||
+ beq t0, t1, 2f
|
||||
+
|
||||
+ /* Switch to IRQ stack */
|
||||
+ li t1, _IRQ_STACK_SIZE
|
||||
+ PTR_ADD sp, t0, t1
|
||||
+
|
||||
+2:
|
||||
+ jal plat_irq_dispatch
|
||||
+
|
||||
+ /* Restore sp */
|
||||
+ move sp, s1
|
||||
+
|
||||
+ j ret_from_irq
|
||||
#ifdef CONFIG_CPU_MICROMIPS
|
||||
nop
|
||||
#endif
|
||||
@@ -263,8 +298,44 @@ NESTED(except_vec_vi_handler, 0, sp)
|
||||
|
||||
LONG_L s0, TI_REGS($28)
|
||||
LONG_S sp, TI_REGS($28)
|
||||
- PTR_LA ra, ret_from_irq
|
||||
- jr v0
|
||||
+
|
||||
+ /*
|
||||
+ * SAVE_ALL ensures we are using a valid kernel stack for the thread.
|
||||
+ * Check if we are already using the IRQ stack.
|
||||
+ */
|
||||
+ move s1, sp # Preserve the sp
|
||||
+
|
||||
+ /* Get IRQ stack for this CPU */
|
||||
+ ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG
|
||||
+#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
|
||||
+ lui k1, %hi(irq_stack)
|
||||
+#else
|
||||
+ lui k1, %highest(irq_stack)
|
||||
+ daddiu k1, %higher(irq_stack)
|
||||
+ dsll k1, 16
|
||||
+ daddiu k1, %hi(irq_stack)
|
||||
+ dsll k1, 16
|
||||
+#endif
|
||||
+ LONG_SRL k0, SMP_CPUID_PTRSHIFT
|
||||
+ LONG_ADDU k1, k0
|
||||
+ LONG_L t0, %lo(irq_stack)(k1)
|
||||
+
|
||||
+ # Check if already on IRQ stack
|
||||
+ PTR_LI t1, ~(_THREAD_SIZE-1)
|
||||
+ and t1, t1, sp
|
||||
+ beq t0, t1, 2f
|
||||
+
|
||||
+ /* Switch to IRQ stack */
|
||||
+ li t1, _IRQ_STACK_SIZE
|
||||
+ PTR_ADD sp, t0, t1
|
||||
+
|
||||
+2:
|
||||
+ jalr v0
|
||||
+
|
||||
+ /* Restore sp */
|
||||
+ move sp, s1
|
||||
+
|
||||
+ j ret_from_irq
|
||||
END(except_vec_vi_handler)
|
||||
|
||||
/*
|
||||
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
|
||||
index 8eb5af805964..dc1180a8bfa1 100644
|
||||
--- a/arch/mips/kernel/irq.c
|
||||
+++ b/arch/mips/kernel/irq.c
|
||||
@@ -25,6 +25,8 @@
|
||||
#include <linux/atomic.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
+void *irq_stack[NR_CPUS];
|
||||
+
|
||||
/*
|
||||
* 'what should we do if we get a hw irq event on an illegal vector'.
|
||||
* each architecture has to answer this themselves.
|
||||
@@ -55,6 +57,15 @@ void __init init_IRQ(void)
|
||||
irq_set_noprobe(i);
|
||||
|
||||
arch_init_irq();
|
||||
+
|
||||
+ for_each_possible_cpu(i) {
|
||||
+ int irq_pages = IRQ_STACK_SIZE / PAGE_SIZE;
|
||||
+ void *s = (void *)__get_free_pages(GFP_KERNEL, irq_pages);
|
||||
+
|
||||
+ irq_stack[i] = s;
|
||||
+ pr_debug("CPU%d IRQ stack at 0x%p - 0x%p\n", i,
|
||||
+ irq_stack[i], irq_stack[i] + IRQ_STACK_SIZE);
|
||||
+ }
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_STACKOVERFLOW
|
||||
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
|
||||
index fc537d1b649d..8c26ecac930d 100644
|
||||
--- a/arch/mips/kernel/process.c
|
||||
+++ b/arch/mips/kernel/process.c
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/dsp.h>
|
||||
#include <asm/fpu.h>
|
||||
+#include <asm/irq.h>
|
||||
#include <asm/msa.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/mipsregs.h>
|
||||
@@ -552,7 +553,19 @@ EXPORT_SYMBOL(unwind_stack_by_address);
|
||||
unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
|
||||
unsigned long pc, unsigned long *ra)
|
||||
{
|
||||
- unsigned long stack_page = (unsigned long)task_stack_page(task);
|
||||
+ unsigned long stack_page = 0;
|
||||
+ int cpu;
|
||||
+
|
||||
+ for_each_possible_cpu(cpu) {
|
||||
+ if (on_irq_stack(cpu, *sp)) {
|
||||
+ stack_page = (unsigned long)irq_stack[cpu];
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!stack_page)
|
||||
+ stack_page = (unsigned long)task_stack_page(task);
|
||||
+
|
||||
return unwind_stack_by_address(stack_page, sp, pc, ra);
|
||||
}
|
||||
#endif
|
||||
diff --git a/block/blk-mq.c b/block/blk-mq.c
|
||||
index d8d63c38bf29..0d1af3e44efb 100644
|
||||
--- a/block/blk-mq.c
|
||||
+++ b/block/blk-mq.c
|
||||
@@ -1470,7 +1470,7 @@ static struct blk_mq_tags *blk_mq_init_rq_map(struct blk_mq_tag_set *set,
|
||||
INIT_LIST_HEAD(&tags->page_list);
|
||||
|
||||
tags->rqs = kzalloc_node(set->queue_depth * sizeof(struct request *),
|
||||
- GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY,
|
||||
+ GFP_NOIO | __GFP_NOWARN | __GFP_NORETRY,
|
||||
set->numa_node);
|
||||
if (!tags->rqs) {
|
||||
blk_mq_free_tags(tags);
|
||||
@@ -1496,7 +1496,7 @@ static struct blk_mq_tags *blk_mq_init_rq_map(struct blk_mq_tag_set *set,
|
||||
|
||||
do {
|
||||
page = alloc_pages_node(set->numa_node,
|
||||
- GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY | __GFP_ZERO,
|
||||
+ GFP_NOIO | __GFP_NOWARN | __GFP_NORETRY | __GFP_ZERO,
|
||||
this_order);
|
||||
if (page)
|
||||
break;
|
||||
@@ -1517,7 +1517,7 @@ static struct blk_mq_tags *blk_mq_init_rq_map(struct blk_mq_tag_set *set,
|
||||
* Allow kmemleak to scan these pages as they contain pointers
|
||||
* to additional allocations like via ops->init_request().
|
||||
*/
|
||||
- kmemleak_alloc(p, order_to_size(this_order), 1, GFP_KERNEL);
|
||||
+ kmemleak_alloc(p, order_to_size(this_order), 1, GFP_NOIO);
|
||||
entries_per_page = order_to_size(this_order) / rq_size;
|
||||
to_do = min(entries_per_page, set->queue_depth - i);
|
||||
left -= to_do * rq_size;
|
||||
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
|
||||
index 69d4a1326fee..53e61459c69f 100644
|
||||
--- a/drivers/crypto/caam/ctrl.c
|
||||
+++ b/drivers/crypto/caam/ctrl.c
|
||||
@@ -278,7 +278,8 @@ static int deinstantiate_rng(struct device *ctrldev, int state_handle_mask)
|
||||
/* Try to run it through DECO0 */
|
||||
ret = run_descriptor_deco0(ctrldev, desc, &status);
|
||||
|
||||
- if (ret || status) {
|
||||
+ if (ret ||
|
||||
+ (status && status != JRSTA_SSRC_JUMP_HALT_CC)) {
|
||||
dev_err(ctrldev,
|
||||
"Failed to deinstantiate RNG4 SH%d\n",
|
||||
sh_idx);
|
||||
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
|
||||
index fb9f647bb5cd..5044f2257e89 100644
|
||||
--- a/drivers/gpu/drm/i915/i915_drv.h
|
||||
+++ b/drivers/gpu/drm/i915/i915_drv.h
|
||||
@@ -1159,7 +1159,7 @@ struct intel_gen6_power_mgmt {
|
||||
struct intel_rps_client semaphores, mmioflips;
|
||||
|
||||
/* manual wa residency calculations */
|
||||
- struct intel_rps_ei up_ei, down_ei;
|
||||
+ struct intel_rps_ei ei;
|
||||
|
||||
/*
|
||||
* Protects RPS/RC6 register access and PCU communication.
|
||||
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
|
||||
index 0f42a2782afc..b7b0a38acd67 100644
|
||||
--- a/drivers/gpu/drm/i915/i915_irq.c
|
||||
+++ b/drivers/gpu/drm/i915/i915_irq.c
|
||||
@@ -994,68 +994,51 @@ static void vlv_c0_read(struct drm_i915_private *dev_priv,
|
||||
ei->media_c0 = I915_READ(VLV_MEDIA_C0_COUNT);
|
||||
}
|
||||
|
||||
-static bool vlv_c0_above(struct drm_i915_private *dev_priv,
|
||||
- const struct intel_rps_ei *old,
|
||||
- const struct intel_rps_ei *now,
|
||||
- int threshold)
|
||||
-{
|
||||
- u64 time, c0;
|
||||
- unsigned int mul = 100;
|
||||
-
|
||||
- if (old->cz_clock == 0)
|
||||
- return false;
|
||||
-
|
||||
- if (I915_READ(VLV_COUNTER_CONTROL) & VLV_COUNT_RANGE_HIGH)
|
||||
- mul <<= 8;
|
||||
-
|
||||
- time = now->cz_clock - old->cz_clock;
|
||||
- time *= threshold * dev_priv->czclk_freq;
|
||||
-
|
||||
- /* Workload can be split between render + media, e.g. SwapBuffers
|
||||
- * being blitted in X after being rendered in mesa. To account for
|
||||
- * this we need to combine both engines into our activity counter.
|
||||
- */
|
||||
- c0 = now->render_c0 - old->render_c0;
|
||||
- c0 += now->media_c0 - old->media_c0;
|
||||
- c0 *= mul * VLV_CZ_CLOCK_TO_MILLI_SEC;
|
||||
-
|
||||
- return c0 >= time;
|
||||
-}
|
||||
-
|
||||
void gen6_rps_reset_ei(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
- vlv_c0_read(dev_priv, &dev_priv->rps.down_ei);
|
||||
- dev_priv->rps.up_ei = dev_priv->rps.down_ei;
|
||||
+ memset(&dev_priv->rps.ei, 0, sizeof(dev_priv->rps.ei));
|
||||
}
|
||||
|
||||
static u32 vlv_wa_c0_ei(struct drm_i915_private *dev_priv, u32 pm_iir)
|
||||
{
|
||||
+ const struct intel_rps_ei *prev = &dev_priv->rps.ei;
|
||||
struct intel_rps_ei now;
|
||||
u32 events = 0;
|
||||
|
||||
- if ((pm_iir & (GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED)) == 0)
|
||||
+ if ((pm_iir & GEN6_PM_RP_UP_EI_EXPIRED) == 0)
|
||||
return 0;
|
||||
|
||||
vlv_c0_read(dev_priv, &now);
|
||||
if (now.cz_clock == 0)
|
||||
return 0;
|
||||
|
||||
- if (pm_iir & GEN6_PM_RP_DOWN_EI_EXPIRED) {
|
||||
- if (!vlv_c0_above(dev_priv,
|
||||
- &dev_priv->rps.down_ei, &now,
|
||||
- dev_priv->rps.down_threshold))
|
||||
- events |= GEN6_PM_RP_DOWN_THRESHOLD;
|
||||
- dev_priv->rps.down_ei = now;
|
||||
- }
|
||||
+ if (prev->cz_clock) {
|
||||
+ u64 time, c0;
|
||||
+ unsigned int mul;
|
||||
|
||||
- if (pm_iir & GEN6_PM_RP_UP_EI_EXPIRED) {
|
||||
- if (vlv_c0_above(dev_priv,
|
||||
- &dev_priv->rps.up_ei, &now,
|
||||
- dev_priv->rps.up_threshold))
|
||||
- events |= GEN6_PM_RP_UP_THRESHOLD;
|
||||
- dev_priv->rps.up_ei = now;
|
||||
+ mul = VLV_CZ_CLOCK_TO_MILLI_SEC * 100; /* scale to threshold% */
|
||||
+ if (I915_READ(VLV_COUNTER_CONTROL) & VLV_COUNT_RANGE_HIGH)
|
||||
+ mul <<= 8;
|
||||
+
|
||||
+ time = now.cz_clock - prev->cz_clock;
|
||||
+ time *= dev_priv->czclk_freq;
|
||||
+
|
||||
+ /* Workload can be split between render + media,
|
||||
+ * e.g. SwapBuffers being blitted in X after being rendered in
|
||||
+ * mesa. To account for this we need to combine both engines
|
||||
+ * into our activity counter.
|
||||
+ */
|
||||
+ c0 = now.render_c0 - prev->render_c0;
|
||||
+ c0 += now.media_c0 - prev->media_c0;
|
||||
+ c0 *= mul;
|
||||
+
|
||||
+ if (c0 > time * dev_priv->rps.up_threshold)
|
||||
+ events = GEN6_PM_RP_UP_THRESHOLD;
|
||||
+ else if (c0 < time * dev_priv->rps.down_threshold)
|
||||
+ events = GEN6_PM_RP_DOWN_THRESHOLD;
|
||||
}
|
||||
|
||||
+ dev_priv->rps.ei = now;
|
||||
return events;
|
||||
}
|
||||
|
||||
@@ -4390,7 +4373,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
|
||||
/* Let's track the enabled rps events */
|
||||
if (IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv))
|
||||
/* WaGsvRC0ResidencyMethod:vlv */
|
||||
- dev_priv->pm_rps_events = GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED;
|
||||
+ dev_priv->pm_rps_events = GEN6_PM_RP_UP_EI_EXPIRED;
|
||||
else
|
||||
dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS;
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
|
||||
index e7c18519274a..fd4690ed93c0 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_pm.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_pm.c
|
||||
@@ -4376,6 +4376,12 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val)
|
||||
break;
|
||||
}
|
||||
|
||||
+ /* When byt can survive without system hang with dynamic
|
||||
+ * sw freq adjustments, this restriction can be lifted.
|
||||
+ */
|
||||
+ if (IS_VALLEYVIEW(dev_priv))
|
||||
+ goto skip_hw_write;
|
||||
+
|
||||
I915_WRITE(GEN6_RP_UP_EI,
|
||||
GT_INTERVAL_FROM_US(dev_priv, ei_up));
|
||||
I915_WRITE(GEN6_RP_UP_THRESHOLD,
|
||||
@@ -4394,6 +4400,7 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val)
|
||||
GEN6_RP_UP_BUSY_AVG |
|
||||
GEN6_RP_DOWN_IDLE_AVG);
|
||||
|
||||
+skip_hw_write:
|
||||
dev_priv->rps.power = new_power;
|
||||
dev_priv->rps.up_threshold = threshold_up;
|
||||
dev_priv->rps.down_threshold = threshold_down;
|
||||
@@ -4404,8 +4411,9 @@ static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val)
|
||||
{
|
||||
u32 mask = 0;
|
||||
|
||||
+ /* We use UP_EI_EXPIRED interupts for both up/down in manual mode */
|
||||
if (val > dev_priv->rps.min_freq_softlimit)
|
||||
- mask |= GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT;
|
||||
+ mask |= GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT;
|
||||
if (val < dev_priv->rps.max_freq_softlimit)
|
||||
mask |= GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_UP_THRESHOLD;
|
||||
|
||||
@@ -4509,7 +4517,7 @@ void gen6_rps_busy(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
mutex_lock(&dev_priv->rps.hw_lock);
|
||||
if (dev_priv->rps.enabled) {
|
||||
- if (dev_priv->pm_rps_events & (GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED))
|
||||
+ if (dev_priv->pm_rps_events & GEN6_PM_RP_UP_EI_EXPIRED)
|
||||
gen6_rps_reset_ei(dev_priv);
|
||||
I915_WRITE(GEN6_PMINTRMSK,
|
||||
gen6_rps_pm_mask(dev_priv, dev_priv->rps.cur_freq));
|
||||
diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c
|
||||
index c0720c1ee4c9..5abab8800891 100644
|
||||
--- a/drivers/mtd/bcm47xxpart.c
|
||||
+++ b/drivers/mtd/bcm47xxpart.c
|
||||
@@ -225,12 +225,10 @@ static int bcm47xxpart_parse(struct mtd_info *master,
|
||||
|
||||
last_trx_part = curr_part - 1;
|
||||
|
||||
- /*
|
||||
- * We have whole TRX scanned, skip to the next part. Use
|
||||
- * roundown (not roundup), as the loop will increase
|
||||
- * offset in next step.
|
||||
- */
|
||||
- offset = rounddown(offset + trx->length, blocksize);
|
||||
+ /* Jump to the end of TRX */
|
||||
+ offset = roundup(offset + trx->length, blocksize);
|
||||
+ /* Next loop iteration will increase the offset */
|
||||
+ offset -= blocksize;
|
||||
continue;
|
||||
}
|
||||
|
||||
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c
|
||||
index 7af870a3c549..855c43d8f7e0 100644
|
||||
--- a/drivers/net/ethernet/ibm/ibmveth.c
|
||||
+++ b/drivers/net/ethernet/ibm/ibmveth.c
|
||||
@@ -58,7 +58,7 @@ static struct kobj_type ktype_veth_pool;
|
||||
|
||||
static const char ibmveth_driver_name[] = "ibmveth";
|
||||
static const char ibmveth_driver_string[] = "IBM Power Virtual Ethernet Driver";
|
||||
-#define ibmveth_driver_version "1.05"
|
||||
+#define ibmveth_driver_version "1.06"
|
||||
|
||||
MODULE_AUTHOR("Santiago Leon <santil@linux.vnet.ibm.com>");
|
||||
MODULE_DESCRIPTION("IBM Power Virtual Ethernet Driver");
|
||||
@@ -137,6 +137,11 @@ static inline int ibmveth_rxq_frame_offset(struct ibmveth_adapter *adapter)
|
||||
return ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_OFF_MASK;
|
||||
}
|
||||
|
||||
+static inline int ibmveth_rxq_large_packet(struct ibmveth_adapter *adapter)
|
||||
+{
|
||||
+ return ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_LRG_PKT;
|
||||
+}
|
||||
+
|
||||
static inline int ibmveth_rxq_frame_length(struct ibmveth_adapter *adapter)
|
||||
{
|
||||
return be32_to_cpu(adapter->rx_queue.queue_addr[adapter->rx_queue.index].length);
|
||||
@@ -1172,6 +1177,45 @@ map_failed:
|
||||
goto retry_bounce;
|
||||
}
|
||||
|
||||
+static void ibmveth_rx_mss_helper(struct sk_buff *skb, u16 mss, int lrg_pkt)
|
||||
+{
|
||||
+ int offset = 0;
|
||||
+
|
||||
+ /* only TCP packets will be aggregated */
|
||||
+ if (skb->protocol == htons(ETH_P_IP)) {
|
||||
+ struct iphdr *iph = (struct iphdr *)skb->data;
|
||||
+
|
||||
+ if (iph->protocol == IPPROTO_TCP) {
|
||||
+ offset = iph->ihl * 4;
|
||||
+ skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
|
||||
+ } else {
|
||||
+ return;
|
||||
+ }
|
||||
+ } else if (skb->protocol == htons(ETH_P_IPV6)) {
|
||||
+ struct ipv6hdr *iph6 = (struct ipv6hdr *)skb->data;
|
||||
+
|
||||
+ if (iph6->nexthdr == IPPROTO_TCP) {
|
||||
+ offset = sizeof(struct ipv6hdr);
|
||||
+ skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
|
||||
+ } else {
|
||||
+ return;
|
||||
+ }
|
||||
+ } else {
|
||||
+ return;
|
||||
+ }
|
||||
+ /* if mss is not set through Large Packet bit/mss in rx buffer,
|
||||
+ * expect that the mss will be written to the tcp header checksum.
|
||||
+ */
|
||||
+ if (lrg_pkt) {
|
||||
+ skb_shinfo(skb)->gso_size = mss;
|
||||
+ } else if (offset) {
|
||||
+ struct tcphdr *tcph = (struct tcphdr *)(skb->data + offset);
|
||||
+
|
||||
+ skb_shinfo(skb)->gso_size = ntohs(tcph->check);
|
||||
+ tcph->check = 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int ibmveth_poll(struct napi_struct *napi, int budget)
|
||||
{
|
||||
struct ibmveth_adapter *adapter =
|
||||
@@ -1180,6 +1224,7 @@ static int ibmveth_poll(struct napi_struct *napi, int budget)
|
||||
int frames_processed = 0;
|
||||
unsigned long lpar_rc;
|
||||
struct iphdr *iph;
|
||||
+ u16 mss = 0;
|
||||
|
||||
restart_poll:
|
||||
while (frames_processed < budget) {
|
||||
@@ -1197,9 +1242,21 @@ restart_poll:
|
||||
int length = ibmveth_rxq_frame_length(adapter);
|
||||
int offset = ibmveth_rxq_frame_offset(adapter);
|
||||
int csum_good = ibmveth_rxq_csum_good(adapter);
|
||||
+ int lrg_pkt = ibmveth_rxq_large_packet(adapter);
|
||||
|
||||
skb = ibmveth_rxq_get_buffer(adapter);
|
||||
|
||||
+ /* if the large packet bit is set in the rx queue
|
||||
+ * descriptor, the mss will be written by PHYP eight
|
||||
+ * bytes from the start of the rx buffer, which is
|
||||
+ * skb->data at this stage
|
||||
+ */
|
||||
+ if (lrg_pkt) {
|
||||
+ __be64 *rxmss = (__be64 *)(skb->data + 8);
|
||||
+
|
||||
+ mss = (u16)be64_to_cpu(*rxmss);
|
||||
+ }
|
||||
+
|
||||
new_skb = NULL;
|
||||
if (length < rx_copybreak)
|
||||
new_skb = netdev_alloc_skb(netdev, length);
|
||||
@@ -1233,11 +1290,15 @@ restart_poll:
|
||||
if (iph->check == 0xffff) {
|
||||
iph->check = 0;
|
||||
iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
|
||||
- adapter->rx_large_packets++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+ if (length > netdev->mtu + ETH_HLEN) {
|
||||
+ ibmveth_rx_mss_helper(skb, mss, lrg_pkt);
|
||||
+ adapter->rx_large_packets++;
|
||||
+ }
|
||||
+
|
||||
napi_gro_receive(napi, skb); /* send it up */
|
||||
|
||||
netdev->stats.rx_packets++;
|
||||
diff --git a/drivers/net/ethernet/ibm/ibmveth.h b/drivers/net/ethernet/ibm/ibmveth.h
|
||||
index 4eade67fe30c..7acda04d034e 100644
|
||||
--- a/drivers/net/ethernet/ibm/ibmveth.h
|
||||
+++ b/drivers/net/ethernet/ibm/ibmveth.h
|
||||
@@ -209,6 +209,7 @@ struct ibmveth_rx_q_entry {
|
||||
#define IBMVETH_RXQ_TOGGLE 0x80000000
|
||||
#define IBMVETH_RXQ_TOGGLE_SHIFT 31
|
||||
#define IBMVETH_RXQ_VALID 0x40000000
|
||||
+#define IBMVETH_RXQ_LRG_PKT 0x04000000
|
||||
#define IBMVETH_RXQ_NO_CSUM 0x02000000
|
||||
#define IBMVETH_RXQ_CSUM_GOOD 0x01000000
|
||||
#define IBMVETH_RXQ_OFF_MASK 0x0000FFFF
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlx4/cq.c b/drivers/net/ethernet/mellanox/mlx4/cq.c
|
||||
index 3348e646db70..6eba58044456 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlx4/cq.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlx4/cq.c
|
||||
@@ -101,13 +101,19 @@ void mlx4_cq_completion(struct mlx4_dev *dev, u32 cqn)
|
||||
{
|
||||
struct mlx4_cq *cq;
|
||||
|
||||
+ rcu_read_lock();
|
||||
cq = radix_tree_lookup(&mlx4_priv(dev)->cq_table.tree,
|
||||
cqn & (dev->caps.num_cqs - 1));
|
||||
+ rcu_read_unlock();
|
||||
+
|
||||
if (!cq) {
|
||||
mlx4_dbg(dev, "Completion event for bogus CQ %08x\n", cqn);
|
||||
return;
|
||||
}
|
||||
|
||||
+ /* Acessing the CQ outside of rcu_read_lock is safe, because
|
||||
+ * the CQ is freed only after interrupt handling is completed.
|
||||
+ */
|
||||
++cq->arm_sn;
|
||||
|
||||
cq->comp(cq);
|
||||
@@ -118,23 +124,19 @@ void mlx4_cq_event(struct mlx4_dev *dev, u32 cqn, int event_type)
|
||||
struct mlx4_cq_table *cq_table = &mlx4_priv(dev)->cq_table;
|
||||
struct mlx4_cq *cq;
|
||||
|
||||
- spin_lock(&cq_table->lock);
|
||||
-
|
||||
+ rcu_read_lock();
|
||||
cq = radix_tree_lookup(&cq_table->tree, cqn & (dev->caps.num_cqs - 1));
|
||||
- if (cq)
|
||||
- atomic_inc(&cq->refcount);
|
||||
-
|
||||
- spin_unlock(&cq_table->lock);
|
||||
+ rcu_read_unlock();
|
||||
|
||||
if (!cq) {
|
||||
- mlx4_warn(dev, "Async event for bogus CQ %08x\n", cqn);
|
||||
+ mlx4_dbg(dev, "Async event for bogus CQ %08x\n", cqn);
|
||||
return;
|
||||
}
|
||||
|
||||
+ /* Acessing the CQ outside of rcu_read_lock is safe, because
|
||||
+ * the CQ is freed only after interrupt handling is completed.
|
||||
+ */
|
||||
cq->event(cq, event_type);
|
||||
-
|
||||
- if (atomic_dec_and_test(&cq->refcount))
|
||||
- complete(&cq->free);
|
||||
}
|
||||
|
||||
static int mlx4_SW2HW_CQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,
|
||||
@@ -301,9 +303,9 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- spin_lock_irq(&cq_table->lock);
|
||||
+ spin_lock(&cq_table->lock);
|
||||
err = radix_tree_insert(&cq_table->tree, cq->cqn, cq);
|
||||
- spin_unlock_irq(&cq_table->lock);
|
||||
+ spin_unlock(&cq_table->lock);
|
||||
if (err)
|
||||
goto err_icm;
|
||||
|
||||
@@ -347,9 +349,9 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent,
|
||||
return 0;
|
||||
|
||||
err_radix:
|
||||
- spin_lock_irq(&cq_table->lock);
|
||||
+ spin_lock(&cq_table->lock);
|
||||
radix_tree_delete(&cq_table->tree, cq->cqn);
|
||||
- spin_unlock_irq(&cq_table->lock);
|
||||
+ spin_unlock(&cq_table->lock);
|
||||
|
||||
err_icm:
|
||||
mlx4_cq_free_icm(dev, cq->cqn);
|
||||
@@ -368,15 +370,15 @@ void mlx4_cq_free(struct mlx4_dev *dev, struct mlx4_cq *cq)
|
||||
if (err)
|
||||
mlx4_warn(dev, "HW2SW_CQ failed (%d) for CQN %06x\n", err, cq->cqn);
|
||||
|
||||
+ spin_lock(&cq_table->lock);
|
||||
+ radix_tree_delete(&cq_table->tree, cq->cqn);
|
||||
+ spin_unlock(&cq_table->lock);
|
||||
+
|
||||
synchronize_irq(priv->eq_table.eq[MLX4_CQ_TO_EQ_VECTOR(cq->vector)].irq);
|
||||
if (priv->eq_table.eq[MLX4_CQ_TO_EQ_VECTOR(cq->vector)].irq !=
|
||||
priv->eq_table.eq[MLX4_EQ_ASYNC].irq)
|
||||
synchronize_irq(priv->eq_table.eq[MLX4_EQ_ASYNC].irq);
|
||||
|
||||
- spin_lock_irq(&cq_table->lock);
|
||||
- radix_tree_delete(&cq_table->tree, cq->cqn);
|
||||
- spin_unlock_irq(&cq_table->lock);
|
||||
-
|
||||
if (atomic_dec_and_test(&cq->refcount))
|
||||
complete(&cq->free);
|
||||
wait_for_completion(&cq->free);
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
|
||||
index 28a4b34310b2..82bf1b539d87 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
|
||||
@@ -439,8 +439,14 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv)
|
||||
ring->cqn = priv->rx_cq[ring_ind]->mcq.cqn;
|
||||
|
||||
ring->stride = stride;
|
||||
- if (ring->stride <= TXBB_SIZE)
|
||||
+ if (ring->stride <= TXBB_SIZE) {
|
||||
+ /* Stamp first unused send wqe */
|
||||
+ __be32 *ptr = (__be32 *)ring->buf;
|
||||
+ __be32 stamp = cpu_to_be32(1 << STAMP_SHIFT);
|
||||
+ *ptr = stamp;
|
||||
+ /* Move pointer to start of rx section */
|
||||
ring->buf += TXBB_SIZE;
|
||||
+ }
|
||||
|
||||
ring->log_stride = ffs(ring->stride) - 1;
|
||||
ring->buf_size = ring->size * ring->stride;
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
|
||||
index d314d96dcb1c..d1fc7fa87b05 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
|
||||
@@ -2955,6 +2955,9 @@ int mlx4_RST2INIT_QP_wrapper(struct mlx4_dev *dev, int slave,
|
||||
put_res(dev, slave, srqn, RES_SRQ);
|
||||
qp->srq = srq;
|
||||
}
|
||||
+
|
||||
+ /* Save param3 for dynamic changes from VST back to VGT */
|
||||
+ qp->param3 = qpc->param3;
|
||||
put_res(dev, slave, rcqn, RES_CQ);
|
||||
put_res(dev, slave, mtt_base, RES_MTT);
|
||||
res_end_move(dev, slave, RES_QP, qpn);
|
||||
@@ -3747,7 +3750,6 @@ int mlx4_INIT2RTR_QP_wrapper(struct mlx4_dev *dev, int slave,
|
||||
int qpn = vhcr->in_modifier & 0x7fffff;
|
||||
struct res_qp *qp;
|
||||
u8 orig_sched_queue;
|
||||
- __be32 orig_param3 = qpc->param3;
|
||||
u8 orig_vlan_control = qpc->pri_path.vlan_control;
|
||||
u8 orig_fvl_rx = qpc->pri_path.fvl_rx;
|
||||
u8 orig_pri_path_fl = qpc->pri_path.fl;
|
||||
@@ -3789,7 +3791,6 @@ out:
|
||||
*/
|
||||
if (!err) {
|
||||
qp->sched_queue = orig_sched_queue;
|
||||
- qp->param3 = orig_param3;
|
||||
qp->vlan_control = orig_vlan_control;
|
||||
qp->fvl_rx = orig_fvl_rx;
|
||||
qp->pri_path_fl = orig_pri_path_fl;
|
||||
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
|
||||
index 9e62c93af96e..7c2d87befb51 100644
|
||||
--- a/drivers/usb/core/hub.c
|
||||
+++ b/drivers/usb/core/hub.c
|
||||
@@ -2602,8 +2602,15 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1,
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
- /* The port state is unknown until the reset completes. */
|
||||
- if (!(portstatus & USB_PORT_STAT_RESET))
|
||||
+ /*
|
||||
+ * The port state is unknown until the reset completes.
|
||||
+ *
|
||||
+ * On top of that, some chips may require additional time
|
||||
+ * to re-establish a connection after the reset is complete,
|
||||
+ * so also wait for the connection to be re-established.
|
||||
+ */
|
||||
+ if (!(portstatus & USB_PORT_STAT_RESET) &&
|
||||
+ (portstatus & USB_PORT_STAT_CONNECTION))
|
||||
break;
|
||||
|
||||
/* switch to the long delay after two short delay failures */
|
||||
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
|
||||
index 210ff64857e1..ec7a50f98f57 100644
|
||||
--- a/drivers/usb/dwc3/gadget.c
|
||||
+++ b/drivers/usb/dwc3/gadget.c
|
||||
@@ -235,6 +235,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
|
||||
int status)
|
||||
{
|
||||
struct dwc3 *dwc = dep->dwc;
|
||||
+ unsigned int unmap_after_complete = false;
|
||||
int i;
|
||||
|
||||
if (req->queued) {
|
||||
@@ -259,11 +260,19 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
|
||||
if (req->request.status == -EINPROGRESS)
|
||||
req->request.status = status;
|
||||
|
||||
- if (dwc->ep0_bounced && dep->number <= 1)
|
||||
+ /*
|
||||
+ * NOTICE we don't want to unmap before calling ->complete() if we're
|
||||
+ * dealing with a bounced ep0 request. If we unmap it here, we would end
|
||||
+ * up overwritting the contents of req->buf and this could confuse the
|
||||
+ * gadget driver.
|
||||
+ */
|
||||
+ if (dwc->ep0_bounced && dep->number <= 1) {
|
||||
dwc->ep0_bounced = false;
|
||||
-
|
||||
- usb_gadget_unmap_request(&dwc->gadget, &req->request,
|
||||
- req->direction);
|
||||
+ unmap_after_complete = true;
|
||||
+ } else {
|
||||
+ usb_gadget_unmap_request(&dwc->gadget,
|
||||
+ &req->request, req->direction);
|
||||
+ }
|
||||
|
||||
dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n",
|
||||
req, dep->name, req->request.actual,
|
||||
@@ -282,6 +282,10 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
|
||||
spin_unlock(&dwc->lock);
|
||||
usb_gadget_giveback_request(&dep->endpoint, &req->request);
|
||||
spin_lock(&dwc->lock);
|
||||
+
|
||||
+ if (unmap_after_complete)
|
||||
+ usb_gadget_unmap_request(&dwc->gadget,
|
||||
+ &req->request, req->direction);
|
||||
}
|
||||
|
||||
int dwc3_send_gadget_generic_command(struct dwc3 *dwc, unsigned cmd, u32 param)
|
||||
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
|
||||
index 3975ac809934..d76800108ddb 100644
|
||||
--- a/net/packet/af_packet.c
|
||||
+++ b/net/packet/af_packet.c
|
||||
@@ -4138,8 +4138,8 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
|
||||
if (unlikely(!PAGE_ALIGNED(req->tp_block_size)))
|
||||
goto out;
|
||||
if (po->tp_version >= TPACKET_V3 &&
|
||||
- (int)(req->tp_block_size -
|
||||
- BLK_PLUS_PRIV(req_u->req3.tp_sizeof_priv)) <= 0)
|
||||
+ req->tp_block_size <=
|
||||
+ BLK_PLUS_PRIV((u64)req_u->req3.tp_sizeof_priv))
|
||||
goto out;
|
||||
if (unlikely(req->tp_frame_size < po->tp_hdrlen +
|
||||
po->tp_reserve))
|
||||
1801
patch/kernel/s5p6818-default/03-patch-4.4.62-63.patch
Normal file
1801
patch/kernel/s5p6818-default/03-patch-4.4.62-63.patch
Normal file
File diff suppressed because it is too large
Load Diff
1016
patch/kernel/s5p6818-default/03-patch-4.4.63-64.patch
Normal file
1016
patch/kernel/s5p6818-default/03-patch-4.4.63-64.patch
Normal file
File diff suppressed because it is too large
Load Diff
881
patch/kernel/s5p6818-default/03-patch-4.4.64-65.patch
Normal file
881
patch/kernel/s5p6818-default/03-patch-4.4.64-65.patch
Normal file
@ -0,0 +1,881 @@
|
||||
diff --git a/Documentation/sysctl/fs.txt b/Documentation/sysctl/fs.txt
|
||||
index 302b5ed616a6..35e17f748ca7 100644
|
||||
--- a/Documentation/sysctl/fs.txt
|
||||
+++ b/Documentation/sysctl/fs.txt
|
||||
@@ -265,6 +265,13 @@ aio-nr can grow to.
|
||||
|
||||
==============================================================
|
||||
|
||||
+mount-max:
|
||||
+
|
||||
+This denotes the maximum number of mounts that may exist
|
||||
+in a mount namespace.
|
||||
+
|
||||
+==============================================================
|
||||
+
|
||||
|
||||
2. /proc/sys/fs/binfmt_misc
|
||||
----------------------------------------------------------
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 17708f5dc169..ddaef04f528a 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 4
|
||||
-SUBLEVEL = 64
|
||||
+SUBLEVEL = 65
|
||||
EXTRAVERSION =
|
||||
NAME = Blurry Fish Butt
|
||||
|
||||
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
|
||||
index 6df3ee561d52..515aa3f993f3 100644
|
||||
--- a/drivers/net/wireless/hostap/hostap_hw.c
|
||||
+++ b/drivers/net/wireless/hostap/hostap_hw.c
|
||||
@@ -836,25 +836,30 @@ static int hfa384x_get_rid(struct net_device *dev, u16 rid, void *buf, int len,
|
||||
spin_lock_bh(&local->baplock);
|
||||
|
||||
res = hfa384x_setup_bap(dev, BAP0, rid, 0);
|
||||
- if (!res)
|
||||
- res = hfa384x_from_bap(dev, BAP0, &rec, sizeof(rec));
|
||||
+ if (res)
|
||||
+ goto unlock;
|
||||
+
|
||||
+ res = hfa384x_from_bap(dev, BAP0, &rec, sizeof(rec));
|
||||
+ if (res)
|
||||
+ goto unlock;
|
||||
|
||||
if (le16_to_cpu(rec.len) == 0) {
|
||||
/* RID not available */
|
||||
res = -ENODATA;
|
||||
+ goto unlock;
|
||||
}
|
||||
|
||||
rlen = (le16_to_cpu(rec.len) - 1) * 2;
|
||||
- if (!res && exact_len && rlen != len) {
|
||||
+ if (exact_len && rlen != len) {
|
||||
printk(KERN_DEBUG "%s: hfa384x_get_rid - RID len mismatch: "
|
||||
"rid=0x%04x, len=%d (expected %d)\n",
|
||||
dev->name, rid, rlen, len);
|
||||
res = -ENODATA;
|
||||
}
|
||||
|
||||
- if (!res)
|
||||
- res = hfa384x_from_bap(dev, BAP0, buf, len);
|
||||
+ res = hfa384x_from_bap(dev, BAP0, buf, len);
|
||||
|
||||
+unlock:
|
||||
spin_unlock_bh(&local->baplock);
|
||||
mutex_unlock(&local->rid_bap_mtx);
|
||||
|
||||
diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c
|
||||
index 80f9de907563..5cc80b80c82b 100644
|
||||
--- a/drivers/tty/nozomi.c
|
||||
+++ b/drivers/tty/nozomi.c
|
||||
@@ -823,7 +823,7 @@ static int receive_data(enum port_type index, struct nozomi *dc)
|
||||
struct tty_struct *tty = tty_port_tty_get(&port->port);
|
||||
int i, ret;
|
||||
|
||||
- read_mem32((u32 *) &size, addr, 4);
|
||||
+ size = __le32_to_cpu(readl(addr));
|
||||
/* DBG1( "%d bytes port: %d", size, index); */
|
||||
|
||||
if (tty && test_bit(TTY_THROTTLED, &tty->flags)) {
|
||||
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
|
||||
index 9982cb176ce8..830e2fd47642 100644
|
||||
--- a/drivers/vfio/pci/vfio_pci.c
|
||||
+++ b/drivers/vfio/pci/vfio_pci.c
|
||||
@@ -562,8 +562,9 @@ static long vfio_pci_ioctl(void *device_data,
|
||||
|
||||
} else if (cmd == VFIO_DEVICE_SET_IRQS) {
|
||||
struct vfio_irq_set hdr;
|
||||
+ size_t size;
|
||||
u8 *data = NULL;
|
||||
- int ret = 0;
|
||||
+ int max, ret = 0;
|
||||
|
||||
minsz = offsetofend(struct vfio_irq_set, count);
|
||||
|
||||
@@ -571,23 +572,31 @@ static long vfio_pci_ioctl(void *device_data,
|
||||
return -EFAULT;
|
||||
|
||||
if (hdr.argsz < minsz || hdr.index >= VFIO_PCI_NUM_IRQS ||
|
||||
+ hdr.count >= (U32_MAX - hdr.start) ||
|
||||
hdr.flags & ~(VFIO_IRQ_SET_DATA_TYPE_MASK |
|
||||
VFIO_IRQ_SET_ACTION_TYPE_MASK))
|
||||
return -EINVAL;
|
||||
|
||||
- if (!(hdr.flags & VFIO_IRQ_SET_DATA_NONE)) {
|
||||
- size_t size;
|
||||
- int max = vfio_pci_get_irq_count(vdev, hdr.index);
|
||||
+ max = vfio_pci_get_irq_count(vdev, hdr.index);
|
||||
+ if (hdr.start >= max || hdr.start + hdr.count > max)
|
||||
+ return -EINVAL;
|
||||
|
||||
- if (hdr.flags & VFIO_IRQ_SET_DATA_BOOL)
|
||||
- size = sizeof(uint8_t);
|
||||
- else if (hdr.flags & VFIO_IRQ_SET_DATA_EVENTFD)
|
||||
- size = sizeof(int32_t);
|
||||
- else
|
||||
- return -EINVAL;
|
||||
+ switch (hdr.flags & VFIO_IRQ_SET_DATA_TYPE_MASK) {
|
||||
+ case VFIO_IRQ_SET_DATA_NONE:
|
||||
+ size = 0;
|
||||
+ break;
|
||||
+ case VFIO_IRQ_SET_DATA_BOOL:
|
||||
+ size = sizeof(uint8_t);
|
||||
+ break;
|
||||
+ case VFIO_IRQ_SET_DATA_EVENTFD:
|
||||
+ size = sizeof(int32_t);
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
|
||||
- if (hdr.argsz - minsz < hdr.count * size ||
|
||||
- hdr.start >= max || hdr.start + hdr.count > max)
|
||||
+ if (size) {
|
||||
+ if (hdr.argsz - minsz < hdr.count * size)
|
||||
return -EINVAL;
|
||||
|
||||
data = memdup_user((void __user *)(arg + minsz),
|
||||
diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c
|
||||
index 20e9a86d2dcf..5c8f767b6368 100644
|
||||
--- a/drivers/vfio/pci/vfio_pci_intrs.c
|
||||
+++ b/drivers/vfio/pci/vfio_pci_intrs.c
|
||||
@@ -255,7 +255,7 @@ static int vfio_msi_enable(struct vfio_pci_device *vdev, int nvec, bool msix)
|
||||
if (!is_irq_none(vdev))
|
||||
return -EINVAL;
|
||||
|
||||
- vdev->ctx = kzalloc(nvec * sizeof(struct vfio_pci_irq_ctx), GFP_KERNEL);
|
||||
+ vdev->ctx = kcalloc(nvec, sizeof(struct vfio_pci_irq_ctx), GFP_KERNEL);
|
||||
if (!vdev->ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
|
||||
index ad8a5b757cc7..a443c6e54412 100644
|
||||
--- a/fs/gfs2/dir.c
|
||||
+++ b/fs/gfs2/dir.c
|
||||
@@ -760,7 +760,7 @@ static int get_first_leaf(struct gfs2_inode *dip, u32 index,
|
||||
int error;
|
||||
|
||||
error = get_leaf_nr(dip, index, &leaf_no);
|
||||
- if (!error)
|
||||
+ if (!IS_ERR_VALUE(error))
|
||||
error = get_leaf(dip, leaf_no, bh_out);
|
||||
|
||||
return error;
|
||||
@@ -976,7 +976,7 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name)
|
||||
|
||||
index = name->hash >> (32 - dip->i_depth);
|
||||
error = get_leaf_nr(dip, index, &leaf_no);
|
||||
- if (error)
|
||||
+ if (IS_ERR_VALUE(error))
|
||||
return error;
|
||||
|
||||
/* Get the old leaf block */
|
||||
diff --git a/fs/mount.h b/fs/mount.h
|
||||
index 3dc7dea5a357..13a4ebbbaa74 100644
|
||||
--- a/fs/mount.h
|
||||
+++ b/fs/mount.h
|
||||
@@ -13,6 +13,8 @@ struct mnt_namespace {
|
||||
u64 seq; /* Sequence number to prevent loops */
|
||||
wait_queue_head_t poll;
|
||||
u64 event;
|
||||
+ unsigned int mounts; /* # of mounts in the namespace */
|
||||
+ unsigned int pending_mounts;
|
||||
};
|
||||
|
||||
struct mnt_pcp {
|
||||
diff --git a/fs/namespace.c b/fs/namespace.c
|
||||
index 7df3d406d3e0..f26d18d69712 100644
|
||||
--- a/fs/namespace.c
|
||||
+++ b/fs/namespace.c
|
||||
@@ -27,6 +27,9 @@
|
||||
#include "pnode.h"
|
||||
#include "internal.h"
|
||||
|
||||
+/* Maximum number of mounts in a mount namespace */
|
||||
+unsigned int sysctl_mount_max __read_mostly = 100000;
|
||||
+
|
||||
static unsigned int m_hash_mask __read_mostly;
|
||||
static unsigned int m_hash_shift __read_mostly;
|
||||
static unsigned int mp_hash_mask __read_mostly;
|
||||
@@ -925,6 +928,9 @@ static void commit_tree(struct mount *mnt)
|
||||
|
||||
list_splice(&head, n->list.prev);
|
||||
|
||||
+ n->mounts += n->pending_mounts;
|
||||
+ n->pending_mounts = 0;
|
||||
+
|
||||
__attach_mnt(mnt, parent);
|
||||
touch_mnt_namespace(n);
|
||||
}
|
||||
@@ -1445,11 +1451,16 @@ static void umount_tree(struct mount *mnt, enum umount_tree_flags how)
|
||||
propagate_umount(&tmp_list);
|
||||
|
||||
while (!list_empty(&tmp_list)) {
|
||||
+ struct mnt_namespace *ns;
|
||||
bool disconnect;
|
||||
p = list_first_entry(&tmp_list, struct mount, mnt_list);
|
||||
list_del_init(&p->mnt_expire);
|
||||
list_del_init(&p->mnt_list);
|
||||
- __touch_mnt_namespace(p->mnt_ns);
|
||||
+ ns = p->mnt_ns;
|
||||
+ if (ns) {
|
||||
+ ns->mounts--;
|
||||
+ __touch_mnt_namespace(ns);
|
||||
+ }
|
||||
p->mnt_ns = NULL;
|
||||
if (how & UMOUNT_SYNC)
|
||||
p->mnt.mnt_flags |= MNT_SYNC_UMOUNT;
|
||||
@@ -1850,6 +1861,28 @@ static int invent_group_ids(struct mount *mnt, bool recurse)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int count_mounts(struct mnt_namespace *ns, struct mount *mnt)
|
||||
+{
|
||||
+ unsigned int max = READ_ONCE(sysctl_mount_max);
|
||||
+ unsigned int mounts = 0, old, pending, sum;
|
||||
+ struct mount *p;
|
||||
+
|
||||
+ for (p = mnt; p; p = next_mnt(p, mnt))
|
||||
+ mounts++;
|
||||
+
|
||||
+ old = ns->mounts;
|
||||
+ pending = ns->pending_mounts;
|
||||
+ sum = old + pending;
|
||||
+ if ((old > sum) ||
|
||||
+ (pending > sum) ||
|
||||
+ (max < sum) ||
|
||||
+ (mounts > (max - sum)))
|
||||
+ return -ENOSPC;
|
||||
+
|
||||
+ ns->pending_mounts = pending + mounts;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* @source_mnt : mount tree to be attached
|
||||
* @nd : place the mount tree @source_mnt is attached
|
||||
@@ -1919,6 +1952,7 @@ static int attach_recursive_mnt(struct mount *source_mnt,
|
||||
struct path *parent_path)
|
||||
{
|
||||
HLIST_HEAD(tree_list);
|
||||
+ struct mnt_namespace *ns = dest_mnt->mnt_ns;
|
||||
struct mountpoint *smp;
|
||||
struct mount *child, *p;
|
||||
struct hlist_node *n;
|
||||
@@ -1931,6 +1965,13 @@ static int attach_recursive_mnt(struct mount *source_mnt,
|
||||
if (IS_ERR(smp))
|
||||
return PTR_ERR(smp);
|
||||
|
||||
+ /* Is there space to add these mounts to the mount namespace? */
|
||||
+ if (!parent_path) {
|
||||
+ err = count_mounts(ns, source_mnt);
|
||||
+ if (err)
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
if (IS_MNT_SHARED(dest_mnt)) {
|
||||
err = invent_group_ids(source_mnt, true);
|
||||
if (err)
|
||||
@@ -1970,11 +2011,14 @@ static int attach_recursive_mnt(struct mount *source_mnt,
|
||||
out_cleanup_ids:
|
||||
while (!hlist_empty(&tree_list)) {
|
||||
child = hlist_entry(tree_list.first, struct mount, mnt_hash);
|
||||
+ child->mnt_parent->mnt_ns->pending_mounts = 0;
|
||||
umount_tree(child, UMOUNT_SYNC);
|
||||
}
|
||||
unlock_mount_hash();
|
||||
cleanup_group_ids(source_mnt, NULL);
|
||||
out:
|
||||
+ ns->pending_mounts = 0;
|
||||
+
|
||||
read_seqlock_excl(&mount_lock);
|
||||
put_mountpoint(smp);
|
||||
read_sequnlock_excl(&mount_lock);
|
||||
@@ -2804,6 +2848,8 @@ static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns)
|
||||
init_waitqueue_head(&new_ns->poll);
|
||||
new_ns->event = 0;
|
||||
new_ns->user_ns = get_user_ns(user_ns);
|
||||
+ new_ns->mounts = 0;
|
||||
+ new_ns->pending_mounts = 0;
|
||||
return new_ns;
|
||||
}
|
||||
|
||||
@@ -2853,6 +2899,7 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns,
|
||||
q = new;
|
||||
while (p) {
|
||||
q->mnt_ns = new_ns;
|
||||
+ new_ns->mounts++;
|
||||
if (new_fs) {
|
||||
if (&p->mnt == new_fs->root.mnt) {
|
||||
new_fs->root.mnt = mntget(&q->mnt);
|
||||
@@ -2891,6 +2938,7 @@ static struct mnt_namespace *create_mnt_ns(struct vfsmount *m)
|
||||
struct mount *mnt = real_mount(m);
|
||||
mnt->mnt_ns = new_ns;
|
||||
new_ns->root = mnt;
|
||||
+ new_ns->mounts++;
|
||||
list_add(&mnt->mnt_list, &new_ns->list);
|
||||
} else {
|
||||
mntput(m);
|
||||
diff --git a/fs/pnode.c b/fs/pnode.c
|
||||
index b9f2af59b9a6..b394ca5307ec 100644
|
||||
--- a/fs/pnode.c
|
||||
+++ b/fs/pnode.c
|
||||
@@ -259,7 +259,7 @@ static int propagate_one(struct mount *m)
|
||||
read_sequnlock_excl(&mount_lock);
|
||||
}
|
||||
hlist_add_head(&child->mnt_hash, list);
|
||||
- return 0;
|
||||
+ return count_mounts(m->mnt_ns, child);
|
||||
}
|
||||
|
||||
/*
|
||||
diff --git a/fs/pnode.h b/fs/pnode.h
|
||||
index 623f01772bec..dc87e65becd2 100644
|
||||
--- a/fs/pnode.h
|
||||
+++ b/fs/pnode.h
|
||||
@@ -54,4 +54,5 @@ void mnt_change_mountpoint(struct mount *parent, struct mountpoint *mp,
|
||||
struct mount *copy_tree(struct mount *, struct dentry *, int);
|
||||
bool is_path_reachable(struct mount *, struct dentry *,
|
||||
const struct path *root);
|
||||
+int count_mounts(struct mnt_namespace *ns, struct mount *mnt);
|
||||
#endif /* _LINUX_PNODE_H */
|
||||
diff --git a/include/linux/mount.h b/include/linux/mount.h
|
||||
index f822c3c11377..dc6cd800cd5d 100644
|
||||
--- a/include/linux/mount.h
|
||||
+++ b/include/linux/mount.h
|
||||
@@ -95,4 +95,6 @@ extern void mark_mounts_for_expiry(struct list_head *mounts);
|
||||
|
||||
extern dev_t name_to_dev_t(const char *name);
|
||||
|
||||
+extern unsigned int sysctl_mount_max;
|
||||
+
|
||||
#endif /* _LINUX_MOUNT_H */
|
||||
diff --git a/kernel/events/core.c b/kernel/events/core.c
|
||||
index e4b5494f05f8..784ab8fe8714 100644
|
||||
--- a/kernel/events/core.c
|
||||
+++ b/kernel/events/core.c
|
||||
@@ -8250,6 +8250,37 @@ static int perf_event_set_clock(struct perf_event *event, clockid_t clk_id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Variation on perf_event_ctx_lock_nested(), except we take two context
|
||||
+ * mutexes.
|
||||
+ */
|
||||
+static struct perf_event_context *
|
||||
+__perf_event_ctx_lock_double(struct perf_event *group_leader,
|
||||
+ struct perf_event_context *ctx)
|
||||
+{
|
||||
+ struct perf_event_context *gctx;
|
||||
+
|
||||
+again:
|
||||
+ rcu_read_lock();
|
||||
+ gctx = READ_ONCE(group_leader->ctx);
|
||||
+ if (!atomic_inc_not_zero(&gctx->refcount)) {
|
||||
+ rcu_read_unlock();
|
||||
+ goto again;
|
||||
+ }
|
||||
+ rcu_read_unlock();
|
||||
+
|
||||
+ mutex_lock_double(&gctx->mutex, &ctx->mutex);
|
||||
+
|
||||
+ if (group_leader->ctx != gctx) {
|
||||
+ mutex_unlock(&ctx->mutex);
|
||||
+ mutex_unlock(&gctx->mutex);
|
||||
+ put_ctx(gctx);
|
||||
+ goto again;
|
||||
+ }
|
||||
+
|
||||
+ return gctx;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* sys_perf_event_open - open a performance event, associate it to a task/cpu
|
||||
*
|
||||
@@ -8486,8 +8517,26 @@ SYSCALL_DEFINE5(perf_event_open,
|
||||
}
|
||||
|
||||
if (move_group) {
|
||||
- gctx = group_leader->ctx;
|
||||
- mutex_lock_double(&gctx->mutex, &ctx->mutex);
|
||||
+ gctx = __perf_event_ctx_lock_double(group_leader, ctx);
|
||||
+
|
||||
+ /*
|
||||
+ * Check if we raced against another sys_perf_event_open() call
|
||||
+ * moving the software group underneath us.
|
||||
+ */
|
||||
+ if (!(group_leader->group_flags & PERF_GROUP_SOFTWARE)) {
|
||||
+ /*
|
||||
+ * If someone moved the group out from under us, check
|
||||
+ * if this new event wound up on the same ctx, if so
|
||||
+ * its the regular !move_group case, otherwise fail.
|
||||
+ */
|
||||
+ if (gctx != ctx) {
|
||||
+ err = -EINVAL;
|
||||
+ goto err_locked;
|
||||
+ } else {
|
||||
+ perf_event_ctx_unlock(group_leader, gctx);
|
||||
+ move_group = 0;
|
||||
+ }
|
||||
+ }
|
||||
} else {
|
||||
mutex_lock(&ctx->mutex);
|
||||
}
|
||||
@@ -8582,7 +8631,7 @@ SYSCALL_DEFINE5(perf_event_open,
|
||||
perf_unpin_context(ctx);
|
||||
|
||||
if (move_group)
|
||||
- mutex_unlock(&gctx->mutex);
|
||||
+ perf_event_ctx_unlock(group_leader, gctx);
|
||||
mutex_unlock(&ctx->mutex);
|
||||
|
||||
if (task) {
|
||||
@@ -8610,7 +8659,7 @@ SYSCALL_DEFINE5(perf_event_open,
|
||||
|
||||
err_locked:
|
||||
if (move_group)
|
||||
- mutex_unlock(&gctx->mutex);
|
||||
+ perf_event_ctx_unlock(group_leader, gctx);
|
||||
mutex_unlock(&ctx->mutex);
|
||||
/* err_file: */
|
||||
fput(event_file);
|
||||
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
|
||||
index 2f0d157258a2..300d64162aff 100644
|
||||
--- a/kernel/sysctl.c
|
||||
+++ b/kernel/sysctl.c
|
||||
@@ -65,6 +65,7 @@
|
||||
#include <linux/sched/sysctl.h>
|
||||
#include <linux/kexec.h>
|
||||
#include <linux/bpf.h>
|
||||
+#include <linux/mount.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/processor.h>
|
||||
@@ -1749,6 +1750,14 @@ static struct ctl_table fs_table[] = {
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_doulongvec_minmax,
|
||||
},
|
||||
+ {
|
||||
+ .procname = "mount-max",
|
||||
+ .data = &sysctl_mount_max,
|
||||
+ .maxlen = sizeof(unsigned int),
|
||||
+ .mode = 0644,
|
||||
+ .proc_handler = proc_dointvec_minmax,
|
||||
+ .extra1 = &one,
|
||||
+ },
|
||||
{ }
|
||||
};
|
||||
|
||||
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
|
||||
index 3a00512addbc..37a3b05d175c 100644
|
||||
--- a/net/ipv4/ping.c
|
||||
+++ b/net/ipv4/ping.c
|
||||
@@ -154,17 +154,18 @@ void ping_hash(struct sock *sk)
|
||||
void ping_unhash(struct sock *sk)
|
||||
{
|
||||
struct inet_sock *isk = inet_sk(sk);
|
||||
+
|
||||
pr_debug("ping_unhash(isk=%p,isk->num=%u)\n", isk, isk->inet_num);
|
||||
+ write_lock_bh(&ping_table.lock);
|
||||
if (sk_hashed(sk)) {
|
||||
- write_lock_bh(&ping_table.lock);
|
||||
hlist_nulls_del(&sk->sk_nulls_node);
|
||||
sk_nulls_node_init(&sk->sk_nulls_node);
|
||||
sock_put(sk);
|
||||
isk->inet_num = 0;
|
||||
isk->inet_sport = 0;
|
||||
sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
|
||||
- write_unlock_bh(&ping_table.lock);
|
||||
}
|
||||
+ write_unlock_bh(&ping_table.lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ping_unhash);
|
||||
|
||||
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
|
||||
index 648f2a67f314..cb1381513c82 100644
|
||||
--- a/net/tipc/bearer.c
|
||||
+++ b/net/tipc/bearer.c
|
||||
@@ -381,6 +381,10 @@ int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b,
|
||||
dev = dev_get_by_name(net, driver_name);
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
+ if (tipc_mtu_bad(dev, 0)) {
|
||||
+ dev_put(dev);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
|
||||
/* Associate TIPC bearer with L2 bearer */
|
||||
rcu_assign_pointer(b->media_ptr, dev);
|
||||
@@ -570,14 +574,19 @@ static int tipc_l2_device_event(struct notifier_block *nb, unsigned long evt,
|
||||
if (!b_ptr)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
- b_ptr->mtu = dev->mtu;
|
||||
-
|
||||
switch (evt) {
|
||||
case NETDEV_CHANGE:
|
||||
if (netif_carrier_ok(dev))
|
||||
break;
|
||||
case NETDEV_GOING_DOWN:
|
||||
+ tipc_reset_bearer(net, b_ptr);
|
||||
+ break;
|
||||
case NETDEV_CHANGEMTU:
|
||||
+ if (tipc_mtu_bad(dev, 0)) {
|
||||
+ bearer_disable(net, b_ptr);
|
||||
+ break;
|
||||
+ }
|
||||
+ b_ptr->mtu = dev->mtu;
|
||||
tipc_reset_bearer(net, b_ptr);
|
||||
break;
|
||||
case NETDEV_CHANGEADDR:
|
||||
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
|
||||
index 552185bc4773..5f11e18b1fa1 100644
|
||||
--- a/net/tipc/bearer.h
|
||||
+++ b/net/tipc/bearer.h
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
#include "netlink.h"
|
||||
#include "core.h"
|
||||
+#include "msg.h"
|
||||
#include <net/genetlink.h>
|
||||
|
||||
#define MAX_MEDIA 3
|
||||
@@ -61,6 +62,9 @@
|
||||
#define TIPC_MEDIA_TYPE_IB 2
|
||||
#define TIPC_MEDIA_TYPE_UDP 3
|
||||
|
||||
+/* minimum bearer MTU */
|
||||
+#define TIPC_MIN_BEARER_MTU (MAX_H_SIZE + INT_H_SIZE)
|
||||
+
|
||||
/**
|
||||
* struct tipc_node_map - set of node identifiers
|
||||
* @count: # of nodes in set
|
||||
@@ -226,4 +230,13 @@ void tipc_bearer_xmit(struct net *net, u32 bearer_id,
|
||||
void tipc_bearer_bc_xmit(struct net *net, u32 bearer_id,
|
||||
struct sk_buff_head *xmitq);
|
||||
|
||||
+/* check if device MTU is too low for tipc headers */
|
||||
+static inline bool tipc_mtu_bad(struct net_device *dev, unsigned int reserve)
|
||||
+{
|
||||
+ if (dev->mtu >= TIPC_MIN_BEARER_MTU + reserve)
|
||||
+ return false;
|
||||
+ netdev_warn(dev, "MTU too low for tipc bearer\n");
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
#endif /* _TIPC_BEARER_H */
|
||||
diff --git a/net/tipc/core.c b/net/tipc/core.c
|
||||
index 03a842870c52..e2bdb07a49a2 100644
|
||||
--- a/net/tipc/core.c
|
||||
+++ b/net/tipc/core.c
|
||||
@@ -69,6 +69,7 @@ static int __net_init tipc_init_net(struct net *net)
|
||||
if (err)
|
||||
goto out_nametbl;
|
||||
|
||||
+ INIT_LIST_HEAD(&tn->dist_queue);
|
||||
err = tipc_topsrv_start(net);
|
||||
if (err)
|
||||
goto out_subscr;
|
||||
diff --git a/net/tipc/core.h b/net/tipc/core.h
|
||||
index 18e95a8020cd..fe3b89e9cde4 100644
|
||||
--- a/net/tipc/core.h
|
||||
+++ b/net/tipc/core.h
|
||||
@@ -103,6 +103,9 @@ struct tipc_net {
|
||||
spinlock_t nametbl_lock;
|
||||
struct name_table *nametbl;
|
||||
|
||||
+ /* Name dist queue */
|
||||
+ struct list_head dist_queue;
|
||||
+
|
||||
/* Topology subscription server */
|
||||
struct tipc_server *topsrv;
|
||||
atomic_t subscription_count;
|
||||
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
|
||||
index f51c8bdbea1c..c4c151bc000c 100644
|
||||
--- a/net/tipc/name_distr.c
|
||||
+++ b/net/tipc/name_distr.c
|
||||
@@ -40,11 +40,6 @@
|
||||
|
||||
int sysctl_tipc_named_timeout __read_mostly = 2000;
|
||||
|
||||
-/**
|
||||
- * struct tipc_dist_queue - queue holding deferred name table updates
|
||||
- */
|
||||
-static struct list_head tipc_dist_queue = LIST_HEAD_INIT(tipc_dist_queue);
|
||||
-
|
||||
struct distr_queue_item {
|
||||
struct distr_item i;
|
||||
u32 dtype;
|
||||
@@ -67,6 +62,8 @@ static void publ_to_item(struct distr_item *i, struct publication *p)
|
||||
|
||||
/**
|
||||
* named_prepare_buf - allocate & initialize a publication message
|
||||
+ *
|
||||
+ * The buffer returned is of size INT_H_SIZE + payload size
|
||||
*/
|
||||
static struct sk_buff *named_prepare_buf(struct net *net, u32 type, u32 size,
|
||||
u32 dest)
|
||||
@@ -171,9 +168,9 @@ static void named_distribute(struct net *net, struct sk_buff_head *list,
|
||||
struct publication *publ;
|
||||
struct sk_buff *skb = NULL;
|
||||
struct distr_item *item = NULL;
|
||||
- uint msg_dsz = (tipc_node_get_mtu(net, dnode, 0) / ITEM_SIZE) *
|
||||
- ITEM_SIZE;
|
||||
- uint msg_rem = msg_dsz;
|
||||
+ u32 msg_dsz = ((tipc_node_get_mtu(net, dnode, 0) - INT_H_SIZE) /
|
||||
+ ITEM_SIZE) * ITEM_SIZE;
|
||||
+ u32 msg_rem = msg_dsz;
|
||||
|
||||
list_for_each_entry(publ, pls, local_list) {
|
||||
/* Prepare next buffer: */
|
||||
@@ -340,9 +337,11 @@ static bool tipc_update_nametbl(struct net *net, struct distr_item *i,
|
||||
* tipc_named_add_backlog - add a failed name table update to the backlog
|
||||
*
|
||||
*/
|
||||
-static void tipc_named_add_backlog(struct distr_item *i, u32 type, u32 node)
|
||||
+static void tipc_named_add_backlog(struct net *net, struct distr_item *i,
|
||||
+ u32 type, u32 node)
|
||||
{
|
||||
struct distr_queue_item *e;
|
||||
+ struct tipc_net *tn = net_generic(net, tipc_net_id);
|
||||
unsigned long now = get_jiffies_64();
|
||||
|
||||
e = kzalloc(sizeof(*e), GFP_ATOMIC);
|
||||
@@ -352,7 +351,7 @@ static void tipc_named_add_backlog(struct distr_item *i, u32 type, u32 node)
|
||||
e->node = node;
|
||||
e->expires = now + msecs_to_jiffies(sysctl_tipc_named_timeout);
|
||||
memcpy(e, i, sizeof(*i));
|
||||
- list_add_tail(&e->next, &tipc_dist_queue);
|
||||
+ list_add_tail(&e->next, &tn->dist_queue);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -362,10 +361,11 @@ static void tipc_named_add_backlog(struct distr_item *i, u32 type, u32 node)
|
||||
void tipc_named_process_backlog(struct net *net)
|
||||
{
|
||||
struct distr_queue_item *e, *tmp;
|
||||
+ struct tipc_net *tn = net_generic(net, tipc_net_id);
|
||||
char addr[16];
|
||||
unsigned long now = get_jiffies_64();
|
||||
|
||||
- list_for_each_entry_safe(e, tmp, &tipc_dist_queue, next) {
|
||||
+ list_for_each_entry_safe(e, tmp, &tn->dist_queue, next) {
|
||||
if (time_after(e->expires, now)) {
|
||||
if (!tipc_update_nametbl(net, &e->i, e->node, e->dtype))
|
||||
continue;
|
||||
@@ -405,7 +405,7 @@ void tipc_named_rcv(struct net *net, struct sk_buff_head *inputq)
|
||||
node = msg_orignode(msg);
|
||||
while (count--) {
|
||||
if (!tipc_update_nametbl(net, item, node, mtype))
|
||||
- tipc_named_add_backlog(item, mtype, node);
|
||||
+ tipc_named_add_backlog(net, item, mtype, node);
|
||||
item++;
|
||||
}
|
||||
kfree_skb(skb);
|
||||
diff --git a/net/tipc/node.c b/net/tipc/node.c
|
||||
index d468aad6163e..2df0b98d4a32 100644
|
||||
--- a/net/tipc/node.c
|
||||
+++ b/net/tipc/node.c
|
||||
@@ -728,7 +728,7 @@ static void tipc_node_fsm_evt(struct tipc_node *n, int evt)
|
||||
state = SELF_UP_PEER_UP;
|
||||
break;
|
||||
case SELF_LOST_CONTACT_EVT:
|
||||
- state = SELF_DOWN_PEER_LEAVING;
|
||||
+ state = SELF_DOWN_PEER_DOWN;
|
||||
break;
|
||||
case SELF_ESTABL_CONTACT_EVT:
|
||||
case PEER_LOST_CONTACT_EVT:
|
||||
@@ -747,7 +747,7 @@ static void tipc_node_fsm_evt(struct tipc_node *n, int evt)
|
||||
state = SELF_UP_PEER_UP;
|
||||
break;
|
||||
case PEER_LOST_CONTACT_EVT:
|
||||
- state = SELF_LEAVING_PEER_DOWN;
|
||||
+ state = SELF_DOWN_PEER_DOWN;
|
||||
break;
|
||||
case SELF_LOST_CONTACT_EVT:
|
||||
case PEER_ESTABL_CONTACT_EVT:
|
||||
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
|
||||
index b26b7a127773..65171f8e8c45 100644
|
||||
--- a/net/tipc/socket.c
|
||||
+++ b/net/tipc/socket.c
|
||||
@@ -777,9 +777,11 @@ void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq,
|
||||
* @tsk: receiving socket
|
||||
* @skb: pointer to message buffer.
|
||||
*/
|
||||
-static void tipc_sk_proto_rcv(struct tipc_sock *tsk, struct sk_buff *skb)
|
||||
+static void tipc_sk_proto_rcv(struct tipc_sock *tsk, struct sk_buff *skb,
|
||||
+ struct sk_buff_head *xmitq)
|
||||
{
|
||||
struct sock *sk = &tsk->sk;
|
||||
+ u32 onode = tsk_own_node(tsk);
|
||||
struct tipc_msg *hdr = buf_msg(skb);
|
||||
int mtyp = msg_type(hdr);
|
||||
int conn_cong;
|
||||
@@ -792,7 +794,8 @@ static void tipc_sk_proto_rcv(struct tipc_sock *tsk, struct sk_buff *skb)
|
||||
|
||||
if (mtyp == CONN_PROBE) {
|
||||
msg_set_type(hdr, CONN_PROBE_REPLY);
|
||||
- tipc_sk_respond(sk, skb, TIPC_OK);
|
||||
+ if (tipc_msg_reverse(onode, &skb, TIPC_OK))
|
||||
+ __skb_queue_tail(xmitq, skb);
|
||||
return;
|
||||
} else if (mtyp == CONN_ACK) {
|
||||
conn_cong = tsk_conn_cong(tsk);
|
||||
@@ -1647,7 +1650,8 @@ static unsigned int rcvbuf_limit(struct sock *sk, struct sk_buff *buf)
|
||||
*
|
||||
* Returns true if message was added to socket receive queue, otherwise false
|
||||
*/
|
||||
-static bool filter_rcv(struct sock *sk, struct sk_buff *skb)
|
||||
+static bool filter_rcv(struct sock *sk, struct sk_buff *skb,
|
||||
+ struct sk_buff_head *xmitq)
|
||||
{
|
||||
struct socket *sock = sk->sk_socket;
|
||||
struct tipc_sock *tsk = tipc_sk(sk);
|
||||
@@ -1657,7 +1661,7 @@ static bool filter_rcv(struct sock *sk, struct sk_buff *skb)
|
||||
int usr = msg_user(hdr);
|
||||
|
||||
if (unlikely(msg_user(hdr) == CONN_MANAGER)) {
|
||||
- tipc_sk_proto_rcv(tsk, skb);
|
||||
+ tipc_sk_proto_rcv(tsk, skb, xmitq);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1700,7 +1704,8 @@ static bool filter_rcv(struct sock *sk, struct sk_buff *skb)
|
||||
return true;
|
||||
|
||||
reject:
|
||||
- tipc_sk_respond(sk, skb, err);
|
||||
+ if (tipc_msg_reverse(tsk_own_node(tsk), &skb, err))
|
||||
+ __skb_queue_tail(xmitq, skb);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1716,9 +1721,24 @@ reject:
|
||||
static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
unsigned int truesize = skb->truesize;
|
||||
+ struct sk_buff_head xmitq;
|
||||
+ u32 dnode, selector;
|
||||
|
||||
- if (likely(filter_rcv(sk, skb)))
|
||||
+ __skb_queue_head_init(&xmitq);
|
||||
+
|
||||
+ if (likely(filter_rcv(sk, skb, &xmitq))) {
|
||||
atomic_add(truesize, &tipc_sk(sk)->dupl_rcvcnt);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (skb_queue_empty(&xmitq))
|
||||
+ return 0;
|
||||
+
|
||||
+ /* Send response/rejected message */
|
||||
+ skb = __skb_dequeue(&xmitq);
|
||||
+ dnode = msg_destnode(buf_msg(skb));
|
||||
+ selector = msg_origport(buf_msg(skb));
|
||||
+ tipc_node_xmit_skb(sock_net(sk), skb, dnode, selector);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1732,12 +1752,13 @@ static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb)
|
||||
* Caller must hold socket lock
|
||||
*/
|
||||
static void tipc_sk_enqueue(struct sk_buff_head *inputq, struct sock *sk,
|
||||
- u32 dport)
|
||||
+ u32 dport, struct sk_buff_head *xmitq)
|
||||
{
|
||||
+ unsigned long time_limit = jiffies + 2;
|
||||
+ struct sk_buff *skb;
|
||||
unsigned int lim;
|
||||
atomic_t *dcnt;
|
||||
- struct sk_buff *skb;
|
||||
- unsigned long time_limit = jiffies + 2;
|
||||
+ u32 onode;
|
||||
|
||||
while (skb_queue_len(inputq)) {
|
||||
if (unlikely(time_after_eq(jiffies, time_limit)))
|
||||
@@ -1749,20 +1770,22 @@ static void tipc_sk_enqueue(struct sk_buff_head *inputq, struct sock *sk,
|
||||
|
||||
/* Add message directly to receive queue if possible */
|
||||
if (!sock_owned_by_user(sk)) {
|
||||
- filter_rcv(sk, skb);
|
||||
+ filter_rcv(sk, skb, xmitq);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Try backlog, compensating for double-counted bytes */
|
||||
dcnt = &tipc_sk(sk)->dupl_rcvcnt;
|
||||
- if (sk->sk_backlog.len)
|
||||
+ if (!sk->sk_backlog.len)
|
||||
atomic_set(dcnt, 0);
|
||||
lim = rcvbuf_limit(sk, skb) + atomic_read(dcnt);
|
||||
if (likely(!sk_add_backlog(sk, skb, lim)))
|
||||
continue;
|
||||
|
||||
/* Overload => reject message back to sender */
|
||||
- tipc_sk_respond(sk, skb, TIPC_ERR_OVERLOAD);
|
||||
+ onode = tipc_own_addr(sock_net(sk));
|
||||
+ if (tipc_msg_reverse(onode, &skb, TIPC_ERR_OVERLOAD))
|
||||
+ __skb_queue_tail(xmitq, skb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1775,12 +1798,14 @@ static void tipc_sk_enqueue(struct sk_buff_head *inputq, struct sock *sk,
|
||||
*/
|
||||
void tipc_sk_rcv(struct net *net, struct sk_buff_head *inputq)
|
||||
{
|
||||
+ struct sk_buff_head xmitq;
|
||||
u32 dnode, dport = 0;
|
||||
int err;
|
||||
struct tipc_sock *tsk;
|
||||
struct sock *sk;
|
||||
struct sk_buff *skb;
|
||||
|
||||
+ __skb_queue_head_init(&xmitq);
|
||||
while (skb_queue_len(inputq)) {
|
||||
dport = tipc_skb_peek_port(inputq, dport);
|
||||
tsk = tipc_sk_lookup(net, dport);
|
||||
@@ -1788,9 +1813,14 @@ void tipc_sk_rcv(struct net *net, struct sk_buff_head *inputq)
|
||||
if (likely(tsk)) {
|
||||
sk = &tsk->sk;
|
||||
if (likely(spin_trylock_bh(&sk->sk_lock.slock))) {
|
||||
- tipc_sk_enqueue(inputq, sk, dport);
|
||||
+ tipc_sk_enqueue(inputq, sk, dport, &xmitq);
|
||||
spin_unlock_bh(&sk->sk_lock.slock);
|
||||
}
|
||||
+ /* Send pending response/rejected messages, if any */
|
||||
+ while ((skb = __skb_dequeue(&xmitq))) {
|
||||
+ dnode = msg_destnode(buf_msg(skb));
|
||||
+ tipc_node_xmit_skb(net, skb, dnode, dport);
|
||||
+ }
|
||||
sock_put(sk);
|
||||
continue;
|
||||
}
|
||||
diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c
|
||||
index 6af78c6276b4..78d6b78de29d 100644
|
||||
--- a/net/tipc/udp_media.c
|
||||
+++ b/net/tipc/udp_media.c
|
||||
@@ -52,7 +52,7 @@
|
||||
/* IANA assigned UDP port */
|
||||
#define UDP_PORT_DEFAULT 6118
|
||||
|
||||
-#define UDP_MIN_HEADROOM 28
|
||||
+#define UDP_MIN_HEADROOM 48
|
||||
|
||||
static const struct nla_policy tipc_nl_udp_policy[TIPC_NLA_UDP_MAX + 1] = {
|
||||
[TIPC_NLA_UDP_UNSPEC] = {.type = NLA_UNSPEC},
|
||||
@@ -376,6 +376,11 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
|
||||
udp_conf.local_ip.s_addr = htonl(INADDR_ANY);
|
||||
udp_conf.use_udp_checksums = false;
|
||||
ub->ifindex = dev->ifindex;
|
||||
+ if (tipc_mtu_bad(dev, sizeof(struct iphdr) +
|
||||
+ sizeof(struct udphdr))) {
|
||||
+ err = -EINVAL;
|
||||
+ goto err;
|
||||
+ }
|
||||
b->mtu = dev->mtu - sizeof(struct iphdr)
|
||||
- sizeof(struct udphdr);
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
1284
patch/kernel/s5p6818-default/03-patch-4.4.65-66.patch
Normal file
1284
patch/kernel/s5p6818-default/03-patch-4.4.65-66.patch
Normal file
File diff suppressed because it is too large
Load Diff
948
patch/kernel/s5p6818-default/03-patch-4.4.66-67.patch
Normal file
948
patch/kernel/s5p6818-default/03-patch-4.4.66-67.patch
Normal file
@ -0,0 +1,948 @@
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 1cd052823c03..c987902ae1ee 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 4
|
||||
-SUBLEVEL = 66
|
||||
+SUBLEVEL = 67
|
||||
EXTRAVERSION =
|
||||
NAME = Blurry Fish Butt
|
||||
|
||||
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c
|
||||
index 9462d2752850..8bdc34dbaedf 100644
|
||||
--- a/drivers/block/drbd/drbd_bitmap.c
|
||||
+++ b/drivers/block/drbd/drbd_bitmap.c
|
||||
@@ -479,8 +479,14 @@ void drbd_bm_cleanup(struct drbd_device *device)
|
||||
* this masks out the remaining bits.
|
||||
* Returns the number of bits cleared.
|
||||
*/
|
||||
+#ifndef BITS_PER_PAGE
|
||||
#define BITS_PER_PAGE (1UL << (PAGE_SHIFT + 3))
|
||||
#define BITS_PER_PAGE_MASK (BITS_PER_PAGE - 1)
|
||||
+#else
|
||||
+# if BITS_PER_PAGE != (1UL << (PAGE_SHIFT + 3))
|
||||
+# error "ambiguous BITS_PER_PAGE"
|
||||
+# endif
|
||||
+#endif
|
||||
#define BITS_PER_LONG_MASK (BITS_PER_LONG - 1)
|
||||
static int bm_clear_surplus(struct drbd_bitmap *b)
|
||||
{
|
||||
diff --git a/drivers/infiniband/hw/qib/qib_qp.c b/drivers/infiniband/hw/qib/qib_qp.c
|
||||
index 3eff35c2d453..2684605fe67f 100644
|
||||
--- a/drivers/infiniband/hw/qib/qib_qp.c
|
||||
+++ b/drivers/infiniband/hw/qib/qib_qp.c
|
||||
@@ -41,13 +41,13 @@
|
||||
|
||||
#include "qib.h"
|
||||
|
||||
-#define BITS_PER_PAGE (PAGE_SIZE*BITS_PER_BYTE)
|
||||
-#define BITS_PER_PAGE_MASK (BITS_PER_PAGE-1)
|
||||
+#define RVT_BITS_PER_PAGE (PAGE_SIZE*BITS_PER_BYTE)
|
||||
+#define RVT_BITS_PER_PAGE_MASK (RVT_BITS_PER_PAGE-1)
|
||||
|
||||
static inline unsigned mk_qpn(struct qib_qpn_table *qpt,
|
||||
struct qpn_map *map, unsigned off)
|
||||
{
|
||||
- return (map - qpt->map) * BITS_PER_PAGE + off;
|
||||
+ return (map - qpt->map) * RVT_BITS_PER_PAGE + off;
|
||||
}
|
||||
|
||||
static inline unsigned find_next_offset(struct qib_qpn_table *qpt,
|
||||
@@ -59,7 +59,7 @@ static inline unsigned find_next_offset(struct qib_qpn_table *qpt,
|
||||
if (((off & qpt->mask) >> 1) >= n)
|
||||
off = (off | qpt->mask) + 2;
|
||||
} else
|
||||
- off = find_next_zero_bit(map->page, BITS_PER_PAGE, off);
|
||||
+ off = find_next_zero_bit(map->page, RVT_BITS_PER_PAGE, off);
|
||||
return off;
|
||||
}
|
||||
|
||||
@@ -147,8 +147,8 @@ static int alloc_qpn(struct qib_devdata *dd, struct qib_qpn_table *qpt,
|
||||
qpn = 2;
|
||||
if (qpt->mask && ((qpn & qpt->mask) >> 1) >= dd->n_krcv_queues)
|
||||
qpn = (qpn | qpt->mask) + 2;
|
||||
- offset = qpn & BITS_PER_PAGE_MASK;
|
||||
- map = &qpt->map[qpn / BITS_PER_PAGE];
|
||||
+ offset = qpn & RVT_BITS_PER_PAGE_MASK;
|
||||
+ map = &qpt->map[qpn / RVT_BITS_PER_PAGE];
|
||||
max_scan = qpt->nmaps - !offset;
|
||||
for (i = 0;;) {
|
||||
if (unlikely(!map->page)) {
|
||||
@@ -173,7 +173,7 @@ static int alloc_qpn(struct qib_devdata *dd, struct qib_qpn_table *qpt,
|
||||
* We just need to be sure we don't loop
|
||||
* forever.
|
||||
*/
|
||||
- } while (offset < BITS_PER_PAGE && qpn < QPN_MAX);
|
||||
+ } while (offset < RVT_BITS_PER_PAGE && qpn < QPN_MAX);
|
||||
/*
|
||||
* In order to keep the number of pages allocated to a
|
||||
* minimum, we scan the all existing pages before increasing
|
||||
@@ -204,9 +204,9 @@ static void free_qpn(struct qib_qpn_table *qpt, u32 qpn)
|
||||
{
|
||||
struct qpn_map *map;
|
||||
|
||||
- map = qpt->map + qpn / BITS_PER_PAGE;
|
||||
+ map = qpt->map + qpn / RVT_BITS_PER_PAGE;
|
||||
if (map->page)
|
||||
- clear_bit(qpn & BITS_PER_PAGE_MASK, map->page);
|
||||
+ clear_bit(qpn & RVT_BITS_PER_PAGE_MASK, map->page);
|
||||
}
|
||||
|
||||
static inline unsigned qpn_hash(struct qib_ibdev *dev, u32 qpn)
|
||||
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
|
||||
index 80a439543259..e503279c34fc 100644
|
||||
--- a/drivers/md/dm-ioctl.c
|
||||
+++ b/drivers/md/dm-ioctl.c
|
||||
@@ -1843,7 +1843,7 @@ static int ctl_ioctl(uint command, struct dm_ioctl __user *user)
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
- param->data_size = sizeof(*param);
|
||||
+ param->data_size = offsetof(struct dm_ioctl, data);
|
||||
r = fn(param, input_param_size);
|
||||
|
||||
if (unlikely(param->flags & DM_BUFFER_FULL_FLAG) &&
|
||||
diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig
|
||||
index 54479c481a7a..8a25adced79f 100644
|
||||
--- a/drivers/mtd/chips/Kconfig
|
||||
+++ b/drivers/mtd/chips/Kconfig
|
||||
@@ -111,6 +111,7 @@ config MTD_MAP_BANK_WIDTH_16
|
||||
|
||||
config MTD_MAP_BANK_WIDTH_32
|
||||
bool "Support 256-bit buswidth" if MTD_CFI_GEOMETRY
|
||||
+ select MTD_COMPLEX_MAPPINGS if HAS_IOMEM
|
||||
default n
|
||||
help
|
||||
If you wish to support CFI devices on a physical bus which is
|
||||
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
|
||||
index 49056c33be74..21e5b9ed1ead 100644
|
||||
--- a/drivers/net/ethernet/broadcom/tg3.c
|
||||
+++ b/drivers/net/ethernet/broadcom/tg3.c
|
||||
@@ -12031,7 +12031,7 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
|
||||
int ret;
|
||||
u32 offset, len, b_offset, odd_len;
|
||||
u8 *buf;
|
||||
- __be32 start, end;
|
||||
+ __be32 start = 0, end;
|
||||
|
||||
if (tg3_flag(tp, NO_NVRAM) ||
|
||||
eeprom->magic != TG3_EEPROM_MAGIC)
|
||||
diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c
|
||||
index 2882bcac918a..0b096730c72a 100644
|
||||
--- a/drivers/scsi/cxlflash/main.c
|
||||
+++ b/drivers/scsi/cxlflash/main.c
|
||||
@@ -996,6 +996,8 @@ static int wait_port_online(__be64 __iomem *fc_regs, u32 delay_us, u32 nretry)
|
||||
do {
|
||||
msleep(delay_us / 1000);
|
||||
status = readq_be(&fc_regs[FC_MTIP_STATUS / 8]);
|
||||
+ if (status == U64_MAX)
|
||||
+ nretry /= 2;
|
||||
} while ((status & FC_MTIP_STATUS_MASK) != FC_MTIP_STATUS_ONLINE &&
|
||||
nretry--);
|
||||
|
||||
@@ -1027,6 +1029,8 @@ static int wait_port_offline(__be64 __iomem *fc_regs, u32 delay_us, u32 nretry)
|
||||
do {
|
||||
msleep(delay_us / 1000);
|
||||
status = readq_be(&fc_regs[FC_MTIP_STATUS / 8]);
|
||||
+ if (status == U64_MAX)
|
||||
+ nretry /= 2;
|
||||
} while ((status & FC_MTIP_STATUS_MASK) != FC_MTIP_STATUS_OFFLINE &&
|
||||
nretry--);
|
||||
|
||||
@@ -1137,7 +1141,7 @@ static const struct asyc_intr_info ainfo[] = {
|
||||
{SISL_ASTATUS_FC0_LOGI_F, "login failed", 0, CLR_FC_ERROR},
|
||||
{SISL_ASTATUS_FC0_LOGI_S, "login succeeded", 0, SCAN_HOST},
|
||||
{SISL_ASTATUS_FC0_LINK_DN, "link down", 0, 0},
|
||||
- {SISL_ASTATUS_FC0_LINK_UP, "link up", 0, SCAN_HOST},
|
||||
+ {SISL_ASTATUS_FC0_LINK_UP, "link up", 0, 0},
|
||||
{SISL_ASTATUS_FC1_OTHER, "other error", 1, CLR_FC_ERROR | LINK_RESET},
|
||||
{SISL_ASTATUS_FC1_LOGO, "target initiated LOGO", 1, 0},
|
||||
{SISL_ASTATUS_FC1_CRC_T, "CRC threshold exceeded", 1, LINK_RESET},
|
||||
@@ -1145,7 +1149,7 @@ static const struct asyc_intr_info ainfo[] = {
|
||||
{SISL_ASTATUS_FC1_LOGI_F, "login failed", 1, CLR_FC_ERROR},
|
||||
{SISL_ASTATUS_FC1_LOGI_S, "login succeeded", 1, SCAN_HOST},
|
||||
{SISL_ASTATUS_FC1_LINK_DN, "link down", 1, 0},
|
||||
- {SISL_ASTATUS_FC1_LINK_UP, "link up", 1, SCAN_HOST},
|
||||
+ {SISL_ASTATUS_FC1_LINK_UP, "link up", 1, 0},
|
||||
{0x0, "", 0, 0} /* terminator */
|
||||
};
|
||||
|
||||
@@ -1962,6 +1966,11 @@ retry:
|
||||
* cxlflash_eh_host_reset_handler() - reset the host adapter
|
||||
* @scp: SCSI command from stack identifying host.
|
||||
*
|
||||
+ * Following a reset, the state is evaluated again in case an EEH occurred
|
||||
+ * during the reset. In such a scenario, the host reset will either yield
|
||||
+ * until the EEH recovery is complete or return success or failure based
|
||||
+ * upon the current device state.
|
||||
+ *
|
||||
* Return:
|
||||
* SUCCESS as defined in scsi/scsi.h
|
||||
* FAILED as defined in scsi/scsi.h
|
||||
@@ -1993,7 +2002,8 @@ static int cxlflash_eh_host_reset_handler(struct scsi_cmnd *scp)
|
||||
} else
|
||||
cfg->state = STATE_NORMAL;
|
||||
wake_up_all(&cfg->reset_waitq);
|
||||
- break;
|
||||
+ ssleep(1);
|
||||
+ /* fall through */
|
||||
case STATE_RESET:
|
||||
wait_event(cfg->reset_waitq, cfg->state != STATE_RESET);
|
||||
if (cfg->state == STATE_NORMAL)
|
||||
@@ -2534,6 +2544,9 @@ static void drain_ioctls(struct cxlflash_cfg *cfg)
|
||||
* @pdev: PCI device struct.
|
||||
* @state: PCI channel state.
|
||||
*
|
||||
+ * When an EEH occurs during an active reset, wait until the reset is
|
||||
+ * complete and then take action based upon the device state.
|
||||
+ *
|
||||
* Return: PCI_ERS_RESULT_NEED_RESET or PCI_ERS_RESULT_DISCONNECT
|
||||
*/
|
||||
static pci_ers_result_t cxlflash_pci_error_detected(struct pci_dev *pdev,
|
||||
@@ -2547,6 +2560,10 @@ static pci_ers_result_t cxlflash_pci_error_detected(struct pci_dev *pdev,
|
||||
|
||||
switch (state) {
|
||||
case pci_channel_io_frozen:
|
||||
+ wait_event(cfg->reset_waitq, cfg->state != STATE_RESET);
|
||||
+ if (cfg->state == STATE_FAILTERM)
|
||||
+ return PCI_ERS_RESULT_DISCONNECT;
|
||||
+
|
||||
cfg->state = STATE_RESET;
|
||||
scsi_block_requests(cfg->host);
|
||||
drain_ioctls(cfg);
|
||||
diff --git a/drivers/staging/rdma/ehca/ehca_mrmw.c b/drivers/staging/rdma/ehca/ehca_mrmw.c
|
||||
index f914b30999f8..4d52ca42644a 100644
|
||||
--- a/drivers/staging/rdma/ehca/ehca_mrmw.c
|
||||
+++ b/drivers/staging/rdma/ehca/ehca_mrmw.c
|
||||
@@ -1921,7 +1921,7 @@ static int ehca_set_pagebuf_user2(struct ehca_mr_pginfo *pginfo,
|
||||
u64 *kpage)
|
||||
{
|
||||
int ret = 0;
|
||||
- u64 pgaddr, prev_pgaddr;
|
||||
+ u64 pgaddr, prev_pgaddr = 0;
|
||||
u32 j = 0;
|
||||
int kpages_per_hwpage = pginfo->hwpage_size / PAGE_SIZE;
|
||||
int nr_kpages = kpages_per_hwpage;
|
||||
@@ -2417,6 +2417,7 @@ static int ehca_reg_bmap_mr_rpages(struct ehca_shca *shca,
|
||||
ehca_err(&shca->ib_device, "kpage alloc failed");
|
||||
return -ENOMEM;
|
||||
}
|
||||
+ hret = H_SUCCESS;
|
||||
for (top = 0; top < EHCA_MAP_ENTRIES; top++) {
|
||||
if (!ehca_bmap_valid(ehca_bmap->top[top]))
|
||||
continue;
|
||||
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
|
||||
index 83ff1724ec79..cf3da51a3536 100644
|
||||
--- a/drivers/tty/serial/8250/8250_pci.c
|
||||
+++ b/drivers/tty/serial/8250/8250_pci.c
|
||||
@@ -5850,17 +5850,15 @@ static pci_ers_result_t serial8250_io_slot_reset(struct pci_dev *dev)
|
||||
static void serial8250_io_resume(struct pci_dev *dev)
|
||||
{
|
||||
struct serial_private *priv = pci_get_drvdata(dev);
|
||||
- const struct pciserial_board *board;
|
||||
+ struct serial_private *new;
|
||||
|
||||
if (!priv)
|
||||
return;
|
||||
|
||||
- board = priv->board;
|
||||
- kfree(priv);
|
||||
- priv = pciserial_init_ports(dev, board);
|
||||
-
|
||||
- if (!IS_ERR(priv)) {
|
||||
- pci_set_drvdata(dev, priv);
|
||||
+ new = pciserial_init_ports(dev, priv->board);
|
||||
+ if (!IS_ERR(new)) {
|
||||
+ pci_set_drvdata(dev, new);
|
||||
+ kfree(priv);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
|
||||
index 94906aaa9b7c..e2f6a79e9b01 100644
|
||||
--- a/fs/cifs/cifsglob.h
|
||||
+++ b/fs/cifs/cifsglob.h
|
||||
@@ -227,6 +227,7 @@ struct smb_version_operations {
|
||||
/* verify the message */
|
||||
int (*check_message)(char *, unsigned int);
|
||||
bool (*is_oplock_break)(char *, struct TCP_Server_Info *);
|
||||
+ int (*handle_cancelled_mid)(char *, struct TCP_Server_Info *);
|
||||
void (*downgrade_oplock)(struct TCP_Server_Info *,
|
||||
struct cifsInodeInfo *, bool);
|
||||
/* process transaction2 response */
|
||||
@@ -1289,12 +1290,19 @@ struct mid_q_entry {
|
||||
void *callback_data; /* general purpose pointer for callback */
|
||||
void *resp_buf; /* pointer to received SMB header */
|
||||
int mid_state; /* wish this were enum but can not pass to wait_event */
|
||||
+ unsigned int mid_flags;
|
||||
__le16 command; /* smb command code */
|
||||
bool large_buf:1; /* if valid response, is pointer to large buf */
|
||||
bool multiRsp:1; /* multiple trans2 responses for one request */
|
||||
bool multiEnd:1; /* both received */
|
||||
};
|
||||
|
||||
+struct close_cancelled_open {
|
||||
+ struct cifs_fid fid;
|
||||
+ struct cifs_tcon *tcon;
|
||||
+ struct work_struct work;
|
||||
+};
|
||||
+
|
||||
/* Make code in transport.c a little cleaner by moving
|
||||
update of optional stats into function below */
|
||||
#ifdef CONFIG_CIFS_STATS2
|
||||
@@ -1426,6 +1434,9 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param,
|
||||
#define MID_RESPONSE_MALFORMED 0x10
|
||||
#define MID_SHUTDOWN 0x20
|
||||
|
||||
+/* Flags */
|
||||
+#define MID_WAIT_CANCELLED 1 /* Cancelled while waiting for response */
|
||||
+
|
||||
/* Types of response buffer returned from SendReceive2 */
|
||||
#define CIFS_NO_BUFFER 0 /* Response buffer not returned */
|
||||
#define CIFS_SMALL_BUFFER 1
|
||||
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
|
||||
index b1104ed8f54c..5e2f8b8ca08a 100644
|
||||
--- a/fs/cifs/cifssmb.c
|
||||
+++ b/fs/cifs/cifssmb.c
|
||||
@@ -1424,6 +1424,8 @@ cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
|
||||
|
||||
length = discard_remaining_data(server);
|
||||
dequeue_mid(mid, rdata->result);
|
||||
+ mid->resp_buf = server->smallbuf;
|
||||
+ server->smallbuf = NULL;
|
||||
return length;
|
||||
}
|
||||
|
||||
@@ -1538,6 +1540,8 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
|
||||
return cifs_readv_discard(server, mid);
|
||||
|
||||
dequeue_mid(mid, false);
|
||||
+ mid->resp_buf = server->smallbuf;
|
||||
+ server->smallbuf = NULL;
|
||||
return length;
|
||||
}
|
||||
|
||||
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
|
||||
index 5d59f25521ce..156bc18eac69 100644
|
||||
--- a/fs/cifs/connect.c
|
||||
+++ b/fs/cifs/connect.c
|
||||
@@ -924,10 +924,19 @@ cifs_demultiplex_thread(void *p)
|
||||
|
||||
server->lstrp = jiffies;
|
||||
if (mid_entry != NULL) {
|
||||
+ if ((mid_entry->mid_flags & MID_WAIT_CANCELLED) &&
|
||||
+ mid_entry->mid_state == MID_RESPONSE_RECEIVED &&
|
||||
+ server->ops->handle_cancelled_mid)
|
||||
+ server->ops->handle_cancelled_mid(
|
||||
+ mid_entry->resp_buf,
|
||||
+ server);
|
||||
+
|
||||
if (!mid_entry->multiRsp || mid_entry->multiEnd)
|
||||
mid_entry->callback(mid_entry);
|
||||
- } else if (!server->ops->is_oplock_break ||
|
||||
- !server->ops->is_oplock_break(buf, server)) {
|
||||
+ } else if (server->ops->is_oplock_break &&
|
||||
+ server->ops->is_oplock_break(buf, server)) {
|
||||
+ cifs_dbg(FYI, "Received oplock break\n");
|
||||
+ } else {
|
||||
cifs_dbg(VFS, "No task to wake, unknown frame received! NumMids %d\n",
|
||||
atomic_read(&midCount));
|
||||
cifs_dump_mem("Received Data is: ", buf,
|
||||
diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c
|
||||
index e5bc85e49be7..76ccf20fbfb7 100644
|
||||
--- a/fs/cifs/smb2misc.c
|
||||
+++ b/fs/cifs/smb2misc.c
|
||||
@@ -630,3 +630,47 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
|
||||
cifs_dbg(FYI, "Can not process oplock break for non-existent connection\n");
|
||||
return false;
|
||||
}
|
||||
+
|
||||
+void
|
||||
+smb2_cancelled_close_fid(struct work_struct *work)
|
||||
+{
|
||||
+ struct close_cancelled_open *cancelled = container_of(work,
|
||||
+ struct close_cancelled_open, work);
|
||||
+
|
||||
+ cifs_dbg(VFS, "Close unmatched open\n");
|
||||
+
|
||||
+ SMB2_close(0, cancelled->tcon, cancelled->fid.persistent_fid,
|
||||
+ cancelled->fid.volatile_fid);
|
||||
+ cifs_put_tcon(cancelled->tcon);
|
||||
+ kfree(cancelled);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+smb2_handle_cancelled_mid(char *buffer, struct TCP_Server_Info *server)
|
||||
+{
|
||||
+ struct smb2_hdr *hdr = (struct smb2_hdr *)buffer;
|
||||
+ struct smb2_create_rsp *rsp = (struct smb2_create_rsp *)buffer;
|
||||
+ struct cifs_tcon *tcon;
|
||||
+ struct close_cancelled_open *cancelled;
|
||||
+
|
||||
+ if (hdr->Command != SMB2_CREATE || hdr->Status != STATUS_SUCCESS)
|
||||
+ return 0;
|
||||
+
|
||||
+ cancelled = kzalloc(sizeof(*cancelled), GFP_KERNEL);
|
||||
+ if (!cancelled)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ tcon = smb2_find_smb_tcon(server, hdr->SessionId, hdr->TreeId);
|
||||
+ if (!tcon) {
|
||||
+ kfree(cancelled);
|
||||
+ return -ENOENT;
|
||||
+ }
|
||||
+
|
||||
+ cancelled->fid.persistent_fid = rsp->PersistentFileId;
|
||||
+ cancelled->fid.volatile_fid = rsp->VolatileFileId;
|
||||
+ cancelled->tcon = tcon;
|
||||
+ INIT_WORK(&cancelled->work, smb2_cancelled_close_fid);
|
||||
+ queue_work(cifsiod_wq, &cancelled->work);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
|
||||
index be34b4860675..087918c4612a 100644
|
||||
--- a/fs/cifs/smb2ops.c
|
||||
+++ b/fs/cifs/smb2ops.c
|
||||
@@ -1511,6 +1511,7 @@ struct smb_version_operations smb20_operations = {
|
||||
.clear_stats = smb2_clear_stats,
|
||||
.print_stats = smb2_print_stats,
|
||||
.is_oplock_break = smb2_is_valid_oplock_break,
|
||||
+ .handle_cancelled_mid = smb2_handle_cancelled_mid,
|
||||
.downgrade_oplock = smb2_downgrade_oplock,
|
||||
.need_neg = smb2_need_neg,
|
||||
.negotiate = smb2_negotiate,
|
||||
@@ -1589,6 +1590,7 @@ struct smb_version_operations smb21_operations = {
|
||||
.clear_stats = smb2_clear_stats,
|
||||
.print_stats = smb2_print_stats,
|
||||
.is_oplock_break = smb2_is_valid_oplock_break,
|
||||
+ .handle_cancelled_mid = smb2_handle_cancelled_mid,
|
||||
.downgrade_oplock = smb2_downgrade_oplock,
|
||||
.need_neg = smb2_need_neg,
|
||||
.negotiate = smb2_negotiate,
|
||||
@@ -1670,6 +1672,7 @@ struct smb_version_operations smb30_operations = {
|
||||
.print_stats = smb2_print_stats,
|
||||
.dump_share_caps = smb2_dump_share_caps,
|
||||
.is_oplock_break = smb2_is_valid_oplock_break,
|
||||
+ .handle_cancelled_mid = smb2_handle_cancelled_mid,
|
||||
.downgrade_oplock = smb2_downgrade_oplock,
|
||||
.need_neg = smb2_need_neg,
|
||||
.negotiate = smb2_negotiate,
|
||||
@@ -1757,6 +1760,7 @@ struct smb_version_operations smb311_operations = {
|
||||
.print_stats = smb2_print_stats,
|
||||
.dump_share_caps = smb2_dump_share_caps,
|
||||
.is_oplock_break = smb2_is_valid_oplock_break,
|
||||
+ .handle_cancelled_mid = smb2_handle_cancelled_mid,
|
||||
.downgrade_oplock = smb2_downgrade_oplock,
|
||||
.need_neg = smb2_need_neg,
|
||||
.negotiate = smb2_negotiate,
|
||||
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h
|
||||
index 0a406ae78129..adc5234486c3 100644
|
||||
--- a/fs/cifs/smb2proto.h
|
||||
+++ b/fs/cifs/smb2proto.h
|
||||
@@ -47,6 +47,10 @@ extern struct mid_q_entry *smb2_setup_request(struct cifs_ses *ses,
|
||||
struct smb_rqst *rqst);
|
||||
extern struct mid_q_entry *smb2_setup_async_request(
|
||||
struct TCP_Server_Info *server, struct smb_rqst *rqst);
|
||||
+extern struct cifs_ses *smb2_find_smb_ses(struct TCP_Server_Info *server,
|
||||
+ __u64 ses_id);
|
||||
+extern struct cifs_tcon *smb2_find_smb_tcon(struct TCP_Server_Info *server,
|
||||
+ __u64 ses_id, __u32 tid);
|
||||
extern int smb2_calc_signature(struct smb_rqst *rqst,
|
||||
struct TCP_Server_Info *server);
|
||||
extern int smb3_calc_signature(struct smb_rqst *rqst,
|
||||
@@ -157,6 +161,9 @@ extern int SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
const u64 persistent_fid, const u64 volatile_fid,
|
||||
const __u8 oplock_level);
|
||||
+extern int smb2_handle_cancelled_mid(char *buffer,
|
||||
+ struct TCP_Server_Info *server);
|
||||
+void smb2_cancelled_close_fid(struct work_struct *work);
|
||||
extern int SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
u64 persistent_file_id, u64 volatile_file_id,
|
||||
struct kstatfs *FSData);
|
||||
diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c
|
||||
index d4c5b6f109a7..69e3b322bbfe 100644
|
||||
--- a/fs/cifs/smb2transport.c
|
||||
+++ b/fs/cifs/smb2transport.c
|
||||
@@ -115,22 +115,68 @@ smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
|
||||
}
|
||||
|
||||
static struct cifs_ses *
|
||||
-smb2_find_smb_ses(struct smb2_hdr *smb2hdr, struct TCP_Server_Info *server)
|
||||
+smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id)
|
||||
{
|
||||
struct cifs_ses *ses;
|
||||
|
||||
- spin_lock(&cifs_tcp_ses_lock);
|
||||
list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
|
||||
- if (ses->Suid != smb2hdr->SessionId)
|
||||
+ if (ses->Suid != ses_id)
|
||||
continue;
|
||||
- spin_unlock(&cifs_tcp_ses_lock);
|
||||
return ses;
|
||||
}
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+struct cifs_ses *
|
||||
+smb2_find_smb_ses(struct TCP_Server_Info *server, __u64 ses_id)
|
||||
+{
|
||||
+ struct cifs_ses *ses;
|
||||
+
|
||||
+ spin_lock(&cifs_tcp_ses_lock);
|
||||
+ ses = smb2_find_smb_ses_unlocked(server, ses_id);
|
||||
spin_unlock(&cifs_tcp_ses_lock);
|
||||
|
||||
+ return ses;
|
||||
+}
|
||||
+
|
||||
+static struct cifs_tcon *
|
||||
+smb2_find_smb_sess_tcon_unlocked(struct cifs_ses *ses, __u32 tid)
|
||||
+{
|
||||
+ struct cifs_tcon *tcon;
|
||||
+
|
||||
+ list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
|
||||
+ if (tcon->tid != tid)
|
||||
+ continue;
|
||||
+ ++tcon->tc_count;
|
||||
+ return tcon;
|
||||
+ }
|
||||
+
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Obtain tcon corresponding to the tid in the given
|
||||
+ * cifs_ses
|
||||
+ */
|
||||
+
|
||||
+struct cifs_tcon *
|
||||
+smb2_find_smb_tcon(struct TCP_Server_Info *server, __u64 ses_id, __u32 tid)
|
||||
+{
|
||||
+ struct cifs_ses *ses;
|
||||
+ struct cifs_tcon *tcon;
|
||||
+
|
||||
+ spin_lock(&cifs_tcp_ses_lock);
|
||||
+ ses = smb2_find_smb_ses_unlocked(server, ses_id);
|
||||
+ if (!ses) {
|
||||
+ spin_unlock(&cifs_tcp_ses_lock);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ tcon = smb2_find_smb_sess_tcon_unlocked(ses, tid);
|
||||
+ spin_unlock(&cifs_tcp_ses_lock);
|
||||
+
|
||||
+ return tcon;
|
||||
+}
|
||||
|
||||
int
|
||||
smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
|
||||
@@ -143,7 +189,7 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
|
||||
struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)iov[0].iov_base;
|
||||
struct cifs_ses *ses;
|
||||
|
||||
- ses = smb2_find_smb_ses(smb2_pdu, server);
|
||||
+ ses = smb2_find_smb_ses(server, smb2_pdu->SessionId);
|
||||
if (!ses) {
|
||||
cifs_dbg(VFS, "%s: Could not find session\n", __func__);
|
||||
return 0;
|
||||
@@ -314,7 +360,7 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
|
||||
struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)iov[0].iov_base;
|
||||
struct cifs_ses *ses;
|
||||
|
||||
- ses = smb2_find_smb_ses(smb2_pdu, server);
|
||||
+ ses = smb2_find_smb_ses(server, smb2_pdu->SessionId);
|
||||
if (!ses) {
|
||||
cifs_dbg(VFS, "%s: Could not find session\n", __func__);
|
||||
return 0;
|
||||
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
|
||||
index 87abe8ed074c..54af10204e83 100644
|
||||
--- a/fs/cifs/transport.c
|
||||
+++ b/fs/cifs/transport.c
|
||||
@@ -786,9 +786,11 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses,
|
||||
|
||||
rc = wait_for_response(ses->server, midQ);
|
||||
if (rc != 0) {
|
||||
+ cifs_dbg(FYI, "Cancelling wait for mid %llu\n", midQ->mid);
|
||||
send_cancel(ses->server, buf, midQ);
|
||||
spin_lock(&GlobalMid_Lock);
|
||||
if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
|
||||
+ midQ->mid_flags |= MID_WAIT_CANCELLED;
|
||||
midQ->callback = DeleteMidQEntry;
|
||||
spin_unlock(&GlobalMid_Lock);
|
||||
cifs_small_buf_release(buf);
|
||||
diff --git a/fs/ext4/crypto.c b/fs/ext4/crypto.c
|
||||
index 1a0835073663..9d6c2dcf1bd0 100644
|
||||
--- a/fs/ext4/crypto.c
|
||||
+++ b/fs/ext4/crypto.c
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <linux/random.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/spinlock_types.h>
|
||||
+#include <linux/namei.h>
|
||||
|
||||
#include "ext4_extents.h"
|
||||
#include "xattr.h"
|
||||
@@ -469,3 +470,61 @@ uint32_t ext4_validate_encryption_key_size(uint32_t mode, uint32_t size)
|
||||
return size;
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+/*
|
||||
+ * Validate dentries for encrypted directories to make sure we aren't
|
||||
+ * potentially caching stale data after a key has been added or
|
||||
+ * removed.
|
||||
+ */
|
||||
+static int ext4_d_revalidate(struct dentry *dentry, unsigned int flags)
|
||||
+{
|
||||
+ struct dentry *dir;
|
||||
+ struct ext4_crypt_info *ci;
|
||||
+ int dir_has_key, cached_with_key;
|
||||
+
|
||||
+ if (flags & LOOKUP_RCU)
|
||||
+ return -ECHILD;
|
||||
+
|
||||
+ dir = dget_parent(dentry);
|
||||
+ if (!ext4_encrypted_inode(d_inode(dir))) {
|
||||
+ dput(dir);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ ci = EXT4_I(d_inode(dir))->i_crypt_info;
|
||||
+
|
||||
+ /* this should eventually be an flag in d_flags */
|
||||
+ cached_with_key = dentry->d_fsdata != NULL;
|
||||
+ dir_has_key = (ci != NULL);
|
||||
+ dput(dir);
|
||||
+
|
||||
+ /*
|
||||
+ * If the dentry was cached without the key, and it is a
|
||||
+ * negative dentry, it might be a valid name. We can't check
|
||||
+ * if the key has since been made available due to locking
|
||||
+ * reasons, so we fail the validation so ext4_lookup() can do
|
||||
+ * this check.
|
||||
+ *
|
||||
+ * We also fail the validation if the dentry was created with
|
||||
+ * the key present, but we no longer have the key, or vice versa.
|
||||
+ */
|
||||
+ if ((!cached_with_key && d_is_negative(dentry)) ||
|
||||
+ (!cached_with_key && dir_has_key) ||
|
||||
+ (cached_with_key && !dir_has_key)) {
|
||||
+#if 0 /* Revalidation debug */
|
||||
+ char buf[80];
|
||||
+ char *cp = simple_dname(dentry, buf, sizeof(buf));
|
||||
+
|
||||
+ if (IS_ERR(cp))
|
||||
+ cp = (char *) "???";
|
||||
+ pr_err("revalidate: %s %p %d %d %d\n", cp, dentry->d_fsdata,
|
||||
+ cached_with_key, d_is_negative(dentry),
|
||||
+ dir_has_key);
|
||||
+#endif
|
||||
+ return 0;
|
||||
+ }
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+const struct dentry_operations ext4_encrypted_d_ops = {
|
||||
+ .d_revalidate = ext4_d_revalidate,
|
||||
+};
|
||||
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
|
||||
index 1d1bca74f844..6d17f31a31d7 100644
|
||||
--- a/fs/ext4/dir.c
|
||||
+++ b/fs/ext4/dir.c
|
||||
@@ -111,6 +111,12 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
|
||||
int dir_has_error = 0;
|
||||
struct ext4_str fname_crypto_str = {.name = NULL, .len = 0};
|
||||
|
||||
+ if (ext4_encrypted_inode(inode)) {
|
||||
+ err = ext4_get_encryption_info(inode);
|
||||
+ if (err && err != -ENOKEY)
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
if (is_dx_dir(inode)) {
|
||||
err = ext4_dx_readdir(file, ctx);
|
||||
if (err != ERR_BAD_DX_DIR) {
|
||||
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
|
||||
index 362d59b24f1d..3de9bb357b4f 100644
|
||||
--- a/fs/ext4/ext4.h
|
||||
+++ b/fs/ext4/ext4.h
|
||||
@@ -2268,6 +2268,7 @@ struct page *ext4_encrypt(struct inode *inode,
|
||||
struct page *plaintext_page);
|
||||
int ext4_decrypt(struct page *page);
|
||||
int ext4_encrypted_zeroout(struct inode *inode, struct ext4_extent *ex);
|
||||
+extern const struct dentry_operations ext4_encrypted_d_ops;
|
||||
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
int ext4_init_crypto(void);
|
||||
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
|
||||
index 789e2d6724a9..bcd7c4788903 100644
|
||||
--- a/fs/ext4/ioctl.c
|
||||
+++ b/fs/ext4/ioctl.c
|
||||
@@ -622,6 +622,9 @@ resizefs_out:
|
||||
struct ext4_encryption_policy policy;
|
||||
int err = 0;
|
||||
|
||||
+ if (!ext4_has_feature_encrypt(sb))
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
if (copy_from_user(&policy,
|
||||
(struct ext4_encryption_policy __user *)arg,
|
||||
sizeof(policy))) {
|
||||
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
|
||||
index 573b4cbb0cb9..fafa903ab3c0 100644
|
||||
--- a/fs/ext4/namei.c
|
||||
+++ b/fs/ext4/namei.c
|
||||
@@ -1557,6 +1557,24 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi
|
||||
struct ext4_dir_entry_2 *de;
|
||||
struct buffer_head *bh;
|
||||
|
||||
+ if (ext4_encrypted_inode(dir)) {
|
||||
+ int res = ext4_get_encryption_info(dir);
|
||||
+
|
||||
+ /*
|
||||
+ * This should be a properly defined flag for
|
||||
+ * dentry->d_flags when we uplift this to the VFS.
|
||||
+ * d_fsdata is set to (void *) 1 if if the dentry is
|
||||
+ * created while the directory was encrypted and we
|
||||
+ * don't have access to the key.
|
||||
+ */
|
||||
+ dentry->d_fsdata = NULL;
|
||||
+ if (ext4_encryption_info(dir))
|
||||
+ dentry->d_fsdata = (void *) 1;
|
||||
+ d_set_d_op(dentry, &ext4_encrypted_d_ops);
|
||||
+ if (res && res != -ENOKEY)
|
||||
+ return ERR_PTR(res);
|
||||
+ }
|
||||
+
|
||||
if (dentry->d_name.len > EXT4_NAME_LEN)
|
||||
return ERR_PTR(-ENAMETOOLONG);
|
||||
|
||||
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
|
||||
index 00575d776d91..7162ab7bc093 100644
|
||||
--- a/fs/nfsd/nfs3xdr.c
|
||||
+++ b/fs/nfsd/nfs3xdr.c
|
||||
@@ -358,6 +358,7 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
|
||||
{
|
||||
unsigned int len, v, hdr, dlen;
|
||||
u32 max_blocksize = svc_max_payload(rqstp);
|
||||
+ struct kvec *head = rqstp->rq_arg.head;
|
||||
|
||||
p = decode_fh(p, &args->fh);
|
||||
if (!p)
|
||||
@@ -367,6 +368,8 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
|
||||
args->count = ntohl(*p++);
|
||||
args->stable = ntohl(*p++);
|
||||
len = args->len = ntohl(*p++);
|
||||
+ if ((void *)p > head->iov_base + head->iov_len)
|
||||
+ return 0;
|
||||
/*
|
||||
* The count must equal the amount of data passed.
|
||||
*/
|
||||
@@ -377,9 +380,8 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
|
||||
* Check to make sure that we got the right number of
|
||||
* bytes.
|
||||
*/
|
||||
- hdr = (void*)p - rqstp->rq_arg.head[0].iov_base;
|
||||
- dlen = rqstp->rq_arg.head[0].iov_len + rqstp->rq_arg.page_len
|
||||
- - hdr;
|
||||
+ hdr = (void*)p - head->iov_base;
|
||||
+ dlen = head->iov_len + rqstp->rq_arg.page_len - hdr;
|
||||
/*
|
||||
* Round the length of the data which was specified up to
|
||||
* the next multiple of XDR units and then compare that
|
||||
@@ -396,7 +398,7 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
|
||||
len = args->len = max_blocksize;
|
||||
}
|
||||
rqstp->rq_vec[0].iov_base = (void*)p;
|
||||
- rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr;
|
||||
+ rqstp->rq_vec[0].iov_len = head->iov_len - hdr;
|
||||
v = 0;
|
||||
while (len > rqstp->rq_vec[v].iov_len) {
|
||||
len -= rqstp->rq_vec[v].iov_len;
|
||||
@@ -471,6 +473,8 @@ nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p,
|
||||
/* first copy and check from the first page */
|
||||
old = (char*)p;
|
||||
vec = &rqstp->rq_arg.head[0];
|
||||
+ if ((void *)old > vec->iov_base + vec->iov_len)
|
||||
+ return 0;
|
||||
avail = vec->iov_len - (old - (char*)vec->iov_base);
|
||||
while (len && avail && *old) {
|
||||
*new++ = *old++;
|
||||
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
|
||||
index 79d964aa8079..bf913201a6ad 100644
|
||||
--- a/fs/nfsd/nfsxdr.c
|
||||
+++ b/fs/nfsd/nfsxdr.c
|
||||
@@ -280,6 +280,7 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
|
||||
struct nfsd_writeargs *args)
|
||||
{
|
||||
unsigned int len, hdr, dlen;
|
||||
+ struct kvec *head = rqstp->rq_arg.head;
|
||||
int v;
|
||||
|
||||
p = decode_fh(p, &args->fh);
|
||||
@@ -300,9 +301,10 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
|
||||
* Check to make sure that we got the right number of
|
||||
* bytes.
|
||||
*/
|
||||
- hdr = (void*)p - rqstp->rq_arg.head[0].iov_base;
|
||||
- dlen = rqstp->rq_arg.head[0].iov_len + rqstp->rq_arg.page_len
|
||||
- - hdr;
|
||||
+ hdr = (void*)p - head->iov_base;
|
||||
+ if (hdr > head->iov_len)
|
||||
+ return 0;
|
||||
+ dlen = head->iov_len + rqstp->rq_arg.page_len - hdr;
|
||||
|
||||
/*
|
||||
* Round the length of the data which was specified up to
|
||||
@@ -316,7 +318,7 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
|
||||
return 0;
|
||||
|
||||
rqstp->rq_vec[0].iov_base = (void*)p;
|
||||
- rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr;
|
||||
+ rqstp->rq_vec[0].iov_len = head->iov_len - hdr;
|
||||
v = 0;
|
||||
while (len > rqstp->rq_vec[v].iov_len) {
|
||||
len -= rqstp->rq_vec[v].iov_len;
|
||||
diff --git a/fs/timerfd.c b/fs/timerfd.c
|
||||
index 053818dd6c18..1327a02ec778 100644
|
||||
--- a/fs/timerfd.c
|
||||
+++ b/fs/timerfd.c
|
||||
@@ -40,6 +40,7 @@ struct timerfd_ctx {
|
||||
short unsigned settime_flags; /* to show in fdinfo */
|
||||
struct rcu_head rcu;
|
||||
struct list_head clist;
|
||||
+ spinlock_t cancel_lock;
|
||||
bool might_cancel;
|
||||
};
|
||||
|
||||
@@ -112,7 +113,7 @@ void timerfd_clock_was_set(void)
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
-static void timerfd_remove_cancel(struct timerfd_ctx *ctx)
|
||||
+static void __timerfd_remove_cancel(struct timerfd_ctx *ctx)
|
||||
{
|
||||
if (ctx->might_cancel) {
|
||||
ctx->might_cancel = false;
|
||||
@@ -122,6 +123,13 @@ static void timerfd_remove_cancel(struct timerfd_ctx *ctx)
|
||||
}
|
||||
}
|
||||
|
||||
+static void timerfd_remove_cancel(struct timerfd_ctx *ctx)
|
||||
+{
|
||||
+ spin_lock(&ctx->cancel_lock);
|
||||
+ __timerfd_remove_cancel(ctx);
|
||||
+ spin_unlock(&ctx->cancel_lock);
|
||||
+}
|
||||
+
|
||||
static bool timerfd_canceled(struct timerfd_ctx *ctx)
|
||||
{
|
||||
if (!ctx->might_cancel || ctx->moffs.tv64 != KTIME_MAX)
|
||||
@@ -132,6 +140,7 @@ static bool timerfd_canceled(struct timerfd_ctx *ctx)
|
||||
|
||||
static void timerfd_setup_cancel(struct timerfd_ctx *ctx, int flags)
|
||||
{
|
||||
+ spin_lock(&ctx->cancel_lock);
|
||||
if ((ctx->clockid == CLOCK_REALTIME ||
|
||||
ctx->clockid == CLOCK_REALTIME_ALARM) &&
|
||||
(flags & TFD_TIMER_ABSTIME) && (flags & TFD_TIMER_CANCEL_ON_SET)) {
|
||||
@@ -141,9 +150,10 @@ static void timerfd_setup_cancel(struct timerfd_ctx *ctx, int flags)
|
||||
list_add_rcu(&ctx->clist, &cancel_list);
|
||||
spin_unlock(&cancel_lock);
|
||||
}
|
||||
- } else if (ctx->might_cancel) {
|
||||
- timerfd_remove_cancel(ctx);
|
||||
+ } else {
|
||||
+ __timerfd_remove_cancel(ctx);
|
||||
}
|
||||
+ spin_unlock(&ctx->cancel_lock);
|
||||
}
|
||||
|
||||
static ktime_t timerfd_get_remaining(struct timerfd_ctx *ctx)
|
||||
@@ -395,6 +405,7 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags)
|
||||
return -ENOMEM;
|
||||
|
||||
init_waitqueue_head(&ctx->wqh);
|
||||
+ spin_lock_init(&ctx->cancel_lock);
|
||||
ctx->clockid = clockid;
|
||||
|
||||
if (isalarm(ctx))
|
||||
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h
|
||||
index 366cf77953b5..806d0ab845e0 100644
|
||||
--- a/include/linux/mtd/map.h
|
||||
+++ b/include/linux/mtd/map.h
|
||||
@@ -122,18 +122,13 @@
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MTD_MAP_BANK_WIDTH_32
|
||||
-# ifdef map_bankwidth
|
||||
-# undef map_bankwidth
|
||||
-# define map_bankwidth(map) ((map)->bankwidth)
|
||||
-# undef map_bankwidth_is_large
|
||||
-# define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8)
|
||||
-# undef map_words
|
||||
-# define map_words(map) map_calc_words(map)
|
||||
-# else
|
||||
-# define map_bankwidth(map) 32
|
||||
-# define map_bankwidth_is_large(map) (1)
|
||||
-# define map_words(map) map_calc_words(map)
|
||||
-# endif
|
||||
+/* always use indirect access for 256-bit to preserve kernel stack */
|
||||
+# undef map_bankwidth
|
||||
+# define map_bankwidth(map) ((map)->bankwidth)
|
||||
+# undef map_bankwidth_is_large
|
||||
+# define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8)
|
||||
+# undef map_words
|
||||
+# define map_words(map) map_calc_words(map)
|
||||
#define map_bankwidth_is_32(map) (map_bankwidth(map) == 32)
|
||||
#undef MAX_MAP_BANKWIDTH
|
||||
#define MAX_MAP_BANKWIDTH 32
|
||||
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
|
||||
index 8e33019d8e7b..acfb16fdcd55 100644
|
||||
--- a/net/netlink/af_netlink.c
|
||||
+++ b/net/netlink/af_netlink.c
|
||||
@@ -2107,7 +2107,7 @@ static int netlink_dump(struct sock *sk)
|
||||
if (!skb) {
|
||||
alloc_size = alloc_min_size;
|
||||
skb = netlink_alloc_skb(sk, alloc_size, nlk->portid,
|
||||
- (GFP_KERNEL & ~__GFP_DIRECT_RECLAIM));
|
||||
+ GFP_KERNEL);
|
||||
}
|
||||
if (!skb)
|
||||
goto errout_skb;
|
||||
diff --git a/sound/ppc/awacs.c b/sound/ppc/awacs.c
|
||||
index 09da7b52bc2e..1468e4b7bf93 100644
|
||||
--- a/sound/ppc/awacs.c
|
||||
+++ b/sound/ppc/awacs.c
|
||||
@@ -991,6 +991,7 @@ snd_pmac_awacs_init(struct snd_pmac *chip)
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
+ master_vol = NULL;
|
||||
if (pm7500)
|
||||
err = build_mixers(chip,
|
||||
ARRAY_SIZE(snd_pmac_awacs_mixers_pmac7500),
|
||||
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
|
||||
index 7a5c9a36c1db..daba8c56b43b 100644
|
||||
--- a/sound/soc/intel/boards/bytcr_rt5640.c
|
||||
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
|
||||
@@ -139,7 +139,7 @@ static struct snd_soc_dai_link byt_dailink[] = {
|
||||
.codec_dai_name = "snd-soc-dummy-dai",
|
||||
.codec_name = "snd-soc-dummy",
|
||||
.platform_name = "sst-mfld-platform",
|
||||
- .ignore_suspend = 1,
|
||||
+ .nonatomic = true,
|
||||
.dynamic = 1,
|
||||
.dpcm_playback = 1,
|
||||
.dpcm_capture = 1,
|
||||
@@ -166,6 +166,7 @@ static struct snd_soc_dai_link byt_dailink[] = {
|
||||
| SND_SOC_DAIFMT_CBS_CFS,
|
||||
.be_hw_params_fixup = byt_codec_fixup,
|
||||
.ignore_suspend = 1,
|
||||
+ .nonatomic = true,
|
||||
.dpcm_playback = 1,
|
||||
.dpcm_capture = 1,
|
||||
.ops = &byt_be_ssp2_ops,
|
||||
2073
patch/kernel/s5p6818-default/03-patch-4.4.67-68.patch
Normal file
2073
patch/kernel/s5p6818-default/03-patch-4.4.67-68.patch
Normal file
File diff suppressed because it is too large
Load Diff
2955
patch/kernel/s5p6818-default/03-patch-4.4.68-69.patch
Normal file
2955
patch/kernel/s5p6818-default/03-patch-4.4.68-69.patch
Normal file
File diff suppressed because it is too large
Load Diff
3739
patch/kernel/s5p6818-default/03-patch-4.4.69-70.patch
Normal file
3739
patch/kernel/s5p6818-default/03-patch-4.4.69-70.patch
Normal file
File diff suppressed because it is too large
Load Diff
2203
patch/kernel/s5p6818-default/03-patch-4.4.70-71.patch
Normal file
2203
patch/kernel/s5p6818-default/03-patch-4.4.70-71.patch
Normal file
File diff suppressed because it is too large
Load Diff
3263
patch/kernel/s5p6818-default/03-patch-4.4.71-72.patch
Normal file
3263
patch/kernel/s5p6818-default/03-patch-4.4.71-72.patch
Normal file
File diff suppressed because it is too large
Load Diff
2192
patch/kernel/s5p6818-default/03-patch-4.4.72-73.patch
Normal file
2192
patch/kernel/s5p6818-default/03-patch-4.4.72-73.patch
Normal file
File diff suppressed because it is too large
Load Diff
1488
patch/kernel/s5p6818-default/03-patch-4.4.73-74.patch
Normal file
1488
patch/kernel/s5p6818-default/03-patch-4.4.73-74.patch
Normal file
File diff suppressed because it is too large
Load Diff
1018
patch/kernel/s5p6818-default/03-patch-4.4.74-75.patch
Normal file
1018
patch/kernel/s5p6818-default/03-patch-4.4.74-75.patch
Normal file
File diff suppressed because it is too large
Load Diff
2853
patch/kernel/s5p6818-default/03-patch-4.4.75-76.patch
Normal file
2853
patch/kernel/s5p6818-default/03-patch-4.4.75-76.patch
Normal file
File diff suppressed because it is too large
Load Diff
1575
patch/kernel/s5p6818-default/03-patch-4.4.76-77.patch
Normal file
1575
patch/kernel/s5p6818-default/03-patch-4.4.76-77.patch
Normal file
File diff suppressed because it is too large
Load Diff
3019
patch/kernel/s5p6818-default/03-patch-4.4.77-78.patch
Normal file
3019
patch/kernel/s5p6818-default/03-patch-4.4.77-78.patch
Normal file
File diff suppressed because it is too large
Load Diff
2607
patch/kernel/s5p6818-default/03-patch-4.4.78-79.patch
Normal file
2607
patch/kernel/s5p6818-default/03-patch-4.4.78-79.patch
Normal file
File diff suppressed because it is too large
Load Diff
3274
patch/kernel/s5p6818-default/03-patch-4.4.79-80.patch
Normal file
3274
patch/kernel/s5p6818-default/03-patch-4.4.79-80.patch
Normal file
File diff suppressed because it is too large
Load Diff
2082
patch/kernel/s5p6818-default/03-patch-4.4.80-81.patch
Normal file
2082
patch/kernel/s5p6818-default/03-patch-4.4.80-81.patch
Normal file
File diff suppressed because it is too large
Load Diff
330
patch/kernel/s5p6818-default/03-patch-4.4.81-82.patch
Normal file
330
patch/kernel/s5p6818-default/03-patch-4.4.81-82.patch
Normal file
@ -0,0 +1,330 @@
|
||||
diff --git a/Makefile b/Makefile
|
||||
index d049e53a6960..52f2dd8dcebd 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 4
|
||||
-SUBLEVEL = 81
|
||||
+SUBLEVEL = 82
|
||||
EXTRAVERSION =
|
||||
NAME = Blurry Fish Butt
|
||||
|
||||
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
|
||||
index 1f1ff7e7b9cf..ba079e279b58 100644
|
||||
--- a/arch/arm/kvm/mmu.c
|
||||
+++ b/arch/arm/kvm/mmu.c
|
||||
@@ -1629,12 +1629,16 @@ static int kvm_test_age_hva_handler(struct kvm *kvm, gpa_t gpa, void *data)
|
||||
|
||||
int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end)
|
||||
{
|
||||
+ if (!kvm->arch.pgd)
|
||||
+ return 0;
|
||||
trace_kvm_age_hva(start, end);
|
||||
return handle_hva_to_gpa(kvm, start, end, kvm_age_hva_handler, NULL);
|
||||
}
|
||||
|
||||
int kvm_test_age_hva(struct kvm *kvm, unsigned long hva)
|
||||
{
|
||||
+ if (!kvm->arch.pgd)
|
||||
+ return 0;
|
||||
trace_kvm_test_age_hva(hva);
|
||||
return handle_hva_to_gpa(kvm, hva, hva, kvm_test_age_hva_handler, NULL);
|
||||
}
|
||||
diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c
|
||||
index 0e2919dd8df3..1395eeb6005f 100644
|
||||
--- a/arch/s390/net/bpf_jit_comp.c
|
||||
+++ b/arch/s390/net/bpf_jit_comp.c
|
||||
@@ -1250,7 +1250,8 @@ static int bpf_jit_prog(struct bpf_jit *jit, struct bpf_prog *fp)
|
||||
insn_count = bpf_jit_insn(jit, fp, i);
|
||||
if (insn_count < 0)
|
||||
return -1;
|
||||
- jit->addrs[i + 1] = jit->prg; /* Next instruction address */
|
||||
+ /* Next instruction address */
|
||||
+ jit->addrs[i + insn_count] = jit->prg;
|
||||
}
|
||||
bpf_jit_epilogue(jit);
|
||||
|
||||
diff --git a/arch/sparc/include/asm/mmu_context_64.h b/arch/sparc/include/asm/mmu_context_64.h
|
||||
index 349dd23e2876..0cdeb2b483a0 100644
|
||||
--- a/arch/sparc/include/asm/mmu_context_64.h
|
||||
+++ b/arch/sparc/include/asm/mmu_context_64.h
|
||||
@@ -25,9 +25,11 @@ void destroy_context(struct mm_struct *mm);
|
||||
void __tsb_context_switch(unsigned long pgd_pa,
|
||||
struct tsb_config *tsb_base,
|
||||
struct tsb_config *tsb_huge,
|
||||
- unsigned long tsb_descr_pa);
|
||||
+ unsigned long tsb_descr_pa,
|
||||
+ unsigned long secondary_ctx);
|
||||
|
||||
-static inline void tsb_context_switch(struct mm_struct *mm)
|
||||
+static inline void tsb_context_switch_ctx(struct mm_struct *mm,
|
||||
+ unsigned long ctx)
|
||||
{
|
||||
__tsb_context_switch(__pa(mm->pgd),
|
||||
&mm->context.tsb_block[0],
|
||||
@@ -38,9 +40,12 @@ static inline void tsb_context_switch(struct mm_struct *mm)
|
||||
#else
|
||||
NULL
|
||||
#endif
|
||||
- , __pa(&mm->context.tsb_descr[0]));
|
||||
+ , __pa(&mm->context.tsb_descr[0]),
|
||||
+ ctx);
|
||||
}
|
||||
|
||||
+#define tsb_context_switch(X) tsb_context_switch_ctx(X, 0)
|
||||
+
|
||||
void tsb_grow(struct mm_struct *mm,
|
||||
unsigned long tsb_index,
|
||||
unsigned long mm_rss);
|
||||
@@ -110,8 +115,7 @@ static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, str
|
||||
* cpu0 to update it's TSB because at that point the cpu_vm_mask
|
||||
* only had cpu1 set in it.
|
||||
*/
|
||||
- load_secondary_context(mm);
|
||||
- tsb_context_switch(mm);
|
||||
+ tsb_context_switch_ctx(mm, CTX_HWBITS(mm->context));
|
||||
|
||||
/* Any time a processor runs a context on an address space
|
||||
* for the first time, we must flush that context out of the
|
||||
diff --git a/arch/sparc/kernel/tsb.S b/arch/sparc/kernel/tsb.S
|
||||
index 395ec1800530..7d961f6e3907 100644
|
||||
--- a/arch/sparc/kernel/tsb.S
|
||||
+++ b/arch/sparc/kernel/tsb.S
|
||||
@@ -375,6 +375,7 @@ tsb_flush:
|
||||
* %o1: TSB base config pointer
|
||||
* %o2: TSB huge config pointer, or NULL if none
|
||||
* %o3: Hypervisor TSB descriptor physical address
|
||||
+ * %o4: Secondary context to load, if non-zero
|
||||
*
|
||||
* We have to run this whole thing with interrupts
|
||||
* disabled so that the current cpu doesn't change
|
||||
@@ -387,6 +388,17 @@ __tsb_context_switch:
|
||||
rdpr %pstate, %g1
|
||||
wrpr %g1, PSTATE_IE, %pstate
|
||||
|
||||
+ brz,pn %o4, 1f
|
||||
+ mov SECONDARY_CONTEXT, %o5
|
||||
+
|
||||
+661: stxa %o4, [%o5] ASI_DMMU
|
||||
+ .section .sun4v_1insn_patch, "ax"
|
||||
+ .word 661b
|
||||
+ stxa %o4, [%o5] ASI_MMU
|
||||
+ .previous
|
||||
+ flush %g6
|
||||
+
|
||||
+1:
|
||||
TRAP_LOAD_TRAP_BLOCK(%g2, %g3)
|
||||
|
||||
stx %o0, [%g2 + TRAP_PER_CPU_PGD_PADDR]
|
||||
diff --git a/arch/sparc/power/hibernate.c b/arch/sparc/power/hibernate.c
|
||||
index 17bd2e167e07..df707a8ad311 100644
|
||||
--- a/arch/sparc/power/hibernate.c
|
||||
+++ b/arch/sparc/power/hibernate.c
|
||||
@@ -35,6 +35,5 @@ void restore_processor_state(void)
|
||||
{
|
||||
struct mm_struct *mm = current->active_mm;
|
||||
|
||||
- load_secondary_context(mm);
|
||||
- tsb_context_switch(mm);
|
||||
+ tsb_context_switch_ctx(mm, CTX_HWBITS(mm->context));
|
||||
}
|
||||
diff --git a/mm/mempool.c b/mm/mempool.c
|
||||
index 004d42b1dfaf..7924f4f58a6d 100644
|
||||
--- a/mm/mempool.c
|
||||
+++ b/mm/mempool.c
|
||||
@@ -135,8 +135,8 @@ static void *remove_element(mempool_t *pool)
|
||||
void *element = pool->elements[--pool->curr_nr];
|
||||
|
||||
BUG_ON(pool->curr_nr < 0);
|
||||
- check_element(pool, element);
|
||||
kasan_unpoison_element(pool, element);
|
||||
+ check_element(pool, element);
|
||||
return element;
|
||||
}
|
||||
|
||||
diff --git a/net/core/dev.c b/net/core/dev.c
|
||||
index 4b0853194a03..24d243084aab 100644
|
||||
--- a/net/core/dev.c
|
||||
+++ b/net/core/dev.c
|
||||
@@ -2551,7 +2551,7 @@ static inline bool skb_needs_check(struct sk_buff *skb, bool tx_path)
|
||||
{
|
||||
if (tx_path)
|
||||
return skb->ip_summed != CHECKSUM_PARTIAL &&
|
||||
- skb->ip_summed != CHECKSUM_NONE;
|
||||
+ skb->ip_summed != CHECKSUM_UNNECESSARY;
|
||||
|
||||
return skb->ip_summed == CHECKSUM_NONE;
|
||||
}
|
||||
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
|
||||
index 5d58a6703a43..09c73dd541c5 100644
|
||||
--- a/net/ipv4/ip_output.c
|
||||
+++ b/net/ipv4/ip_output.c
|
||||
@@ -922,11 +922,12 @@ static int __ip_append_data(struct sock *sk,
|
||||
csummode = CHECKSUM_PARTIAL;
|
||||
|
||||
cork->length += length;
|
||||
- if ((((length + (skb ? skb->len : fragheaderlen)) > mtu) ||
|
||||
- (skb && skb_is_gso(skb))) &&
|
||||
+ if ((skb && skb_is_gso(skb)) ||
|
||||
+ (((length + (skb ? skb->len : fragheaderlen)) > mtu) &&
|
||||
+ (skb_queue_len(queue) <= 1) &&
|
||||
(sk->sk_protocol == IPPROTO_UDP) &&
|
||||
(rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len &&
|
||||
- (sk->sk_type == SOCK_DGRAM) && !sk->sk_no_check_tx) {
|
||||
+ (sk->sk_type == SOCK_DGRAM) && !sk->sk_no_check_tx)) {
|
||||
err = ip_ufo_append_data(sk, queue, getfrag, from, length,
|
||||
hh_len, fragheaderlen, transhdrlen,
|
||||
maxfraglen, flags);
|
||||
@@ -1242,6 +1243,7 @@ ssize_t ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page,
|
||||
return -EINVAL;
|
||||
|
||||
if ((size + skb->len > mtu) &&
|
||||
+ (skb_queue_len(&sk->sk_write_queue) == 1) &&
|
||||
(sk->sk_protocol == IPPROTO_UDP) &&
|
||||
(rt->dst.dev->features & NETIF_F_UFO)) {
|
||||
if (skb->ip_summed != CHECKSUM_PARTIAL)
|
||||
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
|
||||
index 8f13b2eaabf8..f0dabd125c43 100644
|
||||
--- a/net/ipv4/tcp_input.c
|
||||
+++ b/net/ipv4/tcp_input.c
|
||||
@@ -2503,8 +2503,8 @@ static inline void tcp_end_cwnd_reduction(struct sock *sk)
|
||||
struct tcp_sock *tp = tcp_sk(sk);
|
||||
|
||||
/* Reset cwnd to ssthresh in CWR or Recovery (unless it's undone) */
|
||||
- if (inet_csk(sk)->icsk_ca_state == TCP_CA_CWR ||
|
||||
- (tp->undo_marker && tp->snd_ssthresh < TCP_INFINITE_SSTHRESH)) {
|
||||
+ if (tp->snd_ssthresh < TCP_INFINITE_SSTHRESH &&
|
||||
+ (inet_csk(sk)->icsk_ca_state == TCP_CA_CWR || tp->undo_marker)) {
|
||||
tp->snd_cwnd = tp->snd_ssthresh;
|
||||
tp->snd_cwnd_stamp = tcp_time_stamp;
|
||||
}
|
||||
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
|
||||
index 3fdcdc730f71..850d1b5bfd81 100644
|
||||
--- a/net/ipv4/tcp_output.c
|
||||
+++ b/net/ipv4/tcp_output.c
|
||||
@@ -3256,6 +3256,9 @@ int tcp_connect(struct sock *sk)
|
||||
struct sk_buff *buff;
|
||||
int err;
|
||||
|
||||
+ if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk))
|
||||
+ return -EHOSTUNREACH; /* Routing failure or similar. */
|
||||
+
|
||||
tcp_connect_init(sk);
|
||||
|
||||
if (unlikely(tp->repair)) {
|
||||
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
|
||||
index ebb34d0c5e80..1ec12a4f327e 100644
|
||||
--- a/net/ipv4/tcp_timer.c
|
||||
+++ b/net/ipv4/tcp_timer.c
|
||||
@@ -606,7 +606,8 @@ static void tcp_keepalive_timer (unsigned long data)
|
||||
goto death;
|
||||
}
|
||||
|
||||
- if (!sock_flag(sk, SOCK_KEEPOPEN) || sk->sk_state == TCP_CLOSE)
|
||||
+ if (!sock_flag(sk, SOCK_KEEPOPEN) ||
|
||||
+ ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_SYN_SENT)))
|
||||
goto out;
|
||||
|
||||
elapsed = keepalive_time_when(tp);
|
||||
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
|
||||
index e9513e397c4f..301e60829c7e 100644
|
||||
--- a/net/ipv4/udp.c
|
||||
+++ b/net/ipv4/udp.c
|
||||
@@ -819,7 +819,7 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4)
|
||||
if (is_udplite) /* UDP-Lite */
|
||||
csum = udplite_csum(skb);
|
||||
|
||||
- else if (sk->sk_no_check_tx) { /* UDP csum disabled */
|
||||
+ else if (sk->sk_no_check_tx && !skb_is_gso(skb)) { /* UDP csum off */
|
||||
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
goto send;
|
||||
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
|
||||
index 6396f1c80ae9..6dfc3daf7c21 100644
|
||||
--- a/net/ipv4/udp_offload.c
|
||||
+++ b/net/ipv4/udp_offload.c
|
||||
@@ -231,7 +231,7 @@ static struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb,
|
||||
if (uh->check == 0)
|
||||
uh->check = CSUM_MANGLED_0;
|
||||
|
||||
- skb->ip_summed = CHECKSUM_NONE;
|
||||
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
|
||||
/* Fragment the skb. IP headers of the fragments are updated in
|
||||
* inet_gso_segment()
|
||||
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
|
||||
index 0de3245ea42f..e22339fad10b 100644
|
||||
--- a/net/ipv6/ip6_output.c
|
||||
+++ b/net/ipv6/ip6_output.c
|
||||
@@ -1357,11 +1357,12 @@ emsgsize:
|
||||
*/
|
||||
|
||||
cork->length += length;
|
||||
- if ((((length + (skb ? skb->len : headersize)) > mtu) ||
|
||||
- (skb && skb_is_gso(skb))) &&
|
||||
+ if ((skb && skb_is_gso(skb)) ||
|
||||
+ (((length + (skb ? skb->len : headersize)) > mtu) &&
|
||||
+ (skb_queue_len(queue) <= 1) &&
|
||||
(sk->sk_protocol == IPPROTO_UDP) &&
|
||||
(rt->dst.dev->features & NETIF_F_UFO) &&
|
||||
- (sk->sk_type == SOCK_DGRAM) && !udp_get_no_check6_tx(sk)) {
|
||||
+ (sk->sk_type == SOCK_DGRAM) && !udp_get_no_check6_tx(sk))) {
|
||||
err = ip6_ufo_append_data(sk, queue, getfrag, from, length,
|
||||
hh_len, fragheaderlen, exthdrlen,
|
||||
transhdrlen, mtu, flags, fl6);
|
||||
diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c
|
||||
index 01582966ffa0..2e3c12eeca07 100644
|
||||
--- a/net/ipv6/udp_offload.c
|
||||
+++ b/net/ipv6/udp_offload.c
|
||||
@@ -86,7 +86,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
|
||||
if (uh->check == 0)
|
||||
uh->check = CSUM_MANGLED_0;
|
||||
|
||||
- skb->ip_summed = CHECKSUM_NONE;
|
||||
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
|
||||
/* Check if there is enough headroom to insert fragment header. */
|
||||
tnl_hlen = skb_tnl_header_len(skb);
|
||||
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
|
||||
index 061771ca2582..148ec130d99d 100644
|
||||
--- a/net/packet/af_packet.c
|
||||
+++ b/net/packet/af_packet.c
|
||||
@@ -3622,14 +3622,19 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
|
||||
|
||||
if (optlen != sizeof(val))
|
||||
return -EINVAL;
|
||||
- if (po->rx_ring.pg_vec || po->tx_ring.pg_vec)
|
||||
- return -EBUSY;
|
||||
if (copy_from_user(&val, optval, sizeof(val)))
|
||||
return -EFAULT;
|
||||
if (val > INT_MAX)
|
||||
return -EINVAL;
|
||||
- po->tp_reserve = val;
|
||||
- return 0;
|
||||
+ lock_sock(sk);
|
||||
+ if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) {
|
||||
+ ret = -EBUSY;
|
||||
+ } else {
|
||||
+ po->tp_reserve = val;
|
||||
+ ret = 0;
|
||||
+ }
|
||||
+ release_sock(sk);
|
||||
+ return ret;
|
||||
}
|
||||
case PACKET_LOSS:
|
||||
{
|
||||
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
|
||||
index d05869646515..0915d448ba23 100644
|
||||
--- a/net/sched/act_ipt.c
|
||||
+++ b/net/sched/act_ipt.c
|
||||
@@ -42,8 +42,8 @@ static int ipt_init_target(struct xt_entry_target *t, char *table, unsigned int
|
||||
return PTR_ERR(target);
|
||||
|
||||
t->u.kernel.target = target;
|
||||
+ memset(&par, 0, sizeof(par));
|
||||
par.table = table;
|
||||
- par.entryinfo = NULL;
|
||||
par.target = target;
|
||||
par.targinfo = t->data;
|
||||
par.hook_mask = hook;
|
||||
476
patch/kernel/s5p6818-default/03-patch-4.4.82-83.patch
Normal file
476
patch/kernel/s5p6818-default/03-patch-4.4.82-83.patch
Normal file
@ -0,0 +1,476 @@
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 52f2dd8dcebd..7f67b35caf99 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 4
|
||||
-SUBLEVEL = 82
|
||||
+SUBLEVEL = 83
|
||||
EXTRAVERSION =
|
||||
NAME = Blurry Fish Butt
|
||||
|
||||
diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c
|
||||
index fa24d5196615..c7122919a8c0 100644
|
||||
--- a/drivers/iio/accel/bmc150-accel-core.c
|
||||
+++ b/drivers/iio/accel/bmc150-accel-core.c
|
||||
@@ -194,7 +194,6 @@ struct bmc150_accel_data {
|
||||
struct device *dev;
|
||||
int irq;
|
||||
struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
|
||||
- atomic_t active_intr;
|
||||
struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
|
||||
struct mutex mutex;
|
||||
u8 fifo_mode, watermark;
|
||||
@@ -489,11 +488,6 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
|
||||
goto out_fix_power_state;
|
||||
}
|
||||
|
||||
- if (state)
|
||||
- atomic_inc(&data->active_intr);
|
||||
- else
|
||||
- atomic_dec(&data->active_intr);
|
||||
-
|
||||
return 0;
|
||||
|
||||
out_fix_power_state:
|
||||
@@ -1704,8 +1698,7 @@ static int bmc150_accel_resume(struct device *dev)
|
||||
struct bmc150_accel_data *data = iio_priv(indio_dev);
|
||||
|
||||
mutex_lock(&data->mutex);
|
||||
- if (atomic_read(&data->active_intr))
|
||||
- bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0);
|
||||
+ bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0);
|
||||
bmc150_accel_fifo_set_mode(data);
|
||||
mutex_unlock(&data->mutex);
|
||||
|
||||
diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c
|
||||
index b10f629cc44b..1dbc2143cdfc 100644
|
||||
--- a/drivers/iio/adc/vf610_adc.c
|
||||
+++ b/drivers/iio/adc/vf610_adc.c
|
||||
@@ -77,7 +77,7 @@
|
||||
#define VF610_ADC_ADSTS_MASK 0x300
|
||||
#define VF610_ADC_ADLPC_EN 0x80
|
||||
#define VF610_ADC_ADHSC_EN 0x400
|
||||
-#define VF610_ADC_REFSEL_VALT 0x100
|
||||
+#define VF610_ADC_REFSEL_VALT 0x800
|
||||
#define VF610_ADC_REFSEL_VBG 0x1000
|
||||
#define VF610_ADC_ADTRG_HARD 0x2000
|
||||
#define VF610_ADC_AVGS_8 0x4000
|
||||
diff --git a/drivers/iio/light/tsl2563.c b/drivers/iio/light/tsl2563.c
|
||||
index 12731d6b89ec..ec1b2e798cc1 100644
|
||||
--- a/drivers/iio/light/tsl2563.c
|
||||
+++ b/drivers/iio/light/tsl2563.c
|
||||
@@ -626,7 +626,7 @@ static irqreturn_t tsl2563_event_handler(int irq, void *private)
|
||||
struct tsl2563_chip *chip = iio_priv(dev_info);
|
||||
|
||||
iio_push_event(dev_info,
|
||||
- IIO_UNMOD_EVENT_CODE(IIO_LIGHT,
|
||||
+ IIO_UNMOD_EVENT_CODE(IIO_INTENSITY,
|
||||
0,
|
||||
IIO_EV_TYPE_THRESH,
|
||||
IIO_EV_DIR_EITHER),
|
||||
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c
|
||||
index 71ccf6a90b22..2551e4adb33f 100644
|
||||
--- a/drivers/pinctrl/samsung/pinctrl-exynos.c
|
||||
+++ b/drivers/pinctrl/samsung/pinctrl-exynos.c
|
||||
@@ -194,8 +194,6 @@ static int exynos_irq_request_resources(struct irq_data *irqd)
|
||||
|
||||
spin_unlock_irqrestore(&bank->slock, flags);
|
||||
|
||||
- exynos_irq_unmask(irqd);
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -216,8 +214,6 @@ static void exynos_irq_release_resources(struct irq_data *irqd)
|
||||
shift = irqd->hwirq * bank_type->fld_width[PINCFG_TYPE_FUNC];
|
||||
mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
|
||||
|
||||
- exynos_irq_mask(irqd);
|
||||
-
|
||||
spin_lock_irqsave(&bank->slock, flags);
|
||||
|
||||
con = readl(d->virt_base + reg_con);
|
||||
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
|
||||
index 862a096c5dba..be5c71df148d 100644
|
||||
--- a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
|
||||
+++ b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
|
||||
@@ -811,6 +811,7 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = {
|
||||
SUNXI_FUNCTION(0x2, "lcd1"), /* D16 */
|
||||
SUNXI_FUNCTION(0x3, "pata"), /* ATAD12 */
|
||||
SUNXI_FUNCTION(0x4, "keypad"), /* IN6 */
|
||||
+ SUNXI_FUNCTION(0x5, "sim"), /* DET */
|
||||
SUNXI_FUNCTION_IRQ(0x6, 16), /* EINT16 */
|
||||
SUNXI_FUNCTION(0x7, "csi1")), /* D16 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 17),
|
||||
diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
|
||||
index d97aa2827412..8eb7179da342 100644
|
||||
--- a/drivers/staging/iio/resolver/ad2s1210.c
|
||||
+++ b/drivers/staging/iio/resolver/ad2s1210.c
|
||||
@@ -468,7 +468,7 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev,
|
||||
long m)
|
||||
{
|
||||
struct ad2s1210_state *st = iio_priv(indio_dev);
|
||||
- bool negative;
|
||||
+ u16 negative;
|
||||
int ret = 0;
|
||||
u16 pos;
|
||||
s16 vel;
|
||||
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
|
||||
index 31d5d9c0e10b..1ff1c83e2df5 100644
|
||||
--- a/drivers/target/iscsi/iscsi_target.c
|
||||
+++ b/drivers/target/iscsi/iscsi_target.c
|
||||
@@ -418,6 +418,7 @@ int iscsit_reset_np_thread(
|
||||
return 0;
|
||||
}
|
||||
np->np_thread_state = ISCSI_NP_THREAD_RESET;
|
||||
+ atomic_inc(&np->np_reset_count);
|
||||
|
||||
if (np->np_thread) {
|
||||
spin_unlock_bh(&np->np_thread_lock);
|
||||
@@ -1996,6 +1997,7 @@ iscsit_setup_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
|
||||
cmd->cmd_sn = be32_to_cpu(hdr->cmdsn);
|
||||
cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn);
|
||||
cmd->data_direction = DMA_NONE;
|
||||
+ kfree(cmd->text_in_ptr);
|
||||
cmd->text_in_ptr = NULL;
|
||||
|
||||
return 0;
|
||||
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
|
||||
index b19edffa7d98..bc2cbffec27e 100644
|
||||
--- a/drivers/target/iscsi/iscsi_target_login.c
|
||||
+++ b/drivers/target/iscsi/iscsi_target_login.c
|
||||
@@ -1219,9 +1219,11 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
|
||||
flush_signals(current);
|
||||
|
||||
spin_lock_bh(&np->np_thread_lock);
|
||||
- if (np->np_thread_state == ISCSI_NP_THREAD_RESET) {
|
||||
+ if (atomic_dec_if_positive(&np->np_reset_count) >= 0) {
|
||||
np->np_thread_state = ISCSI_NP_THREAD_ACTIVE;
|
||||
+ spin_unlock_bh(&np->np_thread_lock);
|
||||
complete(&np->np_restart_comp);
|
||||
+ return 1;
|
||||
} else if (np->np_thread_state == ISCSI_NP_THREAD_SHUTDOWN) {
|
||||
spin_unlock_bh(&np->np_thread_lock);
|
||||
goto exit;
|
||||
@@ -1254,7 +1256,8 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
|
||||
goto exit;
|
||||
} else if (rc < 0) {
|
||||
spin_lock_bh(&np->np_thread_lock);
|
||||
- if (np->np_thread_state == ISCSI_NP_THREAD_RESET) {
|
||||
+ if (atomic_dec_if_positive(&np->np_reset_count) >= 0) {
|
||||
+ np->np_thread_state = ISCSI_NP_THREAD_ACTIVE;
|
||||
spin_unlock_bh(&np->np_thread_lock);
|
||||
complete(&np->np_restart_comp);
|
||||
iscsit_put_transport(conn->conn_transport);
|
||||
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
|
||||
index b403596818db..5c0952995280 100644
|
||||
--- a/drivers/usb/core/hcd.c
|
||||
+++ b/drivers/usb/core/hcd.c
|
||||
@@ -1851,7 +1851,7 @@ void usb_hcd_flush_endpoint(struct usb_device *udev,
|
||||
/* No more submits can occur */
|
||||
spin_lock_irq(&hcd_urb_list_lock);
|
||||
rescan:
|
||||
- list_for_each_entry (urb, &ep->urb_list, urb_list) {
|
||||
+ list_for_each_entry_reverse(urb, &ep->urb_list, urb_list) {
|
||||
int is_in;
|
||||
|
||||
if (urb->unlinked)
|
||||
@@ -2448,6 +2448,8 @@ void usb_hc_died (struct usb_hcd *hcd)
|
||||
}
|
||||
if (usb_hcd_is_primary_hcd(hcd) && hcd->shared_hcd) {
|
||||
hcd = hcd->shared_hcd;
|
||||
+ clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);
|
||||
+ set_bit(HCD_FLAG_DEAD, &hcd->flags);
|
||||
if (hcd->rh_registered) {
|
||||
clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
|
||||
|
||||
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
|
||||
index 1d59d489a1ad..cdf4be3939f5 100644
|
||||
--- a/drivers/usb/core/hub.c
|
||||
+++ b/drivers/usb/core/hub.c
|
||||
@@ -4661,7 +4661,8 @@ hub_power_remaining(struct usb_hub *hub)
|
||||
static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
|
||||
u16 portchange)
|
||||
{
|
||||
- int status, i;
|
||||
+ int status = -ENODEV;
|
||||
+ int i;
|
||||
unsigned unit_load;
|
||||
struct usb_device *hdev = hub->hdev;
|
||||
struct usb_hcd *hcd = bus_to_hcd(hdev->bus);
|
||||
@@ -4865,9 +4866,10 @@ loop:
|
||||
|
||||
done:
|
||||
hub_port_disable(hub, port1, 1);
|
||||
- if (hcd->driver->relinquish_port && !hub->hdev->parent)
|
||||
- hcd->driver->relinquish_port(hcd, port1);
|
||||
-
|
||||
+ if (hcd->driver->relinquish_port && !hub->hdev->parent) {
|
||||
+ if (status != -ENOTCONN && status != -ENODEV)
|
||||
+ hcd->driver->relinquish_port(hcd, port1);
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Handle physical or logical connection change events.
|
||||
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
|
||||
index 3116edfcdc18..574da2b4529c 100644
|
||||
--- a/drivers/usb/core/quirks.c
|
||||
+++ b/drivers/usb/core/quirks.c
|
||||
@@ -150,6 +150,9 @@ static const struct usb_device_id usb_quirk_list[] = {
|
||||
/* appletouch */
|
||||
{ USB_DEVICE(0x05ac, 0x021a), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
+ /* Genesys Logic hub, internally used by Moshi USB to Ethernet Adapter */
|
||||
+ { USB_DEVICE(0x05e3, 0x0616), .driver_info = USB_QUIRK_NO_LPM },
|
||||
+
|
||||
/* Avision AV600U */
|
||||
{ USB_DEVICE(0x0638, 0x0a13), .driver_info =
|
||||
USB_QUIRK_STRING_FETCH_255 },
|
||||
@@ -249,6 +252,7 @@ static const struct usb_device_id usb_amd_resume_quirk_list[] = {
|
||||
{ USB_DEVICE(0x093a, 0x2500), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
{ USB_DEVICE(0x093a, 0x2510), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
{ USB_DEVICE(0x093a, 0x2521), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
+ { USB_DEVICE(0x03f0, 0x2b4a), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Optical Mouse M90/M100 */
|
||||
{ USB_DEVICE(0x046d, 0xc05a), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
|
||||
index f9400564cb72..03b9a372636f 100644
|
||||
--- a/drivers/usb/host/pci-quirks.c
|
||||
+++ b/drivers/usb/host/pci-quirks.c
|
||||
@@ -89,6 +89,7 @@ enum amd_chipset_gen {
|
||||
AMD_CHIPSET_HUDSON2,
|
||||
AMD_CHIPSET_BOLTON,
|
||||
AMD_CHIPSET_YANGTZE,
|
||||
+ AMD_CHIPSET_TAISHAN,
|
||||
AMD_CHIPSET_UNKNOWN,
|
||||
};
|
||||
|
||||
@@ -132,6 +133,11 @@ static int amd_chipset_sb_type_init(struct amd_chipset_info *pinfo)
|
||||
pinfo->sb_type.gen = AMD_CHIPSET_SB700;
|
||||
else if (rev >= 0x40 && rev <= 0x4f)
|
||||
pinfo->sb_type.gen = AMD_CHIPSET_SB800;
|
||||
+ }
|
||||
+ pinfo->smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD,
|
||||
+ 0x145c, NULL);
|
||||
+ if (pinfo->smbus_dev) {
|
||||
+ pinfo->sb_type.gen = AMD_CHIPSET_TAISHAN;
|
||||
} else {
|
||||
pinfo->smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD,
|
||||
PCI_DEVICE_ID_AMD_HUDSON2_SMBUS, NULL);
|
||||
@@ -251,11 +257,12 @@ int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *pdev)
|
||||
{
|
||||
/* Make sure amd chipset type has already been initialized */
|
||||
usb_amd_find_chipset_info();
|
||||
- if (amd_chipset.sb_type.gen != AMD_CHIPSET_YANGTZE)
|
||||
- return 0;
|
||||
-
|
||||
- dev_dbg(&pdev->dev, "QUIRK: Enable AMD remote wakeup fix\n");
|
||||
- return 1;
|
||||
+ if (amd_chipset.sb_type.gen == AMD_CHIPSET_YANGTZE ||
|
||||
+ amd_chipset.sb_type.gen == AMD_CHIPSET_TAISHAN) {
|
||||
+ dev_dbg(&pdev->dev, "QUIRK: Enable AMD remote wakeup fix\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_hcd_amd_remote_wakeup_quirk);
|
||||
|
||||
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
|
||||
index 13d5614f37f1..0d843e0f8055 100644
|
||||
--- a/drivers/usb/musb/musb_host.c
|
||||
+++ b/drivers/usb/musb/musb_host.c
|
||||
@@ -138,6 +138,7 @@ static void musb_h_tx_flush_fifo(struct musb_hw_ep *ep)
|
||||
"Could not flush host TX%d fifo: csr: %04x\n",
|
||||
ep->epnum, csr))
|
||||
return;
|
||||
+ mdelay(1);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
|
||||
index b0dc6da3d970..41a6513646de 100644
|
||||
--- a/drivers/usb/serial/cp210x.c
|
||||
+++ b/drivers/usb/serial/cp210x.c
|
||||
@@ -135,6 +135,7 @@ static const struct usb_device_id id_table[] = {
|
||||
{ USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */
|
||||
{ USB_DEVICE(0x10C4, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */
|
||||
{ USB_DEVICE(0x10C4, 0x8A5E) }, /* CEL EM3588 ZigBee USB Stick Long Range */
|
||||
+ { USB_DEVICE(0x10C4, 0x8B34) }, /* Qivicon ZigBee USB Radio Stick */
|
||||
{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
|
||||
{ USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
|
||||
{ USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */
|
||||
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
|
||||
index ebe51f11105d..fe123153b1a5 100644
|
||||
--- a/drivers/usb/serial/option.c
|
||||
+++ b/drivers/usb/serial/option.c
|
||||
@@ -2025,6 +2025,8 @@ static const struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d04, 0xff) }, /* D-Link DWM-158 */
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e19, 0xff), /* D-Link DWM-221 B1 */
|
||||
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
||||
+ { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e35, 0xff), /* D-Link DWM-222 */
|
||||
+ .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x7e11, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/A3 */
|
||||
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
|
||||
index 1db4b61bdf7b..a51b28379850 100644
|
||||
--- a/drivers/usb/serial/pl2303.c
|
||||
+++ b/drivers/usb/serial/pl2303.c
|
||||
@@ -49,6 +49,7 @@ static const struct usb_device_id id_table[] = {
|
||||
{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) },
|
||||
{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) },
|
||||
{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) },
|
||||
+ { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_UC485) },
|
||||
{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID2) },
|
||||
{ USB_DEVICE(ATEN_VENDOR_ID2, ATEN_PRODUCT_ID) },
|
||||
{ USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID) },
|
||||
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
|
||||
index 09d9be88209e..3b5a15d1dc0d 100644
|
||||
--- a/drivers/usb/serial/pl2303.h
|
||||
+++ b/drivers/usb/serial/pl2303.h
|
||||
@@ -27,6 +27,7 @@
|
||||
#define ATEN_VENDOR_ID 0x0557
|
||||
#define ATEN_VENDOR_ID2 0x0547
|
||||
#define ATEN_PRODUCT_ID 0x2008
|
||||
+#define ATEN_PRODUCT_UC485 0x2021
|
||||
#define ATEN_PRODUCT_ID2 0x2118
|
||||
|
||||
#define IODATA_VENDOR_ID 0x04bb
|
||||
diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h
|
||||
index 53341a77d89f..a37ed1e59e99 100644
|
||||
--- a/drivers/usb/storage/unusual_uas.h
|
||||
+++ b/drivers/usb/storage/unusual_uas.h
|
||||
@@ -123,9 +123,9 @@ UNUSUAL_DEV(0x0bc2, 0xab2a, 0x0000, 0x9999,
|
||||
/* Reported-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> */
|
||||
UNUSUAL_DEV(0x13fd, 0x3940, 0x0000, 0x9999,
|
||||
"Initio Corporation",
|
||||
- "",
|
||||
+ "INIC-3069",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||
- US_FL_NO_ATA_1X),
|
||||
+ US_FL_NO_ATA_1X | US_FL_IGNORE_RESIDUE),
|
||||
|
||||
/* Reported-by: Tom Arild Naess <tanaess@gmail.com> */
|
||||
UNUSUAL_DEV(0x152d, 0x0539, 0x0000, 0x9999,
|
||||
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
|
||||
index 11538a8be9f0..1a063cbfe503 100644
|
||||
--- a/fs/fuse/file.c
|
||||
+++ b/fs/fuse/file.c
|
||||
@@ -46,7 +46,7 @@ struct fuse_file *fuse_file_alloc(struct fuse_conn *fc)
|
||||
{
|
||||
struct fuse_file *ff;
|
||||
|
||||
- ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL);
|
||||
+ ff = kzalloc(sizeof(struct fuse_file), GFP_KERNEL);
|
||||
if (unlikely(!ff))
|
||||
return NULL;
|
||||
|
||||
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
|
||||
index f31fd0dd92c6..b1daeafbea92 100644
|
||||
--- a/fs/nfs/Kconfig
|
||||
+++ b/fs/nfs/Kconfig
|
||||
@@ -121,6 +121,7 @@ config PNFS_FILE_LAYOUT
|
||||
config PNFS_BLOCK
|
||||
tristate
|
||||
depends on NFS_V4_1 && BLK_DEV_DM
|
||||
+ depends on 64BIT || LBDAF
|
||||
default NFS_V4
|
||||
|
||||
config PNFS_OBJLAYOUT
|
||||
diff --git a/fs/nfs/flexfilelayout/flexfilelayoutdev.c b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
|
||||
index e125e55de86d..2603d7589946 100644
|
||||
--- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c
|
||||
+++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
|
||||
@@ -30,6 +30,7 @@ void nfs4_ff_layout_free_deviceid(struct nfs4_ff_layout_ds *mirror_ds)
|
||||
{
|
||||
nfs4_print_deviceid(&mirror_ds->id_node.deviceid);
|
||||
nfs4_pnfs_ds_put(mirror_ds->ds);
|
||||
+ kfree(mirror_ds->ds_versions);
|
||||
kfree_rcu(mirror_ds, id_node.rcu);
|
||||
}
|
||||
|
||||
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
|
||||
index 85a868ccb493..8397dc235e84 100644
|
||||
--- a/include/linux/cpuset.h
|
||||
+++ b/include/linux/cpuset.h
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#ifdef CONFIG_CPUSETS
|
||||
|
||||
+extern struct static_key cpusets_pre_enable_key;
|
||||
extern struct static_key cpusets_enabled_key;
|
||||
static inline bool cpusets_enabled(void)
|
||||
{
|
||||
@@ -30,12 +31,14 @@ static inline int nr_cpusets(void)
|
||||
|
||||
static inline void cpuset_inc(void)
|
||||
{
|
||||
+ static_key_slow_inc(&cpusets_pre_enable_key);
|
||||
static_key_slow_inc(&cpusets_enabled_key);
|
||||
}
|
||||
|
||||
static inline void cpuset_dec(void)
|
||||
{
|
||||
static_key_slow_dec(&cpusets_enabled_key);
|
||||
+ static_key_slow_dec(&cpusets_pre_enable_key);
|
||||
}
|
||||
|
||||
extern int cpuset_init(void);
|
||||
@@ -104,7 +107,7 @@ extern void cpuset_print_current_mems_allowed(void);
|
||||
*/
|
||||
static inline unsigned int read_mems_allowed_begin(void)
|
||||
{
|
||||
- if (!cpusets_enabled())
|
||||
+ if (!static_key_false(&cpusets_pre_enable_key))
|
||||
return 0;
|
||||
|
||||
return read_seqcount_begin(¤t->mems_allowed_seq);
|
||||
@@ -118,7 +121,7 @@ static inline unsigned int read_mems_allowed_begin(void)
|
||||
*/
|
||||
static inline bool read_mems_allowed_retry(unsigned int seq)
|
||||
{
|
||||
- if (!cpusets_enabled())
|
||||
+ if (!static_key_false(&cpusets_enabled_key))
|
||||
return false;
|
||||
|
||||
return read_seqcount_retry(¤t->mems_allowed_seq, seq);
|
||||
diff --git a/include/target/iscsi/iscsi_target_core.h b/include/target/iscsi/iscsi_target_core.h
|
||||
index fdda45f26f75..22f442ab85f9 100644
|
||||
--- a/include/target/iscsi/iscsi_target_core.h
|
||||
+++ b/include/target/iscsi/iscsi_target_core.h
|
||||
@@ -784,6 +784,7 @@ struct iscsi_np {
|
||||
int np_sock_type;
|
||||
enum np_thread_state_table np_thread_state;
|
||||
bool enabled;
|
||||
+ atomic_t np_reset_count;
|
||||
enum iscsi_timer_flags_table np_login_timer_flags;
|
||||
u32 np_exports;
|
||||
enum np_flags_table np_flags;
|
||||
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
|
||||
index 3b5e5430f5d0..8ccd66a97c8b 100644
|
||||
--- a/kernel/cpuset.c
|
||||
+++ b/kernel/cpuset.c
|
||||
@@ -60,6 +60,7 @@
|
||||
#include <linux/cgroup.h>
|
||||
#include <linux/wait.h>
|
||||
|
||||
+struct static_key cpusets_pre_enable_key __read_mostly = STATIC_KEY_INIT_FALSE;
|
||||
struct static_key cpusets_enabled_key __read_mostly = STATIC_KEY_INIT_FALSE;
|
||||
|
||||
/* See "Frequency meter" comments, below. */
|
||||
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
|
||||
index f9d648fce8cd..53286b2f5b1c 100644
|
||||
--- a/mm/page_alloc.c
|
||||
+++ b/mm/page_alloc.c
|
||||
@@ -6804,7 +6804,7 @@ int alloc_contig_range(unsigned long start, unsigned long end,
|
||||
|
||||
/* Make sure the range is really isolated. */
|
||||
if (test_pages_isolated(outer_start, end, false)) {
|
||||
- pr_info("%s: [%lx, %lx) PFNs busy\n",
|
||||
+ pr_info_ratelimited("%s: [%lx, %lx) PFNs busy\n",
|
||||
__func__, outer_start, end);
|
||||
ret = -EBUSY;
|
||||
goto done;
|
||||
761
patch/kernel/s5p6818-default/03-patch-4.4.83-84.patch
Normal file
761
patch/kernel/s5p6818-default/03-patch-4.4.83-84.patch
Normal file
@ -0,0 +1,761 @@
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 7f67b35caf99..9d77ac063ec0 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 4
|
||||
-SUBLEVEL = 83
|
||||
+SUBLEVEL = 84
|
||||
EXTRAVERSION =
|
||||
NAME = Blurry Fish Butt
|
||||
|
||||
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
|
||||
index 9e11dbe1cec3..329c127e13dc 100644
|
||||
--- a/arch/arm64/include/asm/elf.h
|
||||
+++ b/arch/arm64/include/asm/elf.h
|
||||
@@ -121,10 +121,10 @@ typedef struct user_fpsimd_state elf_fpregset_t;
|
||||
|
||||
/*
|
||||
* This is the base location for PIE (ET_DYN with INTERP) loads. On
|
||||
- * 64-bit, this is raised to 4GB to leave the entire 32-bit address
|
||||
+ * 64-bit, this is above 4GB to leave the entire 32-bit address
|
||||
* space open for things that want to use the area for 32-bit pointers.
|
||||
*/
|
||||
-#define ELF_ET_DYN_BASE 0x100000000UL
|
||||
+#define ELF_ET_DYN_BASE (2 * TASK_SIZE_64 / 3)
|
||||
|
||||
/*
|
||||
* When the program starts, a1 contains a pointer to a function to be
|
||||
diff --git a/arch/x86/crypto/sha1_avx2_x86_64_asm.S b/arch/x86/crypto/sha1_avx2_x86_64_asm.S
|
||||
index 1cd792db15ef..1eab79c9ac48 100644
|
||||
--- a/arch/x86/crypto/sha1_avx2_x86_64_asm.S
|
||||
+++ b/arch/x86/crypto/sha1_avx2_x86_64_asm.S
|
||||
@@ -117,11 +117,10 @@
|
||||
.set T1, REG_T1
|
||||
.endm
|
||||
|
||||
-#define K_BASE %r8
|
||||
#define HASH_PTR %r9
|
||||
+#define BLOCKS_CTR %r8
|
||||
#define BUFFER_PTR %r10
|
||||
#define BUFFER_PTR2 %r13
|
||||
-#define BUFFER_END %r11
|
||||
|
||||
#define PRECALC_BUF %r14
|
||||
#define WK_BUF %r15
|
||||
@@ -205,14 +204,14 @@
|
||||
* blended AVX2 and ALU instruction scheduling
|
||||
* 1 vector iteration per 8 rounds
|
||||
*/
|
||||
- vmovdqu ((i * 2) + PRECALC_OFFSET)(BUFFER_PTR), W_TMP
|
||||
+ vmovdqu (i * 2)(BUFFER_PTR), W_TMP
|
||||
.elseif ((i & 7) == 1)
|
||||
- vinsertf128 $1, (((i-1) * 2)+PRECALC_OFFSET)(BUFFER_PTR2),\
|
||||
+ vinsertf128 $1, ((i-1) * 2)(BUFFER_PTR2),\
|
||||
WY_TMP, WY_TMP
|
||||
.elseif ((i & 7) == 2)
|
||||
vpshufb YMM_SHUFB_BSWAP, WY_TMP, WY
|
||||
.elseif ((i & 7) == 4)
|
||||
- vpaddd K_XMM(K_BASE), WY, WY_TMP
|
||||
+ vpaddd K_XMM + K_XMM_AR(%rip), WY, WY_TMP
|
||||
.elseif ((i & 7) == 7)
|
||||
vmovdqu WY_TMP, PRECALC_WK(i&~7)
|
||||
|
||||
@@ -255,7 +254,7 @@
|
||||
vpxor WY, WY_TMP, WY_TMP
|
||||
.elseif ((i & 7) == 7)
|
||||
vpxor WY_TMP2, WY_TMP, WY
|
||||
- vpaddd K_XMM(K_BASE), WY, WY_TMP
|
||||
+ vpaddd K_XMM + K_XMM_AR(%rip), WY, WY_TMP
|
||||
vmovdqu WY_TMP, PRECALC_WK(i&~7)
|
||||
|
||||
PRECALC_ROTATE_WY
|
||||
@@ -291,7 +290,7 @@
|
||||
vpsrld $30, WY, WY
|
||||
vpor WY, WY_TMP, WY
|
||||
.elseif ((i & 7) == 7)
|
||||
- vpaddd K_XMM(K_BASE), WY, WY_TMP
|
||||
+ vpaddd K_XMM + K_XMM_AR(%rip), WY, WY_TMP
|
||||
vmovdqu WY_TMP, PRECALC_WK(i&~7)
|
||||
|
||||
PRECALC_ROTATE_WY
|
||||
@@ -446,6 +445,16 @@
|
||||
|
||||
.endm
|
||||
|
||||
+/* Add constant only if (%2 > %3) condition met (uses RTA as temp)
|
||||
+ * %1 + %2 >= %3 ? %4 : 0
|
||||
+ */
|
||||
+.macro ADD_IF_GE a, b, c, d
|
||||
+ mov \a, RTA
|
||||
+ add $\d, RTA
|
||||
+ cmp $\c, \b
|
||||
+ cmovge RTA, \a
|
||||
+.endm
|
||||
+
|
||||
/*
|
||||
* macro implements 80 rounds of SHA-1, for multiple blocks with s/w pipelining
|
||||
*/
|
||||
@@ -463,13 +472,16 @@
|
||||
lea (2*4*80+32)(%rsp), WK_BUF
|
||||
|
||||
# Precalc WK for first 2 blocks
|
||||
- PRECALC_OFFSET = 0
|
||||
+ ADD_IF_GE BUFFER_PTR2, BLOCKS_CTR, 2, 64
|
||||
.set i, 0
|
||||
.rept 160
|
||||
PRECALC i
|
||||
.set i, i + 1
|
||||
.endr
|
||||
- PRECALC_OFFSET = 128
|
||||
+
|
||||
+ /* Go to next block if needed */
|
||||
+ ADD_IF_GE BUFFER_PTR, BLOCKS_CTR, 3, 128
|
||||
+ ADD_IF_GE BUFFER_PTR2, BLOCKS_CTR, 4, 128
|
||||
xchg WK_BUF, PRECALC_BUF
|
||||
|
||||
.align 32
|
||||
@@ -479,8 +491,8 @@ _loop:
|
||||
* we use K_BASE value as a signal of a last block,
|
||||
* it is set below by: cmovae BUFFER_PTR, K_BASE
|
||||
*/
|
||||
- cmp K_BASE, BUFFER_PTR
|
||||
- jne _begin
|
||||
+ test BLOCKS_CTR, BLOCKS_CTR
|
||||
+ jnz _begin
|
||||
.align 32
|
||||
jmp _end
|
||||
.align 32
|
||||
@@ -512,10 +524,10 @@ _loop0:
|
||||
.set j, j+2
|
||||
.endr
|
||||
|
||||
- add $(2*64), BUFFER_PTR /* move to next odd-64-byte block */
|
||||
- cmp BUFFER_END, BUFFER_PTR /* is current block the last one? */
|
||||
- cmovae K_BASE, BUFFER_PTR /* signal the last iteration smartly */
|
||||
-
|
||||
+ /* Update Counter */
|
||||
+ sub $1, BLOCKS_CTR
|
||||
+ /* Move to the next block only if needed*/
|
||||
+ ADD_IF_GE BUFFER_PTR, BLOCKS_CTR, 4, 128
|
||||
/*
|
||||
* rounds
|
||||
* 60,62,64,66,68
|
||||
@@ -532,8 +544,8 @@ _loop0:
|
||||
UPDATE_HASH 12(HASH_PTR), D
|
||||
UPDATE_HASH 16(HASH_PTR), E
|
||||
|
||||
- cmp K_BASE, BUFFER_PTR /* is current block the last one? */
|
||||
- je _loop
|
||||
+ test BLOCKS_CTR, BLOCKS_CTR
|
||||
+ jz _loop
|
||||
|
||||
mov TB, B
|
||||
|
||||
@@ -575,10 +587,10 @@ _loop2:
|
||||
.set j, j+2
|
||||
.endr
|
||||
|
||||
- add $(2*64), BUFFER_PTR2 /* move to next even-64-byte block */
|
||||
-
|
||||
- cmp BUFFER_END, BUFFER_PTR2 /* is current block the last one */
|
||||
- cmovae K_BASE, BUFFER_PTR /* signal the last iteration smartly */
|
||||
+ /* update counter */
|
||||
+ sub $1, BLOCKS_CTR
|
||||
+ /* Move to the next block only if needed*/
|
||||
+ ADD_IF_GE BUFFER_PTR2, BLOCKS_CTR, 4, 128
|
||||
|
||||
jmp _loop3
|
||||
_loop3:
|
||||
@@ -641,19 +653,12 @@ _loop3:
|
||||
|
||||
avx2_zeroupper
|
||||
|
||||
- lea K_XMM_AR(%rip), K_BASE
|
||||
-
|
||||
+ /* Setup initial values */
|
||||
mov CTX, HASH_PTR
|
||||
mov BUF, BUFFER_PTR
|
||||
- lea 64(BUF), BUFFER_PTR2
|
||||
-
|
||||
- shl $6, CNT /* mul by 64 */
|
||||
- add BUF, CNT
|
||||
- add $64, CNT
|
||||
- mov CNT, BUFFER_END
|
||||
|
||||
- cmp BUFFER_END, BUFFER_PTR2
|
||||
- cmovae K_BASE, BUFFER_PTR2
|
||||
+ mov BUF, BUFFER_PTR2
|
||||
+ mov CNT, BLOCKS_CTR
|
||||
|
||||
xmm_mov BSWAP_SHUFB_CTL(%rip), YMM_SHUFB_BSWAP
|
||||
|
||||
diff --git a/arch/x86/crypto/sha1_ssse3_glue.c b/arch/x86/crypto/sha1_ssse3_glue.c
|
||||
index 7de207a11014..dd14616b7739 100644
|
||||
--- a/arch/x86/crypto/sha1_ssse3_glue.c
|
||||
+++ b/arch/x86/crypto/sha1_ssse3_glue.c
|
||||
@@ -201,7 +201,7 @@ asmlinkage void sha1_transform_avx2(u32 *digest, const char *data,
|
||||
|
||||
static bool avx2_usable(void)
|
||||
{
|
||||
- if (false && avx_usable() && boot_cpu_has(X86_FEATURE_AVX2)
|
||||
+ if (avx_usable() && boot_cpu_has(X86_FEATURE_AVX2)
|
||||
&& boot_cpu_has(X86_FEATURE_BMI1)
|
||||
&& boot_cpu_has(X86_FEATURE_BMI2))
|
||||
return true;
|
||||
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
|
||||
index a55697d19824..cc0f2f5da19b 100644
|
||||
--- a/arch/x86/entry/entry_64.S
|
||||
+++ b/arch/x86/entry/entry_64.S
|
||||
@@ -1190,6 +1190,8 @@ ENTRY(nmi)
|
||||
* other IST entries.
|
||||
*/
|
||||
|
||||
+ ASM_CLAC
|
||||
+
|
||||
/* Use %rdx as our temp variable throughout */
|
||||
pushq %rdx
|
||||
|
||||
diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
|
||||
index 07cf288b692e..bcd3d6199464 100644
|
||||
--- a/arch/x86/include/asm/elf.h
|
||||
+++ b/arch/x86/include/asm/elf.h
|
||||
@@ -247,11 +247,11 @@ extern int force_personality32;
|
||||
|
||||
/*
|
||||
* This is the base location for PIE (ET_DYN with INTERP) loads. On
|
||||
- * 64-bit, this is raised to 4GB to leave the entire 32-bit address
|
||||
+ * 64-bit, this is above 4GB to leave the entire 32-bit address
|
||||
* space open for things that want to use the area for 32-bit pointers.
|
||||
*/
|
||||
#define ELF_ET_DYN_BASE (mmap_is_ia32() ? 0x000400000UL : \
|
||||
- 0x100000000UL)
|
||||
+ (TASK_SIZE / 3 * 2))
|
||||
|
||||
/* This yields a mask that user programs can use to figure out what
|
||||
instruction set this CPU supports. This could be done in user space,
|
||||
diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
|
||||
index 8900400230c6..2cdae69d7e0b 100644
|
||||
--- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c
|
||||
+++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
|
||||
@@ -153,7 +153,7 @@ static void __intel_pmu_lbr_enable(bool pmi)
|
||||
*/
|
||||
if (cpuc->lbr_sel)
|
||||
lbr_select = cpuc->lbr_sel->config;
|
||||
- if (!pmi)
|
||||
+ if (!pmi && cpuc->lbr_sel)
|
||||
wrmsrl(MSR_LBR_SELECT, lbr_select);
|
||||
|
||||
rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
|
||||
@@ -432,8 +432,10 @@ static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
|
||||
int out = 0;
|
||||
int num = x86_pmu.lbr_nr;
|
||||
|
||||
- if (cpuc->lbr_sel->config & LBR_CALL_STACK)
|
||||
- num = tos;
|
||||
+ if (cpuc->lbr_sel) {
|
||||
+ if (cpuc->lbr_sel->config & LBR_CALL_STACK)
|
||||
+ num = tos;
|
||||
+ }
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
unsigned long lbr_idx = (tos - i) & mask;
|
||||
diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c
|
||||
index da5458dfb1e3..98d4e515587a 100644
|
||||
--- a/drivers/input/mouse/elan_i2c_core.c
|
||||
+++ b/drivers/input/mouse/elan_i2c_core.c
|
||||
@@ -1235,6 +1235,10 @@ static const struct acpi_device_id elan_acpi_id[] = {
|
||||
{ "ELAN0100", 0 },
|
||||
{ "ELAN0600", 0 },
|
||||
{ "ELAN0605", 0 },
|
||||
+ { "ELAN0608", 0 },
|
||||
+ { "ELAN0605", 0 },
|
||||
+ { "ELAN0609", 0 },
|
||||
+ { "ELAN060B", 0 },
|
||||
{ "ELAN1000", 0 },
|
||||
{ }
|
||||
};
|
||||
diff --git a/drivers/irqchip/irq-atmel-aic-common.c b/drivers/irqchip/irq-atmel-aic-common.c
|
||||
index 37199b9b2cfa..831a195cb806 100644
|
||||
--- a/drivers/irqchip/irq-atmel-aic-common.c
|
||||
+++ b/drivers/irqchip/irq-atmel-aic-common.c
|
||||
@@ -148,9 +148,9 @@ void __init aic_common_rtc_irq_fixup(struct device_node *root)
|
||||
struct device_node *np;
|
||||
void __iomem *regs;
|
||||
|
||||
- np = of_find_compatible_node(root, NULL, "atmel,at91rm9200-rtc");
|
||||
+ np = of_find_compatible_node(NULL, NULL, "atmel,at91rm9200-rtc");
|
||||
if (!np)
|
||||
- np = of_find_compatible_node(root, NULL,
|
||||
+ np = of_find_compatible_node(NULL, NULL,
|
||||
"atmel,at91sam9x5-rtc");
|
||||
|
||||
if (!np)
|
||||
@@ -202,7 +202,6 @@ void __init aic_common_irq_fixup(const struct of_device_id *matches)
|
||||
return;
|
||||
|
||||
match = of_match_node(matches, root);
|
||||
- of_node_put(root);
|
||||
|
||||
if (match) {
|
||||
void (*fixup)(struct device_node *) = match->data;
|
||||
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
|
||||
index 582d8f0c6266..958af3b1af7f 100644
|
||||
--- a/drivers/net/usb/qmi_wwan.c
|
||||
+++ b/drivers/net/usb/qmi_wwan.c
|
||||
@@ -707,6 +707,7 @@ static const struct usb_device_id products[] = {
|
||||
{QMI_FIXED_INTF(0x19d2, 0x1428, 2)}, /* Telewell TW-LTE 4G v2 */
|
||||
{QMI_FIXED_INTF(0x19d2, 0x2002, 4)}, /* ZTE (Vodafone) K3765-Z */
|
||||
{QMI_FIXED_INTF(0x2001, 0x7e19, 4)}, /* D-Link DWM-221 B1 */
|
||||
+ {QMI_FIXED_INTF(0x2001, 0x7e35, 4)}, /* D-Link DWM-222 */
|
||||
{QMI_FIXED_INTF(0x0f3d, 0x68a2, 8)}, /* Sierra Wireless MC7700 */
|
||||
{QMI_FIXED_INTF(0x114f, 0x68a2, 8)}, /* Sierra Wireless MC7750 */
|
||||
{QMI_FIXED_INTF(0x1199, 0x68a2, 8)}, /* Sierra Wireless MC7710 in QMI mode */
|
||||
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
|
||||
index 7b0ca1551d7b..005ea632ba53 100644
|
||||
--- a/drivers/parisc/dino.c
|
||||
+++ b/drivers/parisc/dino.c
|
||||
@@ -954,7 +954,7 @@ static int __init dino_probe(struct parisc_device *dev)
|
||||
|
||||
dino_dev->hba.dev = dev;
|
||||
dino_dev->hba.base_addr = ioremap_nocache(hpa, 4096);
|
||||
- dino_dev->hba.lmmio_space_offset = 0; /* CPU addrs == bus addrs */
|
||||
+ dino_dev->hba.lmmio_space_offset = PCI_F_EXTEND;
|
||||
spin_lock_init(&dino_dev->dinosaur_pen);
|
||||
dino_dev->hba.iommu = ccio_get_iommu(dev);
|
||||
|
||||
diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c
|
||||
index 2776cfe64c09..ef9cf4a21afe 100644
|
||||
--- a/drivers/usb/core/usb-acpi.c
|
||||
+++ b/drivers/usb/core/usb-acpi.c
|
||||
@@ -127,6 +127,22 @@ out:
|
||||
*/
|
||||
#define USB_ACPI_LOCATION_VALID (1 << 31)
|
||||
|
||||
+static struct acpi_device *usb_acpi_find_port(struct acpi_device *parent,
|
||||
+ int raw)
|
||||
+{
|
||||
+ struct acpi_device *adev;
|
||||
+
|
||||
+ if (!parent)
|
||||
+ return NULL;
|
||||
+
|
||||
+ list_for_each_entry(adev, &parent->children, node) {
|
||||
+ if (acpi_device_adr(adev) == raw)
|
||||
+ return adev;
|
||||
+ }
|
||||
+
|
||||
+ return acpi_find_child_device(parent, raw, false);
|
||||
+}
|
||||
+
|
||||
static struct acpi_device *usb_acpi_find_companion(struct device *dev)
|
||||
{
|
||||
struct usb_device *udev;
|
||||
@@ -174,8 +190,10 @@ static struct acpi_device *usb_acpi_find_companion(struct device *dev)
|
||||
int raw;
|
||||
|
||||
raw = usb_hcd_find_raw_port_number(hcd, port1);
|
||||
- adev = acpi_find_child_device(ACPI_COMPANION(&udev->dev),
|
||||
- raw, false);
|
||||
+
|
||||
+ adev = usb_acpi_find_port(ACPI_COMPANION(&udev->dev),
|
||||
+ raw);
|
||||
+
|
||||
if (!adev)
|
||||
return NULL;
|
||||
} else {
|
||||
@@ -186,7 +204,9 @@ static struct acpi_device *usb_acpi_find_companion(struct device *dev)
|
||||
return NULL;
|
||||
|
||||
acpi_bus_get_device(parent_handle, &adev);
|
||||
- adev = acpi_find_child_device(adev, port1, false);
|
||||
+
|
||||
+ adev = usb_acpi_find_port(adev, port1);
|
||||
+
|
||||
if (!adev)
|
||||
return NULL;
|
||||
}
|
||||
diff --git a/drivers/xen/biomerge.c b/drivers/xen/biomerge.c
|
||||
index 4da69dbf7dca..1bdd02a6d6ac 100644
|
||||
--- a/drivers/xen/biomerge.c
|
||||
+++ b/drivers/xen/biomerge.c
|
||||
@@ -10,8 +10,7 @@ bool xen_biovec_phys_mergeable(const struct bio_vec *vec1,
|
||||
unsigned long bfn1 = pfn_to_bfn(page_to_pfn(vec1->bv_page));
|
||||
unsigned long bfn2 = pfn_to_bfn(page_to_pfn(vec2->bv_page));
|
||||
|
||||
- return __BIOVEC_PHYS_MERGEABLE(vec1, vec2) &&
|
||||
- ((bfn1 == bfn2) || ((bfn1+1) == bfn2));
|
||||
+ return bfn1 + PFN_DOWN(vec1->bv_offset + vec1->bv_len) == bfn2;
|
||||
#else
|
||||
/*
|
||||
* XXX: Add support for merging bio_vec when using different page
|
||||
diff --git a/include/linux/pid.h b/include/linux/pid.h
|
||||
index 23705a53abba..97b745ddece5 100644
|
||||
--- a/include/linux/pid.h
|
||||
+++ b/include/linux/pid.h
|
||||
@@ -8,7 +8,9 @@ enum pid_type
|
||||
PIDTYPE_PID,
|
||||
PIDTYPE_PGID,
|
||||
PIDTYPE_SID,
|
||||
- PIDTYPE_MAX
|
||||
+ PIDTYPE_MAX,
|
||||
+ /* only valid to __task_pid_nr_ns() */
|
||||
+ __PIDTYPE_TGID
|
||||
};
|
||||
|
||||
/*
|
||||
diff --git a/include/linux/sched.h b/include/linux/sched.h
|
||||
index eff7c1fad26f..e887c8d6f395 100644
|
||||
--- a/include/linux/sched.h
|
||||
+++ b/include/linux/sched.h
|
||||
@@ -1949,31 +1949,8 @@ static inline pid_t task_tgid_nr(struct task_struct *tsk)
|
||||
return tsk->tgid;
|
||||
}
|
||||
|
||||
-pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns);
|
||||
-
|
||||
-static inline pid_t task_tgid_vnr(struct task_struct *tsk)
|
||||
-{
|
||||
- return pid_vnr(task_tgid(tsk));
|
||||
-}
|
||||
-
|
||||
|
||||
static inline int pid_alive(const struct task_struct *p);
|
||||
-static inline pid_t task_ppid_nr_ns(const struct task_struct *tsk, struct pid_namespace *ns)
|
||||
-{
|
||||
- pid_t pid = 0;
|
||||
-
|
||||
- rcu_read_lock();
|
||||
- if (pid_alive(tsk))
|
||||
- pid = task_tgid_nr_ns(rcu_dereference(tsk->real_parent), ns);
|
||||
- rcu_read_unlock();
|
||||
-
|
||||
- return pid;
|
||||
-}
|
||||
-
|
||||
-static inline pid_t task_ppid_nr(const struct task_struct *tsk)
|
||||
-{
|
||||
- return task_ppid_nr_ns(tsk, &init_pid_ns);
|
||||
-}
|
||||
|
||||
static inline pid_t task_pgrp_nr_ns(struct task_struct *tsk,
|
||||
struct pid_namespace *ns)
|
||||
@@ -1998,6 +1975,33 @@ static inline pid_t task_session_vnr(struct task_struct *tsk)
|
||||
return __task_pid_nr_ns(tsk, PIDTYPE_SID, NULL);
|
||||
}
|
||||
|
||||
+static inline pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
|
||||
+{
|
||||
+ return __task_pid_nr_ns(tsk, __PIDTYPE_TGID, ns);
|
||||
+}
|
||||
+
|
||||
+static inline pid_t task_tgid_vnr(struct task_struct *tsk)
|
||||
+{
|
||||
+ return __task_pid_nr_ns(tsk, __PIDTYPE_TGID, NULL);
|
||||
+}
|
||||
+
|
||||
+static inline pid_t task_ppid_nr_ns(const struct task_struct *tsk, struct pid_namespace *ns)
|
||||
+{
|
||||
+ pid_t pid = 0;
|
||||
+
|
||||
+ rcu_read_lock();
|
||||
+ if (pid_alive(tsk))
|
||||
+ pid = task_tgid_nr_ns(rcu_dereference(tsk->real_parent), ns);
|
||||
+ rcu_read_unlock();
|
||||
+
|
||||
+ return pid;
|
||||
+}
|
||||
+
|
||||
+static inline pid_t task_ppid_nr(const struct task_struct *tsk)
|
||||
+{
|
||||
+ return task_ppid_nr_ns(tsk, &init_pid_ns);
|
||||
+}
|
||||
+
|
||||
/* obsolete, do not use */
|
||||
static inline pid_t task_pgrp_nr(struct task_struct *tsk)
|
||||
{
|
||||
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c
|
||||
index 939945a5649c..a162661c9d60 100644
|
||||
--- a/kernel/audit_watch.c
|
||||
+++ b/kernel/audit_watch.c
|
||||
@@ -457,13 +457,15 @@ void audit_remove_watch_rule(struct audit_krule *krule)
|
||||
list_del(&krule->rlist);
|
||||
|
||||
if (list_empty(&watch->rules)) {
|
||||
+ /*
|
||||
+ * audit_remove_watch() drops our reference to 'parent' which
|
||||
+ * can get freed. Grab our own reference to be safe.
|
||||
+ */
|
||||
+ audit_get_parent(parent);
|
||||
audit_remove_watch(watch);
|
||||
-
|
||||
- if (list_empty(&parent->watches)) {
|
||||
- audit_get_parent(parent);
|
||||
+ if (list_empty(&parent->watches))
|
||||
fsnotify_destroy_mark(&parent->mark, audit_watch_group);
|
||||
- audit_put_parent(parent);
|
||||
- }
|
||||
+ audit_put_parent(parent);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/kernel/pid.c b/kernel/pid.c
|
||||
index 78b3d9f80d44..b17263be9082 100644
|
||||
--- a/kernel/pid.c
|
||||
+++ b/kernel/pid.c
|
||||
@@ -526,8 +526,11 @@ pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type,
|
||||
if (!ns)
|
||||
ns = task_active_pid_ns(current);
|
||||
if (likely(pid_alive(task))) {
|
||||
- if (type != PIDTYPE_PID)
|
||||
+ if (type != PIDTYPE_PID) {
|
||||
+ if (type == __PIDTYPE_TGID)
|
||||
+ type = PIDTYPE_PID;
|
||||
task = task->group_leader;
|
||||
+ }
|
||||
nr = pid_nr_ns(rcu_dereference(task->pids[type].pid), ns);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
@@ -536,12 +539,6 @@ pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type,
|
||||
}
|
||||
EXPORT_SYMBOL(__task_pid_nr_ns);
|
||||
|
||||
-pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
|
||||
-{
|
||||
- return pid_nr_ns(task_tgid(tsk), ns);
|
||||
-}
|
||||
-EXPORT_SYMBOL(task_tgid_nr_ns);
|
||||
-
|
||||
struct pid_namespace *task_active_pid_ns(struct task_struct *tsk)
|
||||
{
|
||||
return ns_of_pid(task_pid(tsk));
|
||||
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
|
||||
index e09b1a0e2cfe..c947014d128a 100644
|
||||
--- a/mm/mempolicy.c
|
||||
+++ b/mm/mempolicy.c
|
||||
@@ -894,11 +894,6 @@ static long do_get_mempolicy(int *policy, nodemask_t *nmask,
|
||||
*policy |= (pol->flags & MPOL_MODE_FLAGS);
|
||||
}
|
||||
|
||||
- if (vma) {
|
||||
- up_read(¤t->mm->mmap_sem);
|
||||
- vma = NULL;
|
||||
- }
|
||||
-
|
||||
err = 0;
|
||||
if (nmask) {
|
||||
if (mpol_store_user_nodemask(pol)) {
|
||||
diff --git a/mm/migrate.c b/mm/migrate.c
|
||||
index 72c09dea6526..afedcfab60e2 100644
|
||||
--- a/mm/migrate.c
|
||||
+++ b/mm/migrate.c
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <linux/balloon_compaction.h>
|
||||
#include <linux/mmu_notifier.h>
|
||||
#include <linux/page_idle.h>
|
||||
+#include <linux/ptrace.h>
|
||||
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
@@ -1483,7 +1484,6 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages,
|
||||
const int __user *, nodes,
|
||||
int __user *, status, int, flags)
|
||||
{
|
||||
- const struct cred *cred = current_cred(), *tcred;
|
||||
struct task_struct *task;
|
||||
struct mm_struct *mm;
|
||||
int err;
|
||||
@@ -1507,14 +1507,9 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages,
|
||||
|
||||
/*
|
||||
* Check if this process has the right to modify the specified
|
||||
- * process. The right exists if the process has administrative
|
||||
- * capabilities, superuser privileges or the same
|
||||
- * userid as the target process.
|
||||
+ * process. Use the regular "ptrace_may_access()" checks.
|
||||
*/
|
||||
- tcred = __task_cred(task);
|
||||
- if (!uid_eq(cred->euid, tcred->suid) && !uid_eq(cred->euid, tcred->uid) &&
|
||||
- !uid_eq(cred->uid, tcred->suid) && !uid_eq(cred->uid, tcred->uid) &&
|
||||
- !capable(CAP_SYS_NICE)) {
|
||||
+ if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) {
|
||||
rcu_read_unlock();
|
||||
err = -EPERM;
|
||||
goto out;
|
||||
diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c
|
||||
index 1a9545965c0d..531ca55f1af6 100644
|
||||
--- a/net/netfilter/nf_conntrack_extend.c
|
||||
+++ b/net/netfilter/nf_conntrack_extend.c
|
||||
@@ -53,7 +53,11 @@ nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id,
|
||||
|
||||
rcu_read_lock();
|
||||
t = rcu_dereference(nf_ct_ext_types[id]);
|
||||
- BUG_ON(t == NULL);
|
||||
+ if (!t) {
|
||||
+ rcu_read_unlock();
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
off = ALIGN(sizeof(struct nf_ct_ext), t->align);
|
||||
len = off + t->len + var_alloc_len;
|
||||
alloc_size = t->alloc_size + var_alloc_len;
|
||||
@@ -88,7 +92,10 @@ void *__nf_ct_ext_add_length(struct nf_conn *ct, enum nf_ct_ext_id id,
|
||||
|
||||
rcu_read_lock();
|
||||
t = rcu_dereference(nf_ct_ext_types[id]);
|
||||
- BUG_ON(t == NULL);
|
||||
+ if (!t) {
|
||||
+ rcu_read_unlock();
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
||||
newoff = ALIGN(old->len, t->align);
|
||||
newlen = newoff + t->len + var_alloc_len;
|
||||
@@ -186,6 +193,6 @@ void nf_ct_extend_unregister(struct nf_ct_ext_type *type)
|
||||
RCU_INIT_POINTER(nf_ct_ext_types[type->id], NULL);
|
||||
update_alloc_size(type);
|
||||
mutex_unlock(&nf_ct_ext_type_mutex);
|
||||
- rcu_barrier(); /* Wait for completion of call_rcu()'s */
|
||||
+ synchronize_rcu();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_ct_extend_unregister);
|
||||
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
|
||||
index c67f9c212dd1..e326c1d80416 100644
|
||||
--- a/sound/core/seq/seq_clientmgr.c
|
||||
+++ b/sound/core/seq/seq_clientmgr.c
|
||||
@@ -1530,19 +1530,14 @@ static int snd_seq_ioctl_create_queue(struct snd_seq_client *client,
|
||||
void __user *arg)
|
||||
{
|
||||
struct snd_seq_queue_info info;
|
||||
- int result;
|
||||
struct snd_seq_queue *q;
|
||||
|
||||
if (copy_from_user(&info, arg, sizeof(info)))
|
||||
return -EFAULT;
|
||||
|
||||
- result = snd_seq_queue_alloc(client->number, info.locked, info.flags);
|
||||
- if (result < 0)
|
||||
- return result;
|
||||
-
|
||||
- q = queueptr(result);
|
||||
- if (q == NULL)
|
||||
- return -EINVAL;
|
||||
+ q = snd_seq_queue_alloc(client->number, info.locked, info.flags);
|
||||
+ if (IS_ERR(q))
|
||||
+ return PTR_ERR(q);
|
||||
|
||||
info.queue = q->queue;
|
||||
info.locked = q->locked;
|
||||
@@ -1552,7 +1547,7 @@ static int snd_seq_ioctl_create_queue(struct snd_seq_client *client,
|
||||
if (! info.name[0])
|
||||
snprintf(info.name, sizeof(info.name), "Queue-%d", q->queue);
|
||||
strlcpy(q->name, info.name, sizeof(q->name));
|
||||
- queuefree(q);
|
||||
+ snd_use_lock_free(&q->use_lock);
|
||||
|
||||
if (copy_to_user(arg, &info, sizeof(info)))
|
||||
return -EFAULT;
|
||||
diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c
|
||||
index 450c5187eecb..79e0c5604ef8 100644
|
||||
--- a/sound/core/seq/seq_queue.c
|
||||
+++ b/sound/core/seq/seq_queue.c
|
||||
@@ -184,22 +184,26 @@ void __exit snd_seq_queues_delete(void)
|
||||
static void queue_use(struct snd_seq_queue *queue, int client, int use);
|
||||
|
||||
/* allocate a new queue -
|
||||
- * return queue index value or negative value for error
|
||||
+ * return pointer to new queue or ERR_PTR(-errno) for error
|
||||
+ * The new queue's use_lock is set to 1. It is the caller's responsibility to
|
||||
+ * call snd_use_lock_free(&q->use_lock).
|
||||
*/
|
||||
-int snd_seq_queue_alloc(int client, int locked, unsigned int info_flags)
|
||||
+struct snd_seq_queue *snd_seq_queue_alloc(int client, int locked, unsigned int info_flags)
|
||||
{
|
||||
struct snd_seq_queue *q;
|
||||
|
||||
q = queue_new(client, locked);
|
||||
if (q == NULL)
|
||||
- return -ENOMEM;
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
q->info_flags = info_flags;
|
||||
queue_use(q, client, 1);
|
||||
+ snd_use_lock_use(&q->use_lock);
|
||||
if (queue_list_add(q) < 0) {
|
||||
+ snd_use_lock_free(&q->use_lock);
|
||||
queue_delete(q);
|
||||
- return -ENOMEM;
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
- return q->queue;
|
||||
+ return q;
|
||||
}
|
||||
|
||||
/* delete a queue - queue must be owned by the client */
|
||||
diff --git a/sound/core/seq/seq_queue.h b/sound/core/seq/seq_queue.h
|
||||
index 30c8111477f6..719093489a2c 100644
|
||||
--- a/sound/core/seq/seq_queue.h
|
||||
+++ b/sound/core/seq/seq_queue.h
|
||||
@@ -71,7 +71,7 @@ void snd_seq_queues_delete(void);
|
||||
|
||||
|
||||
/* create new queue (constructor) */
|
||||
-int snd_seq_queue_alloc(int client, int locked, unsigned int flags);
|
||||
+struct snd_seq_queue *snd_seq_queue_alloc(int client, int locked, unsigned int flags);
|
||||
|
||||
/* delete queue (destructor) */
|
||||
int snd_seq_queue_delete(int client, int queueid);
|
||||
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
|
||||
index 499b03c8281d..696de5ac69be 100644
|
||||
--- a/sound/usb/mixer.c
|
||||
+++ b/sound/usb/mixer.c
|
||||
@@ -541,6 +541,8 @@ int snd_usb_mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
|
||||
|
||||
if (size < sizeof(scale))
|
||||
return -ENOMEM;
|
||||
+ if (cval->min_mute)
|
||||
+ scale[0] = SNDRV_CTL_TLVT_DB_MINMAX_MUTE;
|
||||
scale[2] = cval->dBmin;
|
||||
scale[3] = cval->dBmax;
|
||||
if (copy_to_user(_tlv, scale, sizeof(scale)))
|
||||
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
|
||||
index 3417ef347e40..2b4b067646ab 100644
|
||||
--- a/sound/usb/mixer.h
|
||||
+++ b/sound/usb/mixer.h
|
||||
@@ -64,6 +64,7 @@ struct usb_mixer_elem_info {
|
||||
int cached;
|
||||
int cache_val[MAX_CHANNELS];
|
||||
u8 initialized;
|
||||
+ u8 min_mute;
|
||||
void *private_data;
|
||||
};
|
||||
|
||||
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
|
||||
index 04991b009132..5d2fc5f58bfe 100644
|
||||
--- a/sound/usb/mixer_quirks.c
|
||||
+++ b/sound/usb/mixer_quirks.c
|
||||
@@ -1873,6 +1873,12 @@ void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer,
|
||||
if (unitid == 7 && cval->control == UAC_FU_VOLUME)
|
||||
snd_dragonfly_quirk_db_scale(mixer, cval, kctl);
|
||||
break;
|
||||
+ /* lowest playback value is muted on C-Media devices */
|
||||
+ case USB_ID(0x0d8c, 0x000c):
|
||||
+ case USB_ID(0x0d8c, 0x0014):
|
||||
+ if (strstr(kctl->id.name, "Playback"))
|
||||
+ cval->min_mute = 1;
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
|
||||
index 29f38e2b4ca9..1cc20d138dae 100644
|
||||
--- a/sound/usb/quirks.c
|
||||
+++ b/sound/usb/quirks.c
|
||||
@@ -1143,6 +1143,7 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip)
|
||||
case USB_ID(0x0556, 0x0014): /* Phoenix Audio TMX320VC */
|
||||
case USB_ID(0x05A3, 0x9420): /* ELP HD USB Camera */
|
||||
case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */
|
||||
+ case USB_ID(0x1395, 0x740a): /* Sennheiser DECT */
|
||||
case USB_ID(0x1901, 0x0191): /* GE B850V3 CP2114 audio interface */
|
||||
case USB_ID(0x1de7, 0x0013): /* Phoenix Audio MT202exe */
|
||||
case USB_ID(0x1de7, 0x0014): /* Phoenix Audio TMX320 */
|
||||
1498
patch/kernel/s5p6818-default/03-patch-4.4.84-85.patch
Normal file
1498
patch/kernel/s5p6818-default/03-patch-4.4.84-85.patch
Normal file
File diff suppressed because it is too large
Load Diff
393
patch/kernel/s5p6818-default/03-patch-4.4.85-86.patch
Normal file
393
patch/kernel/s5p6818-default/03-patch-4.4.85-86.patch
Normal file
@ -0,0 +1,393 @@
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 0f3d843f42a7..1207bf6a0e7a 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 4
|
||||
-SUBLEVEL = 85
|
||||
+SUBLEVEL = 86
|
||||
EXTRAVERSION =
|
||||
NAME = Blurry Fish Butt
|
||||
|
||||
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
|
||||
index 4c46c54a3ad7..6638903f0cb9 100644
|
||||
--- a/arch/arm64/kernel/fpsimd.c
|
||||
+++ b/arch/arm64/kernel/fpsimd.c
|
||||
@@ -157,9 +157,11 @@ void fpsimd_thread_switch(struct task_struct *next)
|
||||
|
||||
void fpsimd_flush_thread(void)
|
||||
{
|
||||
+ preempt_disable();
|
||||
memset(¤t->thread.fpsimd_state, 0, sizeof(struct fpsimd_state));
|
||||
fpsimd_flush_task_state(current);
|
||||
set_thread_flag(TIF_FOREIGN_FPSTATE);
|
||||
+ preempt_enable();
|
||||
}
|
||||
|
||||
/*
|
||||
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
|
||||
index a4b466424a32..7fabf49f2aeb 100644
|
||||
--- a/arch/arm64/mm/fault.c
|
||||
+++ b/arch/arm64/mm/fault.c
|
||||
@@ -313,8 +313,11 @@ retry:
|
||||
* signal first. We do not need to release the mmap_sem because it
|
||||
* would already be released in __lock_page_or_retry in mm/filemap.c.
|
||||
*/
|
||||
- if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
|
||||
+ if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) {
|
||||
+ if (!user_mode(regs))
|
||||
+ goto no_context;
|
||||
return 0;
|
||||
+ }
|
||||
|
||||
/*
|
||||
* Major/minor page fault accounting is only done on the initial
|
||||
diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
|
||||
index de25aad07853..9016b4b70375 100644
|
||||
--- a/arch/x86/include/asm/io.h
|
||||
+++ b/arch/x86/include/asm/io.h
|
||||
@@ -304,13 +304,13 @@ static inline unsigned type in##bwl##_p(int port) \
|
||||
static inline void outs##bwl(int port, const void *addr, unsigned long count) \
|
||||
{ \
|
||||
asm volatile("rep; outs" #bwl \
|
||||
- : "+S"(addr), "+c"(count) : "d"(port)); \
|
||||
+ : "+S"(addr), "+c"(count) : "d"(port) : "memory"); \
|
||||
} \
|
||||
\
|
||||
static inline void ins##bwl(int port, void *addr, unsigned long count) \
|
||||
{ \
|
||||
asm volatile("rep; ins" #bwl \
|
||||
- : "+D"(addr), "+c"(count) : "d"(port)); \
|
||||
+ : "+D"(addr), "+c"(count) : "d"(port) : "memory"); \
|
||||
}
|
||||
|
||||
BUILDIO(b, b, char)
|
||||
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
|
||||
index cc91ae832ffb..6fd7b50c5747 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_uncore.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_uncore.c
|
||||
@@ -635,7 +635,8 @@ hsw_unclaimed_reg_detect(struct drm_i915_private *dev_priv)
|
||||
"enabling oneshot unclaimed register reporting. "
|
||||
"Please use i915.mmio_debug=N for more information.\n");
|
||||
__raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM);
|
||||
- i915.mmio_debug = mmio_debug_once--;
|
||||
+ i915.mmio_debug = mmio_debug_once;
|
||||
+ mmio_debug_once = false;
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/drivers/i2c/busses/i2c-jz4780.c b/drivers/i2c/busses/i2c-jz4780.c
|
||||
index f325663c27c5..4b58e8aaf5c5 100644
|
||||
--- a/drivers/i2c/busses/i2c-jz4780.c
|
||||
+++ b/drivers/i2c/busses/i2c-jz4780.c
|
||||
@@ -786,10 +786,6 @@ static int jz4780_i2c_probe(struct platform_device *pdev)
|
||||
|
||||
jz4780_i2c_writew(i2c, JZ4780_I2C_INTM, 0x0);
|
||||
|
||||
- i2c->cmd = 0;
|
||||
- memset(i2c->cmd_buf, 0, BUFSIZE);
|
||||
- memset(i2c->data_buf, 0, BUFSIZE);
|
||||
-
|
||||
i2c->irq = platform_get_irq(pdev, 0);
|
||||
ret = devm_request_irq(&pdev->dev, i2c->irq, jz4780_i2c_irq, 0,
|
||||
dev_name(&pdev->dev), i2c);
|
||||
diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c
|
||||
index 257a9eadd595..4ac6764f4897 100644
|
||||
--- a/drivers/net/wireless/p54/fwio.c
|
||||
+++ b/drivers/net/wireless/p54/fwio.c
|
||||
@@ -488,7 +488,7 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell)
|
||||
|
||||
entry += sizeof(__le16);
|
||||
chan->pa_points_per_curve = 8;
|
||||
- memset(chan->curve_data, 0, sizeof(*chan->curve_data));
|
||||
+ memset(chan->curve_data, 0, sizeof(chan->curve_data));
|
||||
memcpy(chan->curve_data, entry,
|
||||
sizeof(struct p54_pa_curve_data_sample) *
|
||||
min((u8)8, curve_data->points_per_channel));
|
||||
diff --git a/drivers/scsi/isci/remote_node_context.c b/drivers/scsi/isci/remote_node_context.c
|
||||
index 1910100638a2..00602abec0ea 100644
|
||||
--- a/drivers/scsi/isci/remote_node_context.c
|
||||
+++ b/drivers/scsi/isci/remote_node_context.c
|
||||
@@ -66,6 +66,9 @@ const char *rnc_state_name(enum scis_sds_remote_node_context_states state)
|
||||
{
|
||||
static const char * const strings[] = RNC_STATES;
|
||||
|
||||
+ if (state >= ARRAY_SIZE(strings))
|
||||
+ return "UNKNOWN";
|
||||
+
|
||||
return strings[state];
|
||||
}
|
||||
#undef C
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
|
||||
index 0e6aaef9a038..c74f74ab981c 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_els.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_els.c
|
||||
@@ -1054,7 +1054,10 @@ stop_rr_fcf_flogi:
|
||||
lpfc_sli4_unreg_all_rpis(vport);
|
||||
}
|
||||
}
|
||||
- lpfc_issue_reg_vfi(vport);
|
||||
+
|
||||
+ /* Do not register VFI if the driver aborted FLOGI */
|
||||
+ if (!lpfc_error_lost_link(irsp))
|
||||
+ lpfc_issue_reg_vfi(vport);
|
||||
lpfc_nlp_put(ndlp);
|
||||
goto out;
|
||||
}
|
||||
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
|
||||
index 6514636431ab..8a9e139e2853 100644
|
||||
--- a/drivers/scsi/sg.c
|
||||
+++ b/drivers/scsi/sg.c
|
||||
@@ -153,6 +153,7 @@ typedef struct sg_fd { /* holds the state of a file descriptor */
|
||||
struct sg_device *parentdp; /* owning device */
|
||||
wait_queue_head_t read_wait; /* queue read until command done */
|
||||
rwlock_t rq_list_lock; /* protect access to list in req_arr */
|
||||
+ struct mutex f_mutex; /* protect against changes in this fd */
|
||||
int timeout; /* defaults to SG_DEFAULT_TIMEOUT */
|
||||
int timeout_user; /* defaults to SG_DEFAULT_TIMEOUT_USER */
|
||||
Sg_scatter_hold reserve; /* buffer held for this file descriptor */
|
||||
@@ -166,6 +167,7 @@ typedef struct sg_fd { /* holds the state of a file descriptor */
|
||||
unsigned char next_cmd_len; /* 0: automatic, >0: use on next write() */
|
||||
char keep_orphan; /* 0 -> drop orphan (def), 1 -> keep for read() */
|
||||
char mmap_called; /* 0 -> mmap() never called on this fd */
|
||||
+ char res_in_use; /* 1 -> 'reserve' array in use */
|
||||
struct kref f_ref;
|
||||
struct execute_work ew;
|
||||
} Sg_fd;
|
||||
@@ -209,7 +211,6 @@ static void sg_remove_sfp(struct kref *);
|
||||
static Sg_request *sg_get_rq_mark(Sg_fd * sfp, int pack_id);
|
||||
static Sg_request *sg_add_request(Sg_fd * sfp);
|
||||
static int sg_remove_request(Sg_fd * sfp, Sg_request * srp);
|
||||
-static int sg_res_in_use(Sg_fd * sfp);
|
||||
static Sg_device *sg_get_dev(int dev);
|
||||
static void sg_device_destroy(struct kref *kref);
|
||||
|
||||
@@ -625,6 +626,7 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
|
||||
}
|
||||
buf += SZ_SG_HEADER;
|
||||
__get_user(opcode, buf);
|
||||
+ mutex_lock(&sfp->f_mutex);
|
||||
if (sfp->next_cmd_len > 0) {
|
||||
cmd_size = sfp->next_cmd_len;
|
||||
sfp->next_cmd_len = 0; /* reset so only this write() effected */
|
||||
@@ -633,6 +635,7 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
|
||||
if ((opcode >= 0xc0) && old_hdr.twelve_byte)
|
||||
cmd_size = 12;
|
||||
}
|
||||
+ mutex_unlock(&sfp->f_mutex);
|
||||
SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sdp,
|
||||
"sg_write: scsi opcode=0x%02x, cmd_size=%d\n", (int) opcode, cmd_size));
|
||||
/* Determine buffer size. */
|
||||
@@ -732,7 +735,7 @@ sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf,
|
||||
sg_remove_request(sfp, srp);
|
||||
return -EINVAL; /* either MMAP_IO or DIRECT_IO (not both) */
|
||||
}
|
||||
- if (sg_res_in_use(sfp)) {
|
||||
+ if (sfp->res_in_use) {
|
||||
sg_remove_request(sfp, srp);
|
||||
return -EBUSY; /* reserve buffer already being used */
|
||||
}
|
||||
@@ -902,7 +905,7 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
|
||||
return result;
|
||||
if (val) {
|
||||
sfp->low_dma = 1;
|
||||
- if ((0 == sfp->low_dma) && (0 == sg_res_in_use(sfp))) {
|
||||
+ if ((0 == sfp->low_dma) && !sfp->res_in_use) {
|
||||
val = (int) sfp->reserve.bufflen;
|
||||
sg_remove_scat(sfp, &sfp->reserve);
|
||||
sg_build_reserve(sfp, val);
|
||||
@@ -977,12 +980,18 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
|
||||
return -EINVAL;
|
||||
val = min_t(int, val,
|
||||
max_sectors_bytes(sdp->device->request_queue));
|
||||
+ mutex_lock(&sfp->f_mutex);
|
||||
if (val != sfp->reserve.bufflen) {
|
||||
- if (sg_res_in_use(sfp) || sfp->mmap_called)
|
||||
+ if (sfp->mmap_called ||
|
||||
+ sfp->res_in_use) {
|
||||
+ mutex_unlock(&sfp->f_mutex);
|
||||
return -EBUSY;
|
||||
+ }
|
||||
+
|
||||
sg_remove_scat(sfp, &sfp->reserve);
|
||||
sg_build_reserve(sfp, val);
|
||||
}
|
||||
+ mutex_unlock(&sfp->f_mutex);
|
||||
return 0;
|
||||
case SG_GET_RESERVED_SIZE:
|
||||
val = min_t(int, sfp->reserve.bufflen,
|
||||
@@ -1737,13 +1746,22 @@ sg_start_req(Sg_request *srp, unsigned char *cmd)
|
||||
md = &map_data;
|
||||
|
||||
if (md) {
|
||||
- if (!sg_res_in_use(sfp) && dxfer_len <= rsv_schp->bufflen)
|
||||
+ mutex_lock(&sfp->f_mutex);
|
||||
+ if (dxfer_len <= rsv_schp->bufflen &&
|
||||
+ !sfp->res_in_use) {
|
||||
+ sfp->res_in_use = 1;
|
||||
sg_link_reserve(sfp, srp, dxfer_len);
|
||||
- else {
|
||||
+ } else if ((hp->flags & SG_FLAG_MMAP_IO) && sfp->res_in_use) {
|
||||
+ mutex_unlock(&sfp->f_mutex);
|
||||
+ return -EBUSY;
|
||||
+ } else {
|
||||
res = sg_build_indirect(req_schp, sfp, dxfer_len);
|
||||
- if (res)
|
||||
+ if (res) {
|
||||
+ mutex_unlock(&sfp->f_mutex);
|
||||
return res;
|
||||
+ }
|
||||
}
|
||||
+ mutex_unlock(&sfp->f_mutex);
|
||||
|
||||
md->pages = req_schp->pages;
|
||||
md->page_order = req_schp->page_order;
|
||||
@@ -2034,6 +2052,8 @@ sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp)
|
||||
req_schp->sglist_len = 0;
|
||||
sfp->save_scat_len = 0;
|
||||
srp->res_used = 0;
|
||||
+ /* Called without mutex lock to avoid deadlock */
|
||||
+ sfp->res_in_use = 0;
|
||||
}
|
||||
|
||||
static Sg_request *
|
||||
@@ -2145,6 +2165,7 @@ sg_add_sfp(Sg_device * sdp)
|
||||
rwlock_init(&sfp->rq_list_lock);
|
||||
|
||||
kref_init(&sfp->f_ref);
|
||||
+ mutex_init(&sfp->f_mutex);
|
||||
sfp->timeout = SG_DEFAULT_TIMEOUT;
|
||||
sfp->timeout_user = SG_DEFAULT_TIMEOUT_USER;
|
||||
sfp->force_packid = SG_DEF_FORCE_PACK_ID;
|
||||
@@ -2220,20 +2241,6 @@ sg_remove_sfp(struct kref *kref)
|
||||
schedule_work(&sfp->ew.work);
|
||||
}
|
||||
|
||||
-static int
|
||||
-sg_res_in_use(Sg_fd * sfp)
|
||||
-{
|
||||
- const Sg_request *srp;
|
||||
- unsigned long iflags;
|
||||
-
|
||||
- read_lock_irqsave(&sfp->rq_list_lock, iflags);
|
||||
- for (srp = sfp->headrp; srp; srp = srp->nextrp)
|
||||
- if (srp->res_used)
|
||||
- break;
|
||||
- read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
|
||||
- return srp ? 1 : 0;
|
||||
-}
|
||||
-
|
||||
#ifdef CONFIG_SCSI_PROC_FS
|
||||
static int
|
||||
sg_idr_max_id(int id, void *p, void *data)
|
||||
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
|
||||
index 9c62a6f9757a..600c67ef8a03 100644
|
||||
--- a/fs/btrfs/volumes.c
|
||||
+++ b/fs/btrfs/volumes.c
|
||||
@@ -108,7 +108,7 @@ const struct btrfs_raid_attr btrfs_raid_array[BTRFS_NR_RAID_TYPES] = {
|
||||
},
|
||||
};
|
||||
|
||||
-const u64 const btrfs_raid_group[BTRFS_NR_RAID_TYPES] = {
|
||||
+const u64 btrfs_raid_group[BTRFS_NR_RAID_TYPES] = {
|
||||
[BTRFS_RAID_RAID10] = BTRFS_BLOCK_GROUP_RAID10,
|
||||
[BTRFS_RAID_RAID1] = BTRFS_BLOCK_GROUP_RAID1,
|
||||
[BTRFS_RAID_DUP] = BTRFS_BLOCK_GROUP_DUP,
|
||||
diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h
|
||||
index 782d4e814e21..4bc4b1b13193 100644
|
||||
--- a/include/linux/lightnvm.h
|
||||
+++ b/include/linux/lightnvm.h
|
||||
@@ -310,6 +310,7 @@ static inline struct ppa_addr dev_to_generic_addr(struct nvm_dev *dev,
|
||||
{
|
||||
struct ppa_addr l;
|
||||
|
||||
+ l.ppa = 0;
|
||||
/*
|
||||
* (r.ppa << X offset) & X len bitmask. X eq. blk, pg, etc.
|
||||
*/
|
||||
diff --git a/kernel/gcov/base.c b/kernel/gcov/base.c
|
||||
index 7080ae1eb6c1..f850e906564b 100644
|
||||
--- a/kernel/gcov/base.c
|
||||
+++ b/kernel/gcov/base.c
|
||||
@@ -98,6 +98,12 @@ void __gcov_merge_icall_topn(gcov_type *counters, unsigned int n_counters)
|
||||
}
|
||||
EXPORT_SYMBOL(__gcov_merge_icall_topn);
|
||||
|
||||
+void __gcov_exit(void)
|
||||
+{
|
||||
+ /* Unused. */
|
||||
+}
|
||||
+EXPORT_SYMBOL(__gcov_exit);
|
||||
+
|
||||
/**
|
||||
* gcov_enable_events - enable event reporting through gcov_event()
|
||||
*
|
||||
diff --git a/kernel/gcov/gcc_4_7.c b/kernel/gcov/gcc_4_7.c
|
||||
index e25e92fb44fa..46a18e72bce6 100644
|
||||
--- a/kernel/gcov/gcc_4_7.c
|
||||
+++ b/kernel/gcov/gcc_4_7.c
|
||||
@@ -18,7 +18,9 @@
|
||||
#include <linux/vmalloc.h>
|
||||
#include "gcov.h"
|
||||
|
||||
-#if __GNUC__ == 5 && __GNUC_MINOR__ >= 1
|
||||
+#if (__GNUC__ >= 7)
|
||||
+#define GCOV_COUNTERS 9
|
||||
+#elif (__GNUC__ > 5) || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1)
|
||||
#define GCOV_COUNTERS 10
|
||||
#elif __GNUC__ == 4 && __GNUC_MINOR__ >= 9
|
||||
#define GCOV_COUNTERS 9
|
||||
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
|
||||
index 74177189063c..d3125c169684 100644
|
||||
--- a/sound/pci/au88x0/au88x0_core.c
|
||||
+++ b/sound/pci/au88x0/au88x0_core.c
|
||||
@@ -2150,8 +2150,7 @@ vortex_adb_allocroute(vortex_t *vortex, int dma, int nr_ch, int dir,
|
||||
stream->resources, en,
|
||||
VORTEX_RESOURCE_SRC)) < 0) {
|
||||
memset(stream->resources, 0,
|
||||
- sizeof(unsigned char) *
|
||||
- VORTEX_RESOURCE_LAST);
|
||||
+ sizeof(stream->resources));
|
||||
return -EBUSY;
|
||||
}
|
||||
if (stream->type != VORTEX_PCM_A3D) {
|
||||
@@ -2161,7 +2160,7 @@ vortex_adb_allocroute(vortex_t *vortex, int dma, int nr_ch, int dir,
|
||||
VORTEX_RESOURCE_MIXIN)) < 0) {
|
||||
memset(stream->resources,
|
||||
0,
|
||||
- sizeof(unsigned char) * VORTEX_RESOURCE_LAST);
|
||||
+ sizeof(stream->resources));
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
@@ -2174,8 +2173,7 @@ vortex_adb_allocroute(vortex_t *vortex, int dma, int nr_ch, int dir,
|
||||
stream->resources, en,
|
||||
VORTEX_RESOURCE_A3D)) < 0) {
|
||||
memset(stream->resources, 0,
|
||||
- sizeof(unsigned char) *
|
||||
- VORTEX_RESOURCE_LAST);
|
||||
+ sizeof(stream->resources));
|
||||
dev_err(vortex->card->dev,
|
||||
"out of A3D sources. Sorry\n");
|
||||
return -EBUSY;
|
||||
@@ -2289,8 +2287,7 @@ vortex_adb_allocroute(vortex_t *vortex, int dma, int nr_ch, int dir,
|
||||
VORTEX_RESOURCE_MIXOUT))
|
||||
< 0) {
|
||||
memset(stream->resources, 0,
|
||||
- sizeof(unsigned char) *
|
||||
- VORTEX_RESOURCE_LAST);
|
||||
+ sizeof(stream->resources));
|
||||
return -EBUSY;
|
||||
}
|
||||
if ((src[i] =
|
||||
@@ -2298,8 +2295,7 @@ vortex_adb_allocroute(vortex_t *vortex, int dma, int nr_ch, int dir,
|
||||
stream->resources, en,
|
||||
VORTEX_RESOURCE_SRC)) < 0) {
|
||||
memset(stream->resources, 0,
|
||||
- sizeof(unsigned char) *
|
||||
- VORTEX_RESOURCE_LAST);
|
||||
+ sizeof(stream->resources));
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
408
patch/kernel/s5p6818-default/03-patch-4.4.86-87.patch
Normal file
408
patch/kernel/s5p6818-default/03-patch-4.4.86-87.patch
Normal file
@ -0,0 +1,408 @@
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 1207bf6a0e7a..f6838187b568 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 4
|
||||
-SUBLEVEL = 86
|
||||
+SUBLEVEL = 87
|
||||
EXTRAVERSION =
|
||||
NAME = Blurry Fish Butt
|
||||
|
||||
diff --git a/arch/alpha/include/asm/types.h b/arch/alpha/include/asm/types.h
|
||||
index 4cb4b6d3452c..0bc66e1d3a7e 100644
|
||||
--- a/arch/alpha/include/asm/types.h
|
||||
+++ b/arch/alpha/include/asm/types.h
|
||||
@@ -1,6 +1,6 @@
|
||||
#ifndef _ALPHA_TYPES_H
|
||||
#define _ALPHA_TYPES_H
|
||||
|
||||
-#include <asm-generic/int-ll64.h>
|
||||
+#include <uapi/asm/types.h>
|
||||
|
||||
#endif /* _ALPHA_TYPES_H */
|
||||
diff --git a/arch/alpha/include/uapi/asm/types.h b/arch/alpha/include/uapi/asm/types.h
|
||||
index 9fd3cd459777..8d1024d7be05 100644
|
||||
--- a/arch/alpha/include/uapi/asm/types.h
|
||||
+++ b/arch/alpha/include/uapi/asm/types.h
|
||||
@@ -9,8 +9,18 @@
|
||||
* need to be careful to avoid a name clashes.
|
||||
*/
|
||||
|
||||
-#ifndef __KERNEL__
|
||||
+/*
|
||||
+ * This is here because we used to use l64 for alpha
|
||||
+ * and we don't want to impact user mode with our change to ll64
|
||||
+ * in the kernel.
|
||||
+ *
|
||||
+ * However, some user programs are fine with this. They can
|
||||
+ * flag __SANE_USERSPACE_TYPES__ to get int-ll64.h here.
|
||||
+ */
|
||||
+#if !defined(__SANE_USERSPACE_TYPES__) && !defined(__KERNEL__)
|
||||
#include <asm-generic/int-l64.h>
|
||||
+#else
|
||||
+#include <asm-generic/int-ll64.h>
|
||||
#endif
|
||||
|
||||
#endif /* _UAPI_ALPHA_TYPES_H */
|
||||
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
|
||||
index ba079e279b58..e8835d4e173c 100644
|
||||
--- a/arch/arm/kvm/mmu.c
|
||||
+++ b/arch/arm/kvm/mmu.c
|
||||
@@ -824,24 +824,25 @@ void stage2_unmap_vm(struct kvm *kvm)
|
||||
* Walks the level-1 page table pointed to by kvm->arch.pgd and frees all
|
||||
* underlying level-2 and level-3 tables before freeing the actual level-1 table
|
||||
* and setting the struct pointer to NULL.
|
||||
- *
|
||||
- * Note we don't need locking here as this is only called when the VM is
|
||||
- * destroyed, which can only be done once.
|
||||
*/
|
||||
void kvm_free_stage2_pgd(struct kvm *kvm)
|
||||
{
|
||||
- if (kvm->arch.pgd == NULL)
|
||||
- return;
|
||||
+ void *pgd = NULL;
|
||||
+ void *hwpgd = NULL;
|
||||
|
||||
spin_lock(&kvm->mmu_lock);
|
||||
- unmap_stage2_range(kvm, 0, KVM_PHYS_SIZE);
|
||||
+ if (kvm->arch.pgd) {
|
||||
+ unmap_stage2_range(kvm, 0, KVM_PHYS_SIZE);
|
||||
+ pgd = READ_ONCE(kvm->arch.pgd);
|
||||
+ hwpgd = kvm_get_hwpgd(kvm);
|
||||
+ kvm->arch.pgd = NULL;
|
||||
+ }
|
||||
spin_unlock(&kvm->mmu_lock);
|
||||
|
||||
- kvm_free_hwpgd(kvm_get_hwpgd(kvm));
|
||||
- if (KVM_PREALLOC_LEVEL > 0)
|
||||
- kfree(kvm->arch.pgd);
|
||||
-
|
||||
- kvm->arch.pgd = NULL;
|
||||
+ if (hwpgd)
|
||||
+ kvm_free_hwpgd(hwpgd);
|
||||
+ if (KVM_PREALLOC_LEVEL > 0 && pgd)
|
||||
+ kfree(pgd);
|
||||
}
|
||||
|
||||
static pud_t *stage2_get_pud(struct kvm *kvm, struct kvm_mmu_memory_cache *cache,
|
||||
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
|
||||
index f5e9f9310b48..b3b0004ea8ac 100644
|
||||
--- a/crypto/algif_skcipher.c
|
||||
+++ b/crypto/algif_skcipher.c
|
||||
@@ -86,8 +86,13 @@ static void skcipher_free_async_sgls(struct skcipher_async_req *sreq)
|
||||
}
|
||||
sgl = sreq->tsg;
|
||||
n = sg_nents(sgl);
|
||||
- for_each_sg(sgl, sg, n, i)
|
||||
- put_page(sg_page(sg));
|
||||
+ for_each_sg(sgl, sg, n, i) {
|
||||
+ struct page *page = sg_page(sg);
|
||||
+
|
||||
+ /* some SGs may not have a page mapped */
|
||||
+ if (page && atomic_read(&page->_count))
|
||||
+ put_page(page);
|
||||
+ }
|
||||
|
||||
kfree(sreq->tsg);
|
||||
}
|
||||
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c
|
||||
index 025c429050c0..5d8dfe027b30 100644
|
||||
--- a/drivers/gpu/drm/ttm/ttm_page_alloc.c
|
||||
+++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c
|
||||
@@ -612,7 +612,7 @@ static void ttm_page_pool_fill_locked(struct ttm_page_pool *pool,
|
||||
} else {
|
||||
pr_err("Failed to fill pool (%p)\n", pool);
|
||||
/* If we have any pages left put them to the pool. */
|
||||
- list_for_each_entry(p, &pool->list, lru) {
|
||||
+ list_for_each_entry(p, &new_pages, lru) {
|
||||
++cpages;
|
||||
}
|
||||
list_splice(&new_pages, &pool->list);
|
||||
diff --git a/drivers/i2c/busses/i2c-ismt.c b/drivers/i2c/busses/i2c-ismt.c
|
||||
index 7ba795b24e75..639d1a9c8793 100644
|
||||
--- a/drivers/i2c/busses/i2c-ismt.c
|
||||
+++ b/drivers/i2c/busses/i2c-ismt.c
|
||||
@@ -339,8 +339,10 @@ static int ismt_process_desc(const struct ismt_desc *desc,
|
||||
break;
|
||||
case I2C_SMBUS_BLOCK_DATA:
|
||||
case I2C_SMBUS_I2C_BLOCK_DATA:
|
||||
- memcpy(&data->block[1], dma_buffer, desc->rxbytes);
|
||||
- data->block[0] = desc->rxbytes;
|
||||
+ if (desc->rxbytes != dma_buffer[0] + 1)
|
||||
+ return -EMSGSIZE;
|
||||
+
|
||||
+ memcpy(data->block, dma_buffer, desc->rxbytes);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
|
||||
index 9e17ef27a183..6f1dbd52ec91 100644
|
||||
--- a/drivers/irqchip/irq-mips-gic.c
|
||||
+++ b/drivers/irqchip/irq-mips-gic.c
|
||||
@@ -915,8 +915,11 @@ static int __init gic_of_init(struct device_node *node,
|
||||
gic_len = resource_size(&res);
|
||||
}
|
||||
|
||||
- if (mips_cm_present())
|
||||
+ if (mips_cm_present()) {
|
||||
write_gcr_gic_base(gic_base | CM_GCR_GIC_BASE_GICEN_MSK);
|
||||
+ /* Ensure GIC region is enabled before trying to access it */
|
||||
+ __sync();
|
||||
+ }
|
||||
gic_present = true;
|
||||
|
||||
__gic_init(gic_base, gic_len, cpu_vec, 0, node);
|
||||
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c
|
||||
index cd4777954f87..9bee3f11898a 100644
|
||||
--- a/drivers/net/wireless/ti/wl1251/main.c
|
||||
+++ b/drivers/net/wireless/ti/wl1251/main.c
|
||||
@@ -1567,6 +1567,7 @@ struct ieee80211_hw *wl1251_alloc_hw(void)
|
||||
|
||||
wl->state = WL1251_STATE_OFF;
|
||||
mutex_init(&wl->mutex);
|
||||
+ spin_lock_init(&wl->wl_lock);
|
||||
|
||||
wl->tx_mgmt_frm_rate = DEFAULT_HW_GEN_TX_RATE;
|
||||
wl->tx_mgmt_frm_mod = DEFAULT_HW_GEN_MODULATION_TYPE;
|
||||
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
|
||||
index c6a1ec110c01..22bae2b434e2 100644
|
||||
--- a/fs/ceph/addr.c
|
||||
+++ b/fs/ceph/addr.c
|
||||
@@ -189,7 +189,7 @@ static int ceph_releasepage(struct page *page, gfp_t g)
|
||||
/*
|
||||
* read a single page, without unlocking it.
|
||||
*/
|
||||
-static int readpage_nounlock(struct file *filp, struct page *page)
|
||||
+static int ceph_do_readpage(struct file *filp, struct page *page)
|
||||
{
|
||||
struct inode *inode = file_inode(filp);
|
||||
struct ceph_inode_info *ci = ceph_inode(inode);
|
||||
@@ -219,7 +219,7 @@ static int readpage_nounlock(struct file *filp, struct page *page)
|
||||
|
||||
err = ceph_readpage_from_fscache(inode, page);
|
||||
if (err == 0)
|
||||
- goto out;
|
||||
+ return -EINPROGRESS;
|
||||
|
||||
dout("readpage inode %p file %p page %p index %lu\n",
|
||||
inode, filp, page, page->index);
|
||||
@@ -249,8 +249,11 @@ out:
|
||||
|
||||
static int ceph_readpage(struct file *filp, struct page *page)
|
||||
{
|
||||
- int r = readpage_nounlock(filp, page);
|
||||
- unlock_page(page);
|
||||
+ int r = ceph_do_readpage(filp, page);
|
||||
+ if (r != -EINPROGRESS)
|
||||
+ unlock_page(page);
|
||||
+ else
|
||||
+ r = 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -1094,7 +1097,7 @@ retry_locked:
|
||||
goto retry_locked;
|
||||
r = writepage_nounlock(page, NULL);
|
||||
if (r < 0)
|
||||
- goto fail_nosnap;
|
||||
+ goto fail_unlock;
|
||||
goto retry_locked;
|
||||
}
|
||||
|
||||
@@ -1122,11 +1125,14 @@ retry_locked:
|
||||
}
|
||||
|
||||
/* we need to read it. */
|
||||
- r = readpage_nounlock(file, page);
|
||||
- if (r < 0)
|
||||
- goto fail_nosnap;
|
||||
+ r = ceph_do_readpage(file, page);
|
||||
+ if (r < 0) {
|
||||
+ if (r == -EINPROGRESS)
|
||||
+ return -EAGAIN;
|
||||
+ goto fail_unlock;
|
||||
+ }
|
||||
goto retry_locked;
|
||||
-fail_nosnap:
|
||||
+fail_unlock:
|
||||
unlock_page(page);
|
||||
return r;
|
||||
}
|
||||
diff --git a/fs/ceph/cache.c b/fs/ceph/cache.c
|
||||
index a4766ded1ba7..ff1cfd7b1083 100644
|
||||
--- a/fs/ceph/cache.c
|
||||
+++ b/fs/ceph/cache.c
|
||||
@@ -224,13 +224,7 @@ void ceph_fscache_unregister_inode_cookie(struct ceph_inode_info* ci)
|
||||
fscache_relinquish_cookie(cookie, 0);
|
||||
}
|
||||
|
||||
-static void ceph_vfs_readpage_complete(struct page *page, void *data, int error)
|
||||
-{
|
||||
- if (!error)
|
||||
- SetPageUptodate(page);
|
||||
-}
|
||||
-
|
||||
-static void ceph_vfs_readpage_complete_unlock(struct page *page, void *data, int error)
|
||||
+static void ceph_readpage_from_fscache_complete(struct page *page, void *data, int error)
|
||||
{
|
||||
if (!error)
|
||||
SetPageUptodate(page);
|
||||
@@ -259,7 +253,7 @@ int ceph_readpage_from_fscache(struct inode *inode, struct page *page)
|
||||
return -ENOBUFS;
|
||||
|
||||
ret = fscache_read_or_alloc_page(ci->fscache, page,
|
||||
- ceph_vfs_readpage_complete, NULL,
|
||||
+ ceph_readpage_from_fscache_complete, NULL,
|
||||
GFP_KERNEL);
|
||||
|
||||
switch (ret) {
|
||||
@@ -288,7 +282,7 @@ int ceph_readpages_from_fscache(struct inode *inode,
|
||||
return -ENOBUFS;
|
||||
|
||||
ret = fscache_read_or_alloc_pages(ci->fscache, mapping, pages, nr_pages,
|
||||
- ceph_vfs_readpage_complete_unlock,
|
||||
+ ceph_readpage_from_fscache_complete,
|
||||
NULL, mapping_gfp_mask(mapping));
|
||||
|
||||
switch (ret) {
|
||||
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
|
||||
index fa8df3fef6fc..297e05c9e2b0 100644
|
||||
--- a/fs/cifs/dir.c
|
||||
+++ b/fs/cifs/dir.c
|
||||
@@ -194,7 +194,7 @@ check_name(struct dentry *direntry, struct cifs_tcon *tcon)
|
||||
int i;
|
||||
|
||||
if (unlikely(direntry->d_name.len >
|
||||
- tcon->fsAttrInfo.MaxPathNameComponentLength))
|
||||
+ le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength)))
|
||||
return -ENAMETOOLONG;
|
||||
|
||||
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
|
||||
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h
|
||||
index b8f553b32dda..aacb15bd56fe 100644
|
||||
--- a/fs/cifs/smb2pdu.h
|
||||
+++ b/fs/cifs/smb2pdu.h
|
||||
@@ -82,8 +82,8 @@
|
||||
|
||||
#define NUMBER_OF_SMB2_COMMANDS 0x0013
|
||||
|
||||
-/* BB FIXME - analyze following length BB */
|
||||
-#define MAX_SMB2_HDR_SIZE 0x78 /* 4 len + 64 hdr + (2*24 wct) + 2 bct + 2 pad */
|
||||
+/* 4 len + 52 transform hdr + 64 hdr + 56 create rsp */
|
||||
+#define MAX_SMB2_HDR_SIZE 0x00b0
|
||||
|
||||
#define SMB2_PROTO_NUMBER cpu_to_le32(0x424d53fe)
|
||||
|
||||
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
|
||||
index 1e009cad8d5c..1b08556776ce 100644
|
||||
--- a/fs/eventpoll.c
|
||||
+++ b/fs/eventpoll.c
|
||||
@@ -518,8 +518,13 @@ static void ep_remove_wait_queue(struct eppoll_entry *pwq)
|
||||
wait_queue_head_t *whead;
|
||||
|
||||
rcu_read_lock();
|
||||
- /* If it is cleared by POLLFREE, it should be rcu-safe */
|
||||
- whead = rcu_dereference(pwq->whead);
|
||||
+ /*
|
||||
+ * If it is cleared by POLLFREE, it should be rcu-safe.
|
||||
+ * If we read NULL we need a barrier paired with
|
||||
+ * smp_store_release() in ep_poll_callback(), otherwise
|
||||
+ * we rely on whead->lock.
|
||||
+ */
|
||||
+ whead = smp_load_acquire(&pwq->whead);
|
||||
if (whead)
|
||||
remove_wait_queue(whead, &pwq->wait);
|
||||
rcu_read_unlock();
|
||||
@@ -1003,17 +1008,6 @@ static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *k
|
||||
struct epitem *epi = ep_item_from_wait(wait);
|
||||
struct eventpoll *ep = epi->ep;
|
||||
|
||||
- if ((unsigned long)key & POLLFREE) {
|
||||
- ep_pwq_from_wait(wait)->whead = NULL;
|
||||
- /*
|
||||
- * whead = NULL above can race with ep_remove_wait_queue()
|
||||
- * which can do another remove_wait_queue() after us, so we
|
||||
- * can't use __remove_wait_queue(). whead->lock is held by
|
||||
- * the caller.
|
||||
- */
|
||||
- list_del_init(&wait->task_list);
|
||||
- }
|
||||
-
|
||||
spin_lock_irqsave(&ep->lock, flags);
|
||||
|
||||
/*
|
||||
@@ -1078,6 +1072,23 @@ out_unlock:
|
||||
if (pwake)
|
||||
ep_poll_safewake(&ep->poll_wait);
|
||||
|
||||
+
|
||||
+ if ((unsigned long)key & POLLFREE) {
|
||||
+ /*
|
||||
+ * If we race with ep_remove_wait_queue() it can miss
|
||||
+ * ->whead = NULL and do another remove_wait_queue() after
|
||||
+ * us, so we can't use __remove_wait_queue().
|
||||
+ */
|
||||
+ list_del_init(&wait->task_list);
|
||||
+ /*
|
||||
+ * ->whead != NULL protects us from the race with ep_free()
|
||||
+ * or ep_remove(), ep_remove_wait_queue() takes whead->lock
|
||||
+ * held by the caller. Once we nullify it, nothing protects
|
||||
+ * ep/epi or even wait.
|
||||
+ */
|
||||
+ smp_store_release(&ep_pwq_from_wait(wait)->whead, NULL);
|
||||
+ }
|
||||
+
|
||||
return 1;
|
||||
}
|
||||
|
||||
diff --git a/include/asm-generic/topology.h b/include/asm-generic/topology.h
|
||||
index fc824e2828f3..5d2add1a6c96 100644
|
||||
--- a/include/asm-generic/topology.h
|
||||
+++ b/include/asm-generic/topology.h
|
||||
@@ -48,7 +48,11 @@
|
||||
#define parent_node(node) ((void)(node),0)
|
||||
#endif
|
||||
#ifndef cpumask_of_node
|
||||
-#define cpumask_of_node(node) ((void)node, cpu_online_mask)
|
||||
+ #ifdef CONFIG_NEED_MULTIPLE_NODES
|
||||
+ #define cpumask_of_node(node) ((node) == 0 ? cpu_online_mask : cpu_none_mask)
|
||||
+ #else
|
||||
+ #define cpumask_of_node(node) ((void)node, cpu_online_mask)
|
||||
+ #endif
|
||||
#endif
|
||||
#ifndef pcibus_to_node
|
||||
#define pcibus_to_node(bus) ((void)(bus), -1)
|
||||
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
|
||||
index 8ccd66a97c8b..2924b6faa469 100644
|
||||
--- a/kernel/cpuset.c
|
||||
+++ b/kernel/cpuset.c
|
||||
@@ -1910,6 +1910,7 @@ static struct cftype files[] = {
|
||||
{
|
||||
.name = "memory_pressure",
|
||||
.read_u64 = cpuset_read_u64,
|
||||
+ .private = FILE_MEMORY_PRESSURE,
|
||||
},
|
||||
|
||||
{
|
||||
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
|
||||
index 77055a362041..0e01250f2072 100644
|
||||
--- a/net/xfrm/xfrm_policy.c
|
||||
+++ b/net/xfrm/xfrm_policy.c
|
||||
@@ -3275,9 +3275,15 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
|
||||
struct xfrm_state *x_new[XFRM_MAX_DEPTH];
|
||||
struct xfrm_migrate *mp;
|
||||
|
||||
+ /* Stage 0 - sanity checks */
|
||||
if ((err = xfrm_migrate_check(m, num_migrate)) < 0)
|
||||
goto out;
|
||||
|
||||
+ if (dir >= XFRM_POLICY_MAX) {
|
||||
+ err = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
/* Stage 1 - find policy */
|
||||
if ((pol = xfrm_migrate_policy_find(sel, dir, type, net)) == NULL) {
|
||||
err = -ENOENT;
|
||||
1154
patch/kernel/s5p6818-default/03-patch-4.4.87-88.patch
Normal file
1154
patch/kernel/s5p6818-default/03-patch-4.4.87-88.patch
Normal file
File diff suppressed because it is too large
Load Diff
2770
patch/kernel/s5p6818-default/03-patch-4.4.88-89.patch
Normal file
2770
patch/kernel/s5p6818-default/03-patch-4.4.88-89.patch
Normal file
File diff suppressed because it is too large
Load Diff
1208
patch/kernel/s5p6818-default/03-patch-4.4.89-90.patch
Normal file
1208
patch/kernel/s5p6818-default/03-patch-4.4.89-90.patch
Normal file
File diff suppressed because it is too large
Load Diff
2284
patch/kernel/s5p6818-default/03-patch-4.4.90-91.patch
Normal file
2284
patch/kernel/s5p6818-default/03-patch-4.4.90-91.patch
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user