Merge branch 'lineage-16.0' of https://github.com/z3ntu/android_kernel_fairphone_msm8974 into lineage-16.0
Change-Id: Ie34580e6571b5e89476b76c6d461a3b2bb0db3f7
diff --git a/arch/arm/boot/dts/batterydata-Hip2440.dtsi b/arch/arm/boot/dts/batterydata-Hip2440.dtsi
new file mode 100644
index 0000000..ffb0827
--- /dev/null
+++ b/arch/arm/boot/dts/batterydata-Hip2440.dtsi
@@ -0,0 +1,97 @@
+qcom,Hip2440-batterydata {
+ qcom,battery-type = "Hip2440";
+ qcom,batt-id-kohm = <100>;
+ qcom,chg-term-ua = <100000>;
+ qcom,default-rbatt-mohm = <164>;
+ qcom,fcc-mah = <2440>;
+ qcom,max-voltage-uv = <4400000>;
+ qcom,rbatt-capacitive-mohm = <50>;
+ qcom,v-cutoff-uv = <3400000>;
+
+ qcom,fcc-temp-lut {
+ qcom,lut-col-legend = <(-20) 0 25 40 60>;
+ qcom,lut-data = <2506 2500 2498 2498 2494>;
+ };
+
+ qcom,pc-temp-ocv-lut {
+ qcom,lut-col-legend = <(-20) 0 25 40 60>;
+ qcom,lut-row-legend = <100 95 90 85 80>,
+ <75 70 65 60 55>,
+ <50 45 40 35 30>,
+ <25 20 16 13 11>,
+ <10 9 8 7 6>,
+ <5 4 3 2 1>,
+ <0>;
+ qcom,lut-data = <4390 4378 4372 4368 4360>,
+ <4256 4298 4303 4301 4295>,
+ <4176 4232 4243 4242 4236>,
+ <4108 4170 4184 4184 4178>,
+ <4058 4110 4128 4127 4123>,
+ <3974 4054 4073 4074 4070>,
+ <3926 3992 4021 4024 4020>,
+ <3884 3940 3968 3976 3974>,
+ <3848 3902 3920 3928 3928>,
+ <3818 3866 3879 3880 3880>,
+ <3798 3834 3847 3848 3846>,
+ <3778 3806 3821 3822 3820>,
+ <3760 3784 3800 3801 3799>,
+ <3741 3764 3780 3782 3780>,
+ <3719 3750 3764 3763 3758>,
+ <3695 3736 3749 3745 3733>,
+ <3666 3720 3731 3726 3712>,
+ <3642 3704 3712 3706 3692>,
+ <3622 3690 3695 3686 3673>,
+ <3607 3680 3687 3679 3667>,
+ <3598 3674 3685 3677 3666>,
+ <3586 3666 3682 3675 3663>,
+ <3572 3655 3680 3673 3661>,
+ <3556 3643 3675 3669 3656>,
+ <3538 3628 3667 3660 3646>,
+ <3516 3606 3648 3639 3616>,
+ <3487 3576 3608 3594 3570>,
+ <3450 3534 3550 3535 3508>,
+ <3396 3470 3469 3454 3422>,
+ <3300 3355 3342 3326 3291>,
+ <3000 3000 3000 3000 3000>;
+ };
+
+ qcom,rbatt-sf-lut {
+ qcom,lut-col-legend = <(-20) 0 25 40 60>;
+ qcom,lut-row-legend = <100 95 90 85 80>,
+ <75 70 65 60 55>,
+ <50 45 40 35 30>,
+ <25 20 16 13 11>,
+ <10 9 8 7 6>,
+ <5 4 3 2 1>;
+ qcom,lut-data = <1281 313 100 78 70>,
+ <1278 313 100 78 70>,
+ <1162 310 102 80 71>,
+ <1088 309 105 81 72>,
+ <1066 307 109 83 73>,
+ <985 305 112 85 74>,
+ <978 303 114 88 76>,
+ <985 304 113 90 79>,
+ <984 301 105 89 79>,
+ <986 301 101 80 73>,
+ <1006 301 100 79 71>,
+ <1034 302 101 79 73>,
+ <1070 304 101 80 73>,
+ <1113 306 101 80 73>,
+ <1164 310 101 79 73>,
+ <1212 317 101 79 71>,
+ <1254 330 102 79 72>,
+ <1302 343 102 79 73>,
+ <1387 351 101 79 71>,
+ <1436 353 101 79 71>,
+ <1502 359 102 80 74>,
+ <1672 366 104 82 75>,
+ <1840 376 107 84 79>,
+ <2078 386 110 87 82>,
+ <2396 401 115 90 83>,
+ <2841 419 114 88 76>,
+ <3449 446 110 84 77>,
+ <4402 490 110 84 77>,
+ <5980 578 116 88 80>,
+ <9369 896 146 122 161>;
+ };
+};
diff --git a/arch/arm/boot/dts/msm8974-mtp.dtsi b/arch/arm/boot/dts/msm8974-mtp.dtsi
index 1467da3..812bb59 100644
--- a/arch/arm/boot/dts/msm8974-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8974-mtp.dtsi
@@ -408,6 +408,7 @@
qcom,vref-batt-therm = <1800000>;
/include/ "batterydata-Hip2420.dtsi"
+ /include/ "batterydata-Hip2440.dtsi"
/include/ "batterydata-palladium.dtsi"
/include/ "batterydata-mtp-3000mah.dtsi"
};
diff --git a/arch/arm/configs/lineageos_FP2_defconfig b/arch/arm/configs/lineageos_FP2_defconfig
index 69015c3..30cda16 100644
--- a/arch/arm/configs/lineageos_FP2_defconfig
+++ b/arch/arm/configs/lineageos_FP2_defconfig
@@ -175,6 +175,10 @@
CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
CONFIG_SECCOMP_FILTER=y
+CONFIG_HAVE_ARCH_MMAP_RND_BITS=y
+CONFIG_ARCH_MMAP_RND_BITS_MIN=8
+CONFIG_ARCH_MMAP_RND_BITS_MAX=16
+CONFIG_ARCH_MMAP_RND_BITS=16
#
# GCOV-based kernel profiling
@@ -270,9 +274,6 @@
# System Type
#
CONFIG_MMU=y
-CONFIG_ARCH_MMAP_RND_BITS_MIN=8
-CONFIG_ARCH_MMAP_RND_BITS_MAX=16
-CONFIG_ARCH_MMAP_RND_BITS=8
# CONFIG_ARCH_INTEGRATOR is not set
# CONFIG_ARCH_REALVIEW is not set
# CONFIG_ARCH_VERSATILE is not set
@@ -479,7 +480,7 @@
# CONFIG_MSM_BUS_RPM_MULTI_TIER_ENABLED is not set
CONFIG_MSM_WATCHDOG_V2=y
CONFIG_MSM_MEMORY_DUMP=y
-CONFIG_MSM_DLOAD_MODE=y
+CONFIG_MSM_DLOAD_MODE=n
# CONFIG_MSM_JTAG is not set
# CONFIG_MSM_JTAG_MM is not set
# CONFIG_MSM_SLEEP_STATS_DEVICE is not set
@@ -608,6 +609,7 @@
# CONFIG_SCHED_SMT is not set
CONFIG_HAVE_ARM_SCU=y
CONFIG_ARM_ARCH_TIMER=y
+# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set
CONFIG_VMSPLIT_3G=y
# CONFIG_VMSPLIT_2G is not set
# CONFIG_VMSPLIT_1G is not set
@@ -802,7 +804,7 @@
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_INET_UDP_DIAG is not set
-# CONFIG_INET_DIAG_DESTROY is not set
+CONFIG_INET_DIAG_DESTROY=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -849,6 +851,7 @@
CONFIG_NF_CONNTRACK=y
CONFIG_NF_CONNTRACK_MARK=y
CONFIG_NF_CONNTRACK_SECMARK=y
+# CONFIG_NF_CONNTRACK_ZONES is not set
CONFIG_NF_CONNTRACK_PROCFS=y
CONFIG_NF_CONNTRACK_EVENTS=y
# CONFIG_NF_CONNTRACK_TIMEOUT is not set
@@ -887,7 +890,7 @@
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
-# CONFIG_NETFILTER_XT_TARGET_CT is not set
+CONFIG_NETFILTER_XT_TARGET_CT=y
# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
CONFIG_NETFILTER_XT_TARGET_HL=y
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
@@ -1322,7 +1325,6 @@
CONFIG_QSEECOM=y
# CONFIG_QFP_FUSE is not set
CONFIG_QPNP_MISC=y
-CONFIG_USB_HSIC_SMSC_HUB=y
CONFIG_TI_DRV2667=y
CONFIG_UID_CPUTIME=y
# CONFIG_TCMD_DRIVER is not set
@@ -2980,16 +2982,10 @@
CONFIG_USB_XHCI_PLATFORM=y
# CONFIG_USB_XHCI_HCD_DEBUGGING is not set
# CONFIG_USB_EHCI_HCD is not set
-# CONFIG_USB_EHCI_EHSET is not set
-# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
-# CONFIG_USB_EHCI_TT_NEWSCHED is not set
-# CONFIG_USB_EHCI_MSM is not set
-# CONFIG_USB_EHCI_MSM_HSIC is not set
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
# CONFIG_USB_ISP1362_HCD is not set
-# CONFIG_USB_EHCI_HCD_PLATFORM is not set
# CONFIG_USB_SL811_HCD is not set
# CONFIG_USB_R8A66597_HCD is not set
# CONFIG_USB_PEHCI_HCD is not set
@@ -3058,12 +3054,10 @@
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
-# CONFIG_USB_SISUSBVGA is not set
# CONFIG_USB_LD is not set
# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_IOWARRIOR is not set
# CONFIG_USB_TEST is not set
-CONFIG_USB_EHSET_TEST_FIXTURE=y
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_YUREX is not set
# CONFIG_USB_QCOM_DIAG_BRIDGE is not set
@@ -3467,8 +3461,13 @@
CONFIG_INOTIFY_USER=y
# CONFIG_FANOTIFY is not set
CONFIG_QUOTA=y
-CONFIG_QUOTACTL=y
+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
+CONFIG_PRINT_QUOTA_WARNING=y
+# CONFIG_QUOTA_DEBUG is not set
+CONFIG_QUOTA_TREE=y
+# CONFIG_QFMT_V1 is not set
CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
# CONFIG_AUTOFS4_FS is not set
CONFIG_FUSE_FS=y
# CONFIG_CUSE is not set
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index c8f46a6..ce9dd23 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -419,3 +419,5 @@
obj-$(CONFIG_WALL_CLK_SYSFS) += wallclk_sysfs.o
obj-$(CONFIG_ARCH_RANDOM) += early_random.o
obj-$(CONFIG_PERFMAP) += perfmap.o
+
+obj-y += msm_ddr_sysctl.o
diff --git a/arch/arm/mach-msm/include/mach/msm_smem.h b/arch/arm/mach-msm/include/mach/msm_smem.h
index 670efe6..683a359 100644
--- a/arch/arm/mach-msm/include/mach/msm_smem.h
+++ b/arch/arm/mach-msm/include/mach/msm_smem.h
@@ -108,6 +108,7 @@
SMEM_ID_VENDOR0,
SMEM_ID_VENDOR1,
SMEM_ID_VENDOR2,
+ SMEM_DDR_VENDOR_ID = SMEM_ID_VENDOR2, /* DDR vendor identifier written by SBL1 */
SMEM_HW_SW_BUILD_ID,
SMEM_SMD_BASE_ID_2,
SMEM_SMD_FIFO_BASE_ID_2 = SMEM_SMD_BASE_ID_2 +
diff --git a/arch/arm/mach-msm/msm_ddr_sysctl.c b/arch/arm/mach-msm/msm_ddr_sysctl.c
new file mode 100644
index 0000000..284118a
--- /dev/null
+++ b/arch/arm/mach-msm/msm_ddr_sysctl.c
@@ -0,0 +1,113 @@
+/* linux/arch/arm/mach-msm/msm_ddr_sysctl.c
+ *
+ * Copyright 2017-2018 Fairphone B.V.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/sysctl.h>
+#include <mach/msm_smem.h>
+#include "smem_private.h"
+
+
+/* DDR vendor identifiers (64-bits unsigned integer) */
+enum {
+ DDR_VENDOR_ID_INVALID = -1,
+ DDR_VENDOR_ID_SAMSUNG = 1,
+ DDR_VENDOR_ID_MICRON = 255,
+};
+
+/* Maximum DDR vendor name length */
+#define DDR_VENDOR_NAME_MAX_LEN 32
+
+/* DDR vendor names (shorter than DDR_VENDOR_NAME_MAX_LEN) */
+char *DDR_VENDOR_NAME_MICRON = "Micron";
+char *DDR_VENDOR_NAME_SAMSUNG = "Samsung";
+char *DDR_VENDOR_NAME_UNKNOWN = "Unknown";
+
+static char ddr_vendor[DDR_VENDOR_NAME_MAX_LEN] = "";
+
+static struct ctl_table_header *ddr_table_header;
+
+static ctl_table ddr_vendor_table[] = {
+ {
+ .procname = "vendor",
+ .data = ddr_vendor,
+ .maxlen = DDR_VENDOR_NAME_MAX_LEN,
+ .mode = 0444,
+ .proc_handler = proc_dostring,
+ },
+ {}
+};
+
+static ctl_table ddr_dir_table[] = {
+ {
+ .procname = "ddr",
+ .mode = 0555,
+ .child = ddr_vendor_table,
+ },
+ {}
+};
+
+static ctl_table dev_root_table[] = {
+ {
+ .procname = "dev",
+ .mode = 0555,
+ .child = ddr_dir_table,
+ },
+ {}
+};
+
+
+static int get_ddr_vendor_id_from_smem(void) {
+ unsigned int smem_size;
+ unsigned int *smem_ddr_vendor_id;
+
+ smem_ddr_vendor_id = smem_get_entry(SMEM_DDR_VENDOR_ID, &smem_size);
+ if (smem_ddr_vendor_id == NULL) {
+ printk("Could not get the DDR vendor identifier from SMEM\n");
+ return DDR_VENDOR_ID_INVALID;
+ }
+
+ return (int) *smem_ddr_vendor_id;
+}
+
+static int __init msm_ddr_init(void) {
+ switch (get_ddr_vendor_id_from_smem()) {
+ case DDR_VENDOR_ID_MICRON:
+ strncpy(ddr_vendor, DDR_VENDOR_NAME_MICRON, DDR_VENDOR_NAME_MAX_LEN);
+ break;
+ case DDR_VENDOR_ID_SAMSUNG:
+ strncpy(ddr_vendor, DDR_VENDOR_NAME_SAMSUNG, DDR_VENDOR_NAME_MAX_LEN);
+ break;
+ case DDR_VENDOR_ID_INVALID:
+ default:
+ strncpy(ddr_vendor, DDR_VENDOR_NAME_UNKNOWN, DDR_VENDOR_NAME_MAX_LEN);
+ break;
+ }
+ ddr_vendor[DDR_VENDOR_NAME_MAX_LEN-1] = '\0';
+
+ ddr_table_header = register_sysctl_table(dev_root_table);
+ if (!ddr_table_header)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void __exit msm_ddr_exit(void) {
+ unregister_sysctl_table(ddr_table_header);
+}
+
+module_init(msm_ddr_init);
+module_exit(msm_ddr_exit);
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("DDR information");
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c b/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
index 99a1863..e27d5e7 100644
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -21,6 +21,7 @@
#include <linux/uaccess.h>
#include <linux/time.h>
#include <linux/kmemleak.h>
+#include <linux/mutex.h>
#include <asm/mach-types.h>
#include <sound/apr_audio.h>
#include <mach/qdsp6v2/usf.h>
@@ -59,6 +60,9 @@
#define USF_MAX_BUF_SIZE 3145680
#define USF_MAX_BUF_NUM 32
+/* max size for buffer set from user space */
+#define USF_MAX_USER_BUF_SIZE 100000
+
/* Place for opreation result, received from QDSP6 */
#define APR_RESULT_IND 1
@@ -128,6 +132,8 @@
uint16_t conflicting_event_filters;
/* The requested buttons bitmap */
uint16_t req_buttons_bitmap;
+ /* Mutex for exclusive operations (all public APIs) */
+ struct mutex mutex;
};
struct usf_input_dev_type {
@@ -561,11 +567,6 @@
(void *)config->port_id,
min_map_size);
- if (rc) {
- pr_err("%s: ports offsets copy failure\n", __func__);
- return -EINVAL;
- }
-
usf_xx->encdec_cfg.format_id = config->stream_format;
usf_xx->encdec_cfg.params_size = config->params_data_size;
usf_xx->user_upd_info_na = 1; /* it's used in US_GET_TX_UPDATE */
@@ -833,6 +834,12 @@
return -EFAULT;
}
+ if (detect_info.params_data_size > USF_MAX_USER_BUF_SIZE) {
+ pr_err("%s: user buffer size exceeds maximum\n",
+ __func__);
+ return -EFAULT;
+ }
+
if (detect_info.us_detector != US_DETECT_FW) {
pr_err("%s: unsupported detector: %d\n",
__func__, detect_info.us_detector);
@@ -942,6 +949,12 @@
return -EFAULT;
}
+ if (config_tx.us_xx_info.params_data_size > USF_MAX_USER_BUF_SIZE) {
+ pr_err("%s: user buffer size exceeds maximum\n",
+ __func__);
+ return -EFAULT;
+ }
+
name = config_tx.us_xx_info.client_name;
usf_xx->new_region = USM_UNDEF_TOKEN;
@@ -1016,6 +1029,12 @@
return -EFAULT;
}
+ if (config_rx.us_xx_info.params_data_size > USF_MAX_USER_BUF_SIZE) {
+ pr_err("%s: user buffer size exceeds maximum\n",
+ __func__);
+ return -EFAULT;
+ }
+
usf_xx->new_region = USM_UNDEF_TOKEN;
usf_xx->prev_region = USM_UNDEF_TOKEN;
@@ -1295,9 +1314,22 @@
{
struct us_stream_param_type set_stream_param;
struct us_client *usc = usf_xx->usc;
- struct us_port_data *port = &usc->port[dir];
+ struct us_port_data *port;
int rc = 0;
+ if (usc == NULL) {
+ pr_err("%s: usc is null\n",
+ __func__);
+ return -EFAULT;
+ }
+
+ port = &usc->port[dir];
+ if (port == NULL) {
+ pr_err("%s: port is null\n",
+ __func__);
+ return -EFAULT;
+ }
+
if (port->param_buf == NULL) {
pr_err("%s: parameter buffer is null\n",
__func__);
@@ -1352,9 +1384,17 @@
{
struct us_stream_param_type get_stream_param;
struct us_client *usc = usf_xx->usc;
- struct us_port_data *port = &usc->port[dir];
+ struct us_port_data *port;
int rc = 0;
+ if (usc == NULL) {
+ pr_err("%s: us_client is null\n",
+ __func__);
+ return -EFAULT;
+ }
+
+ port = &usc->port[dir];
+
if (port->param_buf == NULL) {
pr_err("%s: parameter buffer is null\n",
__func__);
@@ -1404,10 +1444,12 @@
return rc;
} /* usf_get_stream_param */
-static long usf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+static long __usf_ioctl(struct usf_type *usf,
+ unsigned int cmd,
+ unsigned long arg)
{
+
int rc = 0;
- struct usf_type *usf = file->private_data;
struct usf_xx_type *usf_xx = NULL;
switch (cmd) {
@@ -1570,6 +1612,18 @@
release_xx(usf_xx);
return rc;
+} /* __usf_ioctl */
+
+static long usf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct usf_type *usf = file->private_data;
+ int rc = 0;
+
+ mutex_lock(&usf->mutex);
+ rc = __usf_ioctl(usf, cmd, arg);
+ mutex_unlock(&usf->mutex);
+
+ return rc;
} /* usf_ioctl */
static int usf_mmap(struct file *file, struct vm_area_struct *vms)
@@ -1577,13 +1631,17 @@
struct usf_type *usf = file->private_data;
int dir = OUT;
struct usf_xx_type *usf_xx = &usf->usf_tx;
+ int rc = 0;
+ mutex_lock(&usf->mutex);
if (vms->vm_flags & USF_VM_WRITE) { /* RX buf mapping */
dir = IN;
usf_xx = &usf->usf_rx;
}
+ rc = q6usm_get_virtual_address(dir, usf_xx->usc, vms);
+ mutex_unlock(&usf->mutex);
- return q6usm_get_virtual_address(dir, usf_xx->usc, vms);
+ return rc;
}
static uint16_t add_opened_dev(int minor)
@@ -1635,6 +1693,8 @@
usf->usf_tx.us_detect_type = USF_US_DETECT_UNDEF;
usf->usf_rx.us_detect_type = USF_US_DETECT_UNDEF;
+ mutex_init(&usf->mutex);
+
pr_debug("%s:usf in open\n", __func__);
return 0;
}
@@ -1645,6 +1705,7 @@
pr_debug("%s: release entry\n", __func__);
+ mutex_lock(&usf->mutex);
usf_release_input(usf);
usf_disable(&usf->usf_tx);
@@ -1652,6 +1713,8 @@
s_opened_devs[usf->dev_ind] = 0;
+ mutex_unlock(&usf->mutex);
+ mutex_destroy(&usf->mutex);
kfree(usf);
pr_debug("%s: release exit\n", __func__);
return 0;
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/version_a/q6usm_a.c b/arch/arm/mach-msm/qdsp6v2/ultrasound/version_a/q6usm_a.c
index 32ea025..ac034c6 100644
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/version_a/q6usm_a.c
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/version_a/q6usm_a.c
@@ -602,13 +602,13 @@
int rc = 0x00;
struct usm_stream_cmd_open_read open;
- pr_debug("%s: session[%d]", __func__, usc->session);
-
if ((usc == NULL) || (usc->apr == NULL)) {
pr_err("%s: client or its apr is NULL\n", __func__);
return -EINVAL;
}
+ pr_debug("%s: session[%d]", __func__, usc->session);
+
q6usm_add_hdr(usc, &open.hdr, sizeof(open), true);
open.hdr.opcode = USM_STREAM_CMD_OPEN_READ;
open.src_endpoint = 0; /* AFE */
@@ -848,13 +848,13 @@
uint32_t int_format = INVALID_FORMAT;
struct usm_stream_cmd_open_write open;
- pr_debug("%s: session[%d]", __func__, usc->session);
-
if ((usc == NULL) || (usc->apr == NULL)) {
pr_err("%s: APR handle NULL\n", __func__);
return -EINVAL;
}
+ pr_debug("%s: session[%d]", __func__, usc->session);
+
q6usm_add_hdr(usc, &open.hdr, sizeof(open), true);
open.hdr.opcode = USM_STREAM_CMD_OPEN_WRITE;
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/version_b/q6usm_b.c b/arch/arm/mach-msm/qdsp6v2/ultrasound/version_b/q6usm_b.c
index 0f2a623..64b0091 100644
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/version_b/q6usm_b.c
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/version_b/q6usm_b.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -768,13 +768,13 @@
int rc = 0x00;
struct usm_stream_cmd_open_read open;
- pr_debug("%s: session[%d]", __func__, usc->session);
-
if ((usc == NULL) || (usc->apr == NULL)) {
pr_err("%s: client or its apr is NULL\n", __func__);
return -EINVAL;
}
+ pr_debug("%s: session[%d]", __func__, usc->session);
+
q6usm_add_hdr(usc, &open.hdr, sizeof(open), true);
open.hdr.opcode = USM_STREAM_CMD_OPEN_READ;
open.src_endpoint = 0; /* AFE */
@@ -1015,13 +1015,13 @@
uint32_t int_format = INVALID_FORMAT;
struct usm_stream_cmd_open_write open;
- pr_debug("%s: session[%d]", __func__, usc->session);
-
if ((usc == NULL) || (usc->apr == NULL)) {
pr_err("%s: APR handle NULL\n", __func__);
return -EINVAL;
}
+ pr_debug("%s: session[%d]", __func__, usc->session);
+
q6usm_add_hdr(usc, &open.hdr, sizeof(open), true);
open.hdr.opcode = USM_STREAM_CMD_OPEN_WRITE;
diff --git a/drivers/gpu/ion/ion_system_heap.c b/drivers/gpu/ion/ion_system_heap.c
index b7ad01f..2d86180 100644
--- a/drivers/gpu/ion/ion_system_heap.c
+++ b/drivers/gpu/ion/ion_system_heap.c
@@ -455,8 +455,10 @@
{
int i;
for (i = 0; i < num_orders; i++)
- if (pools[i])
+ if (pools[i]) {
ion_page_pool_destroy(pools[i]);
+ pools[i] = NULL;
+ }
}
/**
diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
index 8310844..d31e4f2 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
@@ -797,6 +797,9 @@
struct msm_camera_cci_ctrl *cci_ctrl)
{
int32_t rc = 0;
+ struct cci_device *cci_dev = v4l2_get_subdevdata(sd);
+
+ mutex_lock(&cci_dev->mutex);
CDBG("%s line %d cmd %d\n", __func__, __LINE__,
cci_ctrl->cmd);
switch (cci_ctrl->cmd) {
@@ -820,6 +823,7 @@
}
CDBG("%s line %d rc %d\n", __func__, __LINE__, rc);
cci_ctrl->status = rc;
+ mutex_unlock(&cci_dev->mutex);
return rc;
}
@@ -1128,6 +1132,7 @@
CDBG("%s: no enough memory\n", __func__);
return -ENOMEM;
}
+ mutex_init(&new_cci_dev->mutex);
v4l2_subdev_init(&new_cci_dev->msm_sd.sd, &msm_cci_subdev_ops);
new_cci_dev->msm_sd.sd.internal_ops = &msm_cci_internal_ops;
snprintf(new_cci_dev->msm_sd.sd.name,
diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.h b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.h
index 283bd28..bbf94e1 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.h
+++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.h
@@ -129,6 +129,7 @@
uint32_t hw_version;
uint8_t ref_count;
+ struct mutex mutex;
enum msm_cci_state_t cci_state;
struct clk *cci_clk[CCI_NUM_CLK_MAX];
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index aa4ea4e..3529fc7 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -311,9 +311,8 @@
};
enum binder_deferred_state {
- BINDER_DEFERRED_PUT_FILES = 0x01,
- BINDER_DEFERRED_FLUSH = 0x02,
- BINDER_DEFERRED_RELEASE = 0x04,
+ BINDER_DEFERRED_FLUSH = 0x01,
+ BINDER_DEFERRED_RELEASE = 0x02,
};
struct binder_proc {
@@ -326,7 +325,6 @@
struct vm_area_struct *vma;
struct mm_struct *vma_vm_mm;
struct task_struct *tsk;
- struct files_struct *files;
struct hlist_node deferred_work_node;
int deferred_work;
void *buffer;
@@ -399,17 +397,23 @@
static void
binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer);
+static struct files_struct *binder_get_files_struct(struct binder_proc *proc)
+{
+ return get_files_struct(proc->tsk);
+}
+
/*
* copied from get_unused_fd_flags
*/
static int task_get_unused_fd_flags(struct binder_proc *proc, int flags)
{
- struct files_struct *files = proc->files;
+ struct files_struct *files;
int fd, error;
struct fdtable *fdt;
unsigned long rlim_cur;
unsigned long irqs;
+ files = binder_get_files_struct(proc);
if (files == NULL)
return -ESRCH;
@@ -463,6 +467,7 @@
out:
spin_unlock(&files->file_lock);
+ put_files_struct(files);
return error;
}
@@ -472,9 +477,10 @@
static void task_fd_install(
struct binder_proc *proc, unsigned int fd, struct file *file)
{
- struct files_struct *files = proc->files;
+ struct files_struct *files;
struct fdtable *fdt;
+ files = binder_get_files_struct(proc);
if (files == NULL)
return;
@@ -483,6 +489,7 @@
BUG_ON(fdt->fd[fd] != NULL);
rcu_assign_pointer(fdt->fd[fd], file);
spin_unlock(&files->file_lock);
+ put_files_struct(files);
}
/*
@@ -502,7 +509,7 @@
static long task_close_fd(struct binder_proc *proc, unsigned int fd)
{
struct file *filp;
- struct files_struct *files = proc->files;
+ struct files_struct *files = binder_get_files_struct(proc);
struct fdtable *fdt;
int retval;
@@ -528,11 +535,13 @@
retval == -ERESTARTNOHAND ||
retval == -ERESTART_RESTARTBLOCK))
retval = -EINTR;
+ put_files_struct(files);
return retval;
out_unlock:
spin_unlock(&files->file_lock);
+ put_files_struct(files);
return -EBADF;
}
@@ -3422,7 +3431,6 @@
(unsigned long)pgprot_val(vma->vm_page_prot));
proc->vma = NULL;
proc->vma_vm_mm = NULL;
- binder_defer_work(proc, BINDER_DEFERRED_PUT_FILES);
}
static int binder_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
@@ -3525,7 +3533,6 @@
binder_insert_free_buffer(proc, buffer);
proc->free_async_space = proc->buffer_size / 2;
barrier();
- proc->files = get_files_struct(current);
proc->vma = vma;
proc->vma_vm_mm = vma->vm_mm;
@@ -3656,7 +3663,6 @@
active_transactions, page_count;
BUG_ON(proc->vma);
- BUG_ON(proc->files);
hlist_del(&proc->proc_node);
@@ -3795,7 +3801,6 @@
static void binder_deferred_func(struct work_struct *work)
{
struct binder_proc *proc;
- struct files_struct *files;
int defer;
@@ -3814,13 +3819,6 @@
}
mutex_unlock(&binder_deferred_lock);
- files = NULL;
- if (defer & BINDER_DEFERRED_PUT_FILES) {
- files = proc->files;
- if (files)
- proc->files = NULL;
- }
-
if (defer & BINDER_DEFERRED_FLUSH)
binder_deferred_flush(proc);
@@ -3828,8 +3826,6 @@
binder_deferred_release(proc); /* frees proc */
binder_unlock(__func__);
- if (files)
- put_files_struct(files);
} while (proc);
}
static DECLARE_WORK(binder_deferred_work, binder_deferred_func);
diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg80211.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg80211.c
index d64f2eb..4181247 100644
--- a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -2132,6 +2132,8 @@
{ .type = NLA_U32 },
[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
{ .type = NLA_U32 },
+ [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] =
+ { .type = NLA_U32 },
[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
{ .type = NLA_U32 },
@@ -9035,15 +9037,24 @@
return -EINVAL;
}
+ if (CSR_MAX_RSC_LEN < params->seq_len)
+ {
+ hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
+ params->seq_len);
+
+ return -EINVAL;
+ }
+
hddLog(VOS_TRACE_LEVEL_INFO,
- "%s: called with key index = %d & key length %d",
- __func__, key_index, params->key_len);
+ "%s: called with key index = %d & key length %d & seq length %d",
+ __func__, key_index, params->key_len, params->seq_len);
/*extract key idx, key len and key*/
vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
setKey.keyId = key_index;
setKey.keyLength = params->key_len;
vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
+ vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
switch (params->cipher)
{
@@ -12692,6 +12703,12 @@
if ( NULL != ie )
{
pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
+ if (ie[1] < DOT11F_IE_WPA_MIN_LEN ||
+ ie[1] > DOT11F_IE_WPA_MAX_LEN) {
+ hddLog(VOS_TRACE_LEVEL_ERROR, "%s: invalid ie len:%d",
+ __func__, ie[1]);
+ return -EINVAL;
+ }
// Unpack the WPA IE
//Skip past the EID byte and length byte - and four byte WiFi OUI
dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
diff --git a/fs/dcache.c b/fs/dcache.c
index b9f0bb3..f74399f 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -271,6 +271,43 @@
dentry_free(dentry);
}
+void take_dentry_name_snapshot(struct name_snapshot *name, struct dentry *dentry)
+{
+ spin_lock(&dentry->d_lock);
+ if (unlikely(dname_external(dentry))) {
+ u32 len;
+ char *p;
+
+ for (;;) {
+ len = dentry->d_name.len;
+ spin_unlock(&dentry->d_lock);
+
+ p = kmalloc(len + 1, GFP_KERNEL | __GFP_NOFAIL);
+
+ spin_lock(&dentry->d_lock);
+ if (dentry->d_name.len <= len)
+ break;
+ kfree(p);
+ }
+ memcpy(p, dentry->d_name.name, dentry->d_name.len + 1);
+ spin_unlock(&dentry->d_lock);
+
+ name->name = p;
+ } else {
+ memcpy(name->inline_name, dentry->d_iname, DNAME_INLINE_LEN);
+ spin_unlock(&dentry->d_lock);
+ name->name = name->inline_name;
+ }
+}
+EXPORT_SYMBOL(take_dentry_name_snapshot);
+
+void release_dentry_name_snapshot(struct name_snapshot *name)
+{
+ if (unlikely(name->name != name->inline_name))
+ kfree(name->name);
+}
+EXPORT_SYMBOL(release_dentry_name_snapshot);
+
/**
* dentry_rcuwalk_barrier - invalidate in-progress rcu-walk lookups
* @dentry: the target dentry
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 00c9da5..72ab3b4 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -596,7 +596,7 @@
{
int error;
struct dentry *dentry = NULL, *trap;
- const char *old_name;
+ struct name_snapshot old_name;
trap = lock_rename(new_dir, old_dir);
/* Source or destination directories don't exist? */
@@ -611,19 +611,19 @@
if (IS_ERR(dentry) || dentry == trap || dentry->d_inode)
goto exit;
- old_name = fsnotify_oldname_init(old_dentry->d_name.name);
+ take_dentry_name_snapshot(&old_name, old_dentry);
error = simple_rename(old_dir->d_inode, old_dentry, new_dir->d_inode,
dentry);
if (error) {
- fsnotify_oldname_free(old_name);
+ release_dentry_name_snapshot(&old_name);
goto exit;
}
d_move(old_dentry, dentry);
- fsnotify_move(old_dir->d_inode, new_dir->d_inode, old_name,
+ fsnotify_move(old_dir->d_inode, new_dir->d_inode, old_name.name,
S_ISDIR(old_dentry->d_inode->i_mode),
NULL, old_dentry);
- fsnotify_oldname_free(old_name);
+ release_dentry_name_snapshot(&old_name);
unlock_rename(new_dir, old_dir);
dput(dentry);
return old_dentry;
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 58d5438..12d657d 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1388,6 +1388,12 @@
le32_to_cpu(raw_super->root_ino));
return 1;
}
+ if (le32_to_cpu(raw_super->segment_count) > F2FS_MAX_SEGMENT) {
+ f2fs_msg(sb, KERN_INFO,
+ "Invalid segment count (%u)",
+ le32_to_cpu(raw_super->segment_count));
+ return 1;
+ }
/* check CP/SIT/NAT/SSA/MAIN_AREA area boundary */
if (sanity_check_area_boundary(sbi, bh))
@@ -1402,6 +1408,8 @@
struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
+ unsigned int main_segs, blocks_per_seg;
+ int i;
total = le32_to_cpu(raw_super->segment_count);
fsmeta = le32_to_cpu(raw_super->segment_count_ckpt);
fsmeta += le32_to_cpu(raw_super->segment_count_sit);
@@ -1412,6 +1420,23 @@
if (unlikely(fsmeta >= total))
return 1;
+
+ main_segs = le32_to_cpu(sbi->raw_super->segment_count_main);
+ blocks_per_seg = sbi->blocks_per_seg;
+
+ for (i = 0; i < NR_CURSEG_NODE_TYPE; i++) {
+ if (le32_to_cpu(ckpt->cur_node_segno[i]) >= main_segs ||
+ le16_to_cpu(ckpt->cur_node_blkoff[i]) >= blocks_per_seg) {
+ return 1;
+ }
+ }
+ for (i = 0; i < NR_CURSEG_DATA_TYPE; i++) {
+ if (le32_to_cpu(ckpt->cur_data_segno[i]) >= main_segs ||
+ le16_to_cpu(ckpt->cur_data_blkoff[i]) >= blocks_per_seg) {
+ return 1;
+ }
+ }
+
if (unlikely(f2fs_cp_error(sbi))) {
f2fs_msg(sbi->sb, KERN_ERR, "A bug case: need to run fsck");
return 1;
diff --git a/fs/namei.c b/fs/namei.c
index 0bca3d0..909c01d 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3940,7 +3940,7 @@
{
int error;
int is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
- const unsigned char *old_name;
+ struct name_snapshot old_name;
if (old_dentry->d_inode == new_dentry->d_inode)
return 0;
@@ -3959,16 +3959,16 @@
if (!old_dir->i_op->rename)
return -EPERM;
- old_name = fsnotify_oldname_init(old_dentry->d_name.name);
+ take_dentry_name_snapshot(&old_name, old_dentry);
if (is_dir)
error = vfs_rename_dir(mnt, old_dir,old_dentry,new_dir,new_dentry);
else
error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
if (!error)
- fsnotify_move(old_dir, new_dir, old_name, is_dir,
+ fsnotify_move(old_dir, new_dir, old_name.name, is_dir,
new_dentry->d_inode, old_dentry);
- fsnotify_oldname_free(old_name);
+ release_dentry_name_snapshot(&old_name);
return error;
}
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index e5b6db6..6426f41 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -105,16 +105,20 @@
if (unlikely(!fsnotify_inode_watches_children(p_inode)))
__fsnotify_update_child_dentry_flags(p_inode);
else if (p_inode->i_fsnotify_mask & mask) {
+ struct name_snapshot name;
+
/* we are notifying a parent so come up with the new mask which
* specifies these are events which came from a child. */
mask |= FS_EVENT_ON_CHILD;
+ take_dentry_name_snapshot(&name, dentry);
if (path)
ret = fsnotify(p_inode, mask, path, FSNOTIFY_EVENT_PATH,
- dentry->d_name.name, 0);
+ name.name, 0);
else
ret = fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE,
- dentry->d_name.name, 0);
+ name.name, 0);
+ release_dentry_name_snapshot(&name);
}
dput(parent);
diff --git a/fs/proc/base.c b/fs/proc/base.c
index a8652a1..bf99be4 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -2377,11 +2377,19 @@
*/
static int proc_fd_permission(struct inode *inode, int mask)
{
- int rv = generic_permission(inode, mask);
+ struct task_struct *p;
+ int rv;
+
+ rv = generic_permission(inode, mask);
if (rv == 0)
- return 0;
- if (task_pid(current) == proc_pid(inode))
+ return rv;
+
+ rcu_read_lock();
+ p = pid_task(proc_pid(inode), PIDTYPE_PID);
+ if (p && same_thread_group(p, current))
rv = 0;
+ rcu_read_unlock();
+
return rv;
}
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 923d093..8b2d2f6 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -164,6 +164,80 @@
(typeof(ptr)) (__ptr + (off)); })
#endif
+#include <linux/types.h>
+
+static __always_inline void data_access_exceeds_word_size(void)
+#ifdef __compiletime_warning
+__compiletime_warning("data access exceeds word size and won't be atomic")
+#endif
+;
+
+static __always_inline void data_access_exceeds_word_size(void)
+{
+}
+
+static __always_inline void __read_once_size(const volatile void *p, void *res, int size)
+{
+ switch (size) {
+ case 1: *(__u8 *)res = *(volatile __u8 *)p; break;
+ case 2: *(__u16 *)res = *(volatile __u16 *)p; break;
+ case 4: *(__u32 *)res = *(volatile __u32 *)p; break;
+#ifdef CONFIG_64BIT
+ case 8: *(__u64 *)res = *(volatile __u64 *)p; break;
+#endif
+ default:
+ barrier();
+ __builtin_memcpy((void *)res, (const void *)p, size);
+ data_access_exceeds_word_size();
+ barrier();
+ }
+}
+
+static __always_inline void __write_once_size(volatile void *p, void *res, int size)
+{
+ switch (size) {
+ case 1: *(volatile __u8 *)p = *(__u8 *)res; break;
+ case 2: *(volatile __u16 *)p = *(__u16 *)res; break;
+ case 4: *(volatile __u32 *)p = *(__u32 *)res; break;
+#ifdef CONFIG_64BIT
+ case 8: *(volatile __u64 *)p = *(__u64 *)res; break;
+#endif
+ default:
+ barrier();
+ __builtin_memcpy((void *)p, (const void *)res, size);
+ data_access_exceeds_word_size();
+ barrier();
+ }
+}
+
+/*
+ * Prevent the compiler from merging or refetching reads or writes. The
+ * compiler is also forbidden from reordering successive instances of
+ * READ_ONCE, WRITE_ONCE and ACCESS_ONCE (see below), but only when the
+ * compiler is aware of some particular ordering. One way to make the
+ * compiler aware of ordering is to put the two invocations of READ_ONCE,
+ * WRITE_ONCE or ACCESS_ONCE() in different C statements.
+ *
+ * In contrast to ACCESS_ONCE these two macros will also work on aggregate
+ * data types like structs or unions. If the size of the accessed data
+ * type exceeds the word size of the machine (e.g., 32 bits or 64 bits)
+ * READ_ONCE() and WRITE_ONCE() will fall back to memcpy and print a
+ * compile-time warning.
+ *
+ * Their two major use cases are: (1) Mediating communication between
+ * process-level code and irq/NMI handlers, all running on the same CPU,
+ * and (2) Ensuring that the compiler does not fold, spindle, or otherwise
+ * mutilate accesses that either do not require ordering or that interact
+ * with an explicit memory barrier or atomic instruction that provides the
+ * required ordering.
+ */
+
+#define READ_ONCE(x) \
+ ({ union { typeof(x) __val; char __c[1]; } __u; __read_once_size(&(x), __u.__c, sizeof(x)); __u.__val; })
+
+#define WRITE_ONCE(x, val) \
+ ({ typeof(x) __val = (val); __write_once_size(&(x), &__val, sizeof(__val)); __val; })
+
#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 2927089..a39ee4b 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -429,4 +429,11 @@
extern int sysctl_vfs_cache_pressure;
+struct name_snapshot {
+ const char *name;
+ char inline_name[DNAME_INLINE_LEN];
+};
+void take_dentry_name_snapshot(struct name_snapshot *, struct dentry *);
+void release_dentry_name_snapshot(struct name_snapshot *);
+
#endif /* __LINUX_DCACHE_H */
diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
index 1a1d318..e020cbf 100644
--- a/include/linux/f2fs_fs.h
+++ b/include/linux/f2fs_fs.h
@@ -289,6 +289,12 @@
#define SIT_ENTRY_PER_BLOCK (PAGE_CACHE_SIZE / sizeof(struct f2fs_sit_entry))
/*
+ * F2FS uses 4 bytes to represent block address. As a result, supported size of
+ * disk is 16 TB and it equals to 16 * 1024 * 1024 / 2 segments.
+ */
+#define F2FS_MAX_SEGMENT ((16 * 1024 * 1024) / 2)
+
+/*
* Note that f2fs_sit_entry->vblocks has the following bit-field information.
* [15:10] : allocation type such as CURSEG_XXXX_TYPE
* [9:0] : valid block count
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h
index f0d1955..f4befd6 100644
--- a/include/linux/fsnotify.h
+++ b/include/linux/fsnotify.h
@@ -315,35 +315,4 @@
}
}
-#if defined(CONFIG_FSNOTIFY) /* notify helpers */
-
-/*
- * fsnotify_oldname_init - save off the old filename before we change it
- */
-static inline const unsigned char *fsnotify_oldname_init(const unsigned char *name)
-{
- return kstrdup(name, GFP_KERNEL);
-}
-
-/*
- * fsnotify_oldname_free - free the name we got from fsnotify_oldname_init
- */
-static inline void fsnotify_oldname_free(const unsigned char *old_name)
-{
- kfree(old_name);
-}
-
-#else /* CONFIG_FSNOTIFY */
-
-static inline const char *fsnotify_oldname_init(const unsigned char *name)
-{
- return NULL;
-}
-
-static inline void fsnotify_oldname_free(const unsigned char *old_name)
-{
-}
-
-#endif /* CONFIG_FSNOTIFY */
-
#endif /* _LINUX_FS_NOTIFY_H */
diff --git a/kernel/signal.c b/kernel/signal.c
index 111226e..a9da8ac 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2938,7 +2938,8 @@
/* Not even root can pretend to send signals from the kernel.
* Nor can they impersonate a kill()/tgkill(), which adds source info.
*/
- if (info.si_code >= 0 || info.si_code == SI_TKILL) {
+ if ((info.si_code >= 0 || info.si_code == SI_TKILL) &&
+ (task_pid_vnr(current) != pid)) {
/* We used to allow any < 0 si_code */
WARN_ON_ONCE(info.si_code < 0);
return -EPERM;
@@ -2958,7 +2959,8 @@
/* Not even root can pretend to send signals from the kernel.
* Nor can they impersonate a kill()/tgkill(), which adds source info.
*/
- if (info->si_code >= 0 || info->si_code == SI_TKILL) {
+ if ((info->si_code >= 0 || info->si_code == SI_TKILL) &&
+ (task_pid_vnr(current) != pid)) {
/* We used to allow any < 0 si_code */
WARN_ON_ONCE(info->si_code < 0);
return -EPERM;