From: Greg Kroah-Hartman Date: Sat, 2 May 2015 14:21:17 +0000 (+0200) Subject: 3.14-stable patches X-Git-Tag: v3.10.77~41 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=58fc144e7cd7aadb3b00afcd51ddb9ebe62537e2;p=thirdparty%2Fkernel%2Fstable-queue.git 3.14-stable patches added patches: arm64-vdso-fix-build-error-when-switching-from-le-to-be.patch bfa-replace-large-udelay-with-mdelay.patch drm-msm-use-componentised-device-support.patch ext4-make-fsync-to-sync-parent-dir-in-no-journal-for-real-this-time.patch fs-binfmt_elf.c-fix-bug-in-loading-of-pie-binaries.patch input-elantech-fix-absolute-mode-setting-on-some-asus-laptops.patch ptrace-fix-race-between-ptrace_resume-and-wait_task_stopped.patch rtlwifi-rtl8192cu-add-new-device-id.patch rtlwifi-rtl8192cu-add-new-usb-id.patch --- diff --git a/queue-3.14/arm64-vdso-fix-build-error-when-switching-from-le-to-be.patch b/queue-3.14/arm64-vdso-fix-build-error-when-switching-from-le-to-be.patch new file mode 100644 index 00000000000..b48a6a390b1 --- /dev/null +++ b/queue-3.14/arm64-vdso-fix-build-error-when-switching-from-le-to-be.patch @@ -0,0 +1,45 @@ +From 1915e2ad1cf548217c963121e4076b3d44dd0169 Mon Sep 17 00:00:00 2001 +From: Arun Chandran +Date: Thu, 26 Jun 2014 15:16:03 +0530 +Subject: arm64: vdso: fix build error when switching from LE to BE + +From: Arun Chandran + +commit 1915e2ad1cf548217c963121e4076b3d44dd0169 upstream. + +Building a kernel with CPU_BIG_ENDIAN fails if there are stale objects +from a !CPU_BIG_ENDIAN build. Due to a missing FORCE prerequisite on an +if_changed rule in the VDSO Makefile, we attempt to link a stale LE +object into the new BE kernel. + +According to Documentation/kbuild/makefiles.txt, FORCE is required for +if_changed rules and forgetting it is a common mistake, so fix it by +'Forcing' the build of vdso. This patch fixes build errors like these: + +arch/arm64/kernel/vdso/note.o: compiled for a little endian system and target is big endian +failed to merge target specific data of file arch/arm64/kernel/vdso/note.o + +arch/arm64/kernel/vdso/sigreturn.o: compiled for a little endian system and target is big endian +failed to merge target specific data of file arch/arm64/kernel/vdso/sigreturn.o + +Tested-by: Mark Rutland +Signed-off-by: Arun Chandran +Signed-off-by: Will Deacon +Cc: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/kernel/vdso/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm64/kernel/vdso/Makefile ++++ b/arch/arm64/kernel/vdso/Makefile +@@ -43,7 +43,7 @@ $(obj)/vdso-offsets.h: $(obj)/vdso.so.db + $(call if_changed,vdsosym) + + # Assembly rules for the .S files +-$(obj-vdso): %.o: %.S ++$(obj-vdso): %.o: %.S FORCE + $(call if_changed_dep,vdsoas) + + # Actual build commands diff --git a/queue-3.14/bfa-replace-large-udelay-with-mdelay.patch b/queue-3.14/bfa-replace-large-udelay-with-mdelay.patch new file mode 100644 index 00000000000..c7eb16bd826 --- /dev/null +++ b/queue-3.14/bfa-replace-large-udelay-with-mdelay.patch @@ -0,0 +1,35 @@ +From b367dcaa512922e9207160bef0895622cfae4c9f Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Sun, 9 Mar 2014 04:04:18 +0000 +Subject: [SCSI] bfa: Replace large udelay() with mdelay() + +From: Ben Hutchings + +commit b367dcaa512922e9207160bef0895622cfae4c9f upstream. + +udelay() does not work on some architectures for values above +2000, in particular on ARM: + +ERROR: "__bad_udelay" [drivers/scsi/bfa/bfa.ko] undefined! + +Reported-by: Vagrant Cascadian +Signed-off-by: Ben Hutchings +Signed-off-by: James Bottomley +Cc: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/bfa/bfa_ioc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/scsi/bfa/bfa_ioc.c ++++ b/drivers/scsi/bfa/bfa_ioc.c +@@ -7006,7 +7006,7 @@ bfa_flash_sem_get(void __iomem *bar) + while (!bfa_raw_sem_get(bar)) { + if (--n <= 0) + return BFA_STATUS_BADFLASH; +- udelay(10000); ++ mdelay(10); + } + return BFA_STATUS_OK; + } diff --git a/queue-3.14/drm-msm-use-componentised-device-support.patch b/queue-3.14/drm-msm-use-componentised-device-support.patch new file mode 100644 index 00000000000..bec1e6ea0fe --- /dev/null +++ b/queue-3.14/drm-msm-use-componentised-device-support.patch @@ -0,0 +1,450 @@ +From 060530f1ea6740eb767085008d183f89ccdd289c Mon Sep 17 00:00:00 2001 +From: Rob Clark +Date: Mon, 3 Mar 2014 14:19:12 -0500 +Subject: drm/msm: use componentised device support + +From: Rob Clark + +commit 060530f1ea6740eb767085008d183f89ccdd289c upstream. + + +Signed-off-by: Rob Clark +[Guenter Roeck: backported to 3.14] +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman +--- +Please consider adding this patch to v3.14, to fix a build error +seen with arm:allmodconfig. + +Rob, it would be great if you can have a look to ensure that I did not miss +anything. + +Build results: + total: 125 pass: 125 fail: 0 + +Qemu test results: + total: 30 pass: 30 fail: 0 + + + drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 49 ++++++++++---- + drivers/gpu/drm/msm/hdmi/hdmi.c | 42 +++++++++--- + drivers/gpu/drm/msm/msm_drv.c | 112 ++++++++++++++++++++++++++++++++-- + drivers/gpu/drm/msm/msm_drv.h | 4 + + 4 files changed, 176 insertions(+), 31 deletions(-) + +--- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c ++++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c +@@ -35,8 +35,6 @@ + A3XX_INT0_CP_AHB_ERROR_HALT | \ + A3XX_INT0_UCHE_OOB_ACCESS) + +-static struct platform_device *a3xx_pdev; +- + static void a3xx_me_init(struct msm_gpu *gpu) + { + struct msm_ringbuffer *ring = gpu->rb; +@@ -311,7 +309,6 @@ static void a3xx_destroy(struct msm_gpu + ocmem_free(OCMEM_GRAPHICS, a3xx_gpu->ocmem_hdl); + #endif + +- put_device(&a3xx_gpu->pdev->dev); + kfree(a3xx_gpu); + } + +@@ -439,7 +436,8 @@ struct msm_gpu *a3xx_gpu_init(struct drm + struct a3xx_gpu *a3xx_gpu = NULL; + struct adreno_gpu *adreno_gpu; + struct msm_gpu *gpu; +- struct platform_device *pdev = a3xx_pdev; ++ struct msm_drm_private *priv = dev->dev_private; ++ struct platform_device *pdev = priv->gpu_pdev; + struct adreno_platform_config *config; + int ret; + +@@ -460,7 +458,6 @@ struct msm_gpu *a3xx_gpu_init(struct drm + adreno_gpu = &a3xx_gpu->base; + gpu = &adreno_gpu->base; + +- get_device(&pdev->dev); + a3xx_gpu->pdev = pdev; + + gpu->fast_rate = config->fast_rate; +@@ -522,17 +519,24 @@ fail: + # include + #endif + +-static int a3xx_probe(struct platform_device *pdev) ++static void set_gpu_pdev(struct drm_device *dev, ++ struct platform_device *pdev) ++{ ++ struct msm_drm_private *priv = dev->dev_private; ++ priv->gpu_pdev = pdev; ++} ++ ++static int a3xx_bind(struct device *dev, struct device *master, void *data) + { + static struct adreno_platform_config config = {}; + #ifdef CONFIG_OF +- struct device_node *child, *node = pdev->dev.of_node; ++ struct device_node *child, *node = dev->of_node; + u32 val; + int ret; + + ret = of_property_read_u32(node, "qcom,chipid", &val); + if (ret) { +- dev_err(&pdev->dev, "could not find chipid: %d\n", ret); ++ dev_err(dev, "could not find chipid: %d\n", ret); + return ret; + } + +@@ -548,7 +552,7 @@ static int a3xx_probe(struct platform_de + for_each_child_of_node(child, pwrlvl) { + ret = of_property_read_u32(pwrlvl, "qcom,gpu-freq", &val); + if (ret) { +- dev_err(&pdev->dev, "could not find gpu-freq: %d\n", ret); ++ dev_err(dev, "could not find gpu-freq: %d\n", ret); + return ret; + } + config.fast_rate = max(config.fast_rate, val); +@@ -558,12 +562,12 @@ static int a3xx_probe(struct platform_de + } + + if (!config.fast_rate) { +- dev_err(&pdev->dev, "could not find clk rates\n"); ++ dev_err(dev, "could not find clk rates\n"); + return -ENXIO; + } + + #else +- struct kgsl_device_platform_data *pdata = pdev->dev.platform_data; ++ struct kgsl_device_platform_data *pdata = dev->platform_data; + uint32_t version = socinfo_get_version(); + if (cpu_is_apq8064ab()) { + config.fast_rate = 450000000; +@@ -609,14 +613,30 @@ static int a3xx_probe(struct platform_de + config.bus_scale_table = pdata->bus_scale_table; + # endif + #endif +- pdev->dev.platform_data = &config; +- a3xx_pdev = pdev; ++ dev->platform_data = &config; ++ set_gpu_pdev(dev_get_drvdata(master), to_platform_device(dev)); + return 0; + } + ++static void a3xx_unbind(struct device *dev, struct device *master, ++ void *data) ++{ ++ set_gpu_pdev(dev_get_drvdata(master), NULL); ++} ++ ++static const struct component_ops a3xx_ops = { ++ .bind = a3xx_bind, ++ .unbind = a3xx_unbind, ++}; ++ ++static int a3xx_probe(struct platform_device *pdev) ++{ ++ return component_add(&pdev->dev, &a3xx_ops); ++} ++ + static int a3xx_remove(struct platform_device *pdev) + { +- a3xx_pdev = NULL; ++ component_del(&pdev->dev, &a3xx_ops); + return 0; + } + +@@ -624,7 +644,6 @@ static const struct of_device_id dt_matc + { .compatible = "qcom,kgsl-3d0" }, + {} + }; +-MODULE_DEVICE_TABLE(of, dt_match); + + static struct platform_driver a3xx_driver = { + .probe = a3xx_probe, +--- a/drivers/gpu/drm/msm/hdmi/hdmi.c ++++ b/drivers/gpu/drm/msm/hdmi/hdmi.c +@@ -17,8 +17,6 @@ + + #include "hdmi.h" + +-static struct platform_device *hdmi_pdev; +- + void hdmi_set_mode(struct hdmi *hdmi, bool power_on) + { + uint32_t ctrl = 0; +@@ -75,7 +73,7 @@ struct hdmi *hdmi_init(struct drm_device + { + struct hdmi *hdmi = NULL; + struct msm_drm_private *priv = dev->dev_private; +- struct platform_device *pdev = hdmi_pdev; ++ struct platform_device *pdev = priv->hdmi_pdev; + struct hdmi_platform_config *config; + int i, ret; + +@@ -95,8 +93,6 @@ struct hdmi *hdmi_init(struct drm_device + + kref_init(&hdmi->refcount); + +- get_device(&pdev->dev); +- + hdmi->dev = dev; + hdmi->pdev = pdev; + hdmi->config = config; +@@ -249,17 +245,24 @@ fail: + + #include + +-static int hdmi_dev_probe(struct platform_device *pdev) ++static void set_hdmi_pdev(struct drm_device *dev, ++ struct platform_device *pdev) ++{ ++ struct msm_drm_private *priv = dev->dev_private; ++ priv->hdmi_pdev = pdev; ++} ++ ++static int hdmi_bind(struct device *dev, struct device *master, void *data) + { + static struct hdmi_platform_config config = {}; + #ifdef CONFIG_OF +- struct device_node *of_node = pdev->dev.of_node; ++ struct device_node *of_node = dev->of_node; + + int get_gpio(const char *name) + { + int gpio = of_get_named_gpio(of_node, name, 0); + if (gpio < 0) { +- dev_err(&pdev->dev, "failed to get gpio: %s (%d)\n", ++ dev_err(dev, "failed to get gpio: %s (%d)\n", + name, gpio); + gpio = -1; + } +@@ -336,14 +339,30 @@ static int hdmi_dev_probe(struct platfor + config.mux_sel_gpio = -1; + } + #endif +- pdev->dev.platform_data = &config; +- hdmi_pdev = pdev; ++ dev->platform_data = &config; ++ set_hdmi_pdev(dev_get_drvdata(master), to_platform_device(dev)); + return 0; + } + ++static void hdmi_unbind(struct device *dev, struct device *master, ++ void *data) ++{ ++ set_hdmi_pdev(dev_get_drvdata(master), NULL); ++} ++ ++static const struct component_ops hdmi_ops = { ++ .bind = hdmi_bind, ++ .unbind = hdmi_unbind, ++}; ++ ++static int hdmi_dev_probe(struct platform_device *pdev) ++{ ++ return component_add(&pdev->dev, &hdmi_ops); ++} ++ + static int hdmi_dev_remove(struct platform_device *pdev) + { +- hdmi_pdev = NULL; ++ component_del(&pdev->dev, &hdmi_ops); + return 0; + } + +@@ -351,7 +370,6 @@ static const struct of_device_id dt_matc + { .compatible = "qcom,hdmi-tx" }, + {} + }; +-MODULE_DEVICE_TABLE(of, dt_match); + + static struct platform_driver hdmi_driver = { + .probe = hdmi_dev_probe, +--- a/drivers/gpu/drm/msm/msm_drv.c ++++ b/drivers/gpu/drm/msm/msm_drv.c +@@ -56,6 +56,10 @@ static char *vram; + MODULE_PARM_DESC(vram, "Configure VRAM size (for devices without IOMMU/GPUMMU"); + module_param(vram, charp, 0); + ++/* ++ * Util/helpers: ++ */ ++ + void __iomem *msm_ioremap(struct platform_device *pdev, const char *name, + const char *dbgname) + { +@@ -143,6 +147,8 @@ static int msm_unload(struct drm_device + priv->vram.paddr, &attrs); + } + ++ component_unbind_all(dev->dev, dev); ++ + dev->dev_private = NULL; + + kfree(priv); +@@ -175,6 +181,7 @@ static int msm_load(struct drm_device *d + struct msm_kms *kms; + int ret; + ++ + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) { + dev_err(dev->dev, "failed to allocate private data\n"); +@@ -226,6 +233,13 @@ static int msm_load(struct drm_device *d + (uint32_t)(priv->vram.paddr + size)); + } + ++ platform_set_drvdata(pdev, dev); ++ ++ /* Bind all our sub-components: */ ++ ret = component_bind_all(dev->dev, dev); ++ if (ret) ++ return ret; ++ + switch (get_mdp_ver(pdev)) { + case 4: + kms = mdp4_kms_init(dev); +@@ -281,8 +295,6 @@ static int msm_load(struct drm_device *d + goto fail; + } + +- platform_set_drvdata(pdev, dev); +- + #ifdef CONFIG_DRM_MSM_FBDEV + priv->fbdev = msm_fbdev_init(dev); + #endif +@@ -819,18 +831,110 @@ static const struct dev_pm_ops msm_pm_op + }; + + /* ++ * Componentized driver support: ++ */ ++ ++#ifdef CONFIG_OF ++/* NOTE: the CONFIG_OF case duplicates the same code as exynos or imx ++ * (or probably any other).. so probably some room for some helpers ++ */ ++static int compare_of(struct device *dev, void *data) ++{ ++ return dev->of_node == data; ++} ++ ++static int msm_drm_add_components(struct device *master, struct master *m) ++{ ++ struct device_node *np = master->of_node; ++ unsigned i; ++ int ret; ++ ++ for (i = 0; ; i++) { ++ struct device_node *node; ++ ++ node = of_parse_phandle(np, "connectors", i); ++ if (!node) ++ break; ++ ++ ret = component_master_add_child(m, compare_of, node); ++ of_node_put(node); ++ ++ if (ret) ++ return ret; ++ } ++ return 0; ++} ++#else ++static int compare_dev(struct device *dev, void *data) ++{ ++ return dev == data; ++} ++ ++static int msm_drm_add_components(struct device *master, struct master *m) ++{ ++ /* For non-DT case, it kinda sucks. We don't actually have a way ++ * to know whether or not we are waiting for certain devices (or if ++ * they are simply not present). But for non-DT we only need to ++ * care about apq8064/apq8060/etc (all mdp4/a3xx): ++ */ ++ static const char *devnames[] = { ++ "hdmi_msm.0", "kgsl-3d0.0", ++ }; ++ int i; ++ ++ DBG("Adding components.."); ++ ++ for (i = 0; i < ARRAY_SIZE(devnames); i++) { ++ struct device *dev; ++ int ret; ++ ++ dev = bus_find_device_by_name(&platform_bus_type, ++ NULL, devnames[i]); ++ if (!dev) { ++ dev_info(master, "still waiting for %s\n", devnames[i]); ++ return -EPROBE_DEFER; ++ } ++ ++ ret = component_master_add_child(m, compare_dev, dev); ++ if (ret) { ++ DBG("could not add child: %d", ret); ++ return ret; ++ } ++ } ++ ++ return 0; ++} ++#endif ++ ++static int msm_drm_bind(struct device *dev) ++{ ++ return drm_platform_init(&msm_driver, to_platform_device(dev)); ++} ++ ++static void msm_drm_unbind(struct device *dev) ++{ ++ drm_put_dev(platform_get_drvdata(to_platform_device(dev))); ++} ++ ++static const struct component_master_ops msm_drm_ops = { ++ .add_components = msm_drm_add_components, ++ .bind = msm_drm_bind, ++ .unbind = msm_drm_unbind, ++}; ++ ++/* + * Platform driver: + */ + + static int msm_pdev_probe(struct platform_device *pdev) + { + pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); +- return drm_platform_init(&msm_driver, pdev); ++ return component_master_add(&pdev->dev, &msm_drm_ops); + } + + static int msm_pdev_remove(struct platform_device *pdev) + { +- drm_put_dev(platform_get_drvdata(pdev)); ++ component_master_del(&pdev->dev, &msm_drm_ops); + + return 0; + } +--- a/drivers/gpu/drm/msm/msm_drv.h ++++ b/drivers/gpu/drm/msm/msm_drv.h +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -69,6 +70,9 @@ struct msm_drm_private { + + struct msm_kms *kms; + ++ /* subordinate devices, if present: */ ++ struct platform_device *hdmi_pdev, *gpu_pdev; ++ + /* when we have more than one 'msm_gpu' these need to be an array: */ + struct msm_gpu *gpu; + struct msm_file_private *lastctx; diff --git a/queue-3.14/ext4-make-fsync-to-sync-parent-dir-in-no-journal-for-real-this-time.patch b/queue-3.14/ext4-make-fsync-to-sync-parent-dir-in-no-journal-for-real-this-time.patch new file mode 100644 index 00000000000..adb52a6544d --- /dev/null +++ b/queue-3.14/ext4-make-fsync-to-sync-parent-dir-in-no-journal-for-real-this-time.patch @@ -0,0 +1,101 @@ +From e12fb97222fc41e8442896934f76d39ef99b590a Mon Sep 17 00:00:00 2001 +From: Lukas Czerner +Date: Fri, 3 Apr 2015 10:46:58 -0400 +Subject: ext4: make fsync to sync parent dir in no-journal for real this time + +From: Lukas Czerner + +commit e12fb97222fc41e8442896934f76d39ef99b590a upstream. + +Previously commit 14ece1028b3ed53ffec1b1213ffc6acaf79ad77c added a +support for for syncing parent directory of newly created inodes to +make sure that the inode is not lost after a power failure in +no-journal mode. + +However this does not work in majority of cases, namely: + - if the directory has inline data + - if the directory is already indexed + - if the directory already has at least one block and: + - the new entry fits into it + - or we've successfully converted it to indexed + +So in those cases we might lose the inode entirely even after fsync in +the no-journal mode. This also includes ext2 default mode obviously. + +I've noticed this while running xfstest generic/321 and even though the +test should fail (we need to run fsck after a crash in no-journal mode) +I could not find a newly created entries even when if it was fsynced +before. + +Fix this by adjusting the ext4_add_entry() successful exit paths to set +the inode EXT4_STATE_NEWENTRY so that fsync has the chance to fsync the +parent directory as well. + +Signed-off-by: Lukas Czerner +Signed-off-by: Theodore Ts'o +Reviewed-by: Jan Kara +Cc: Frank Mayhar +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/namei.c | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -1869,7 +1869,7 @@ static int ext4_add_entry(handle_t *hand + struct inode *inode) + { + struct inode *dir = dentry->d_parent->d_inode; +- struct buffer_head *bh; ++ struct buffer_head *bh = NULL; + struct ext4_dir_entry_2 *de; + struct ext4_dir_entry_tail *t; + struct super_block *sb; +@@ -1893,14 +1893,14 @@ static int ext4_add_entry(handle_t *hand + return retval; + if (retval == 1) { + retval = 0; +- return retval; ++ goto out; + } + } + + if (is_dx(dir)) { + retval = ext4_dx_add_entry(handle, dentry, inode); + if (!retval || (retval != ERR_BAD_DX_DIR)) +- return retval; ++ goto out; + ext4_clear_inode_flag(dir, EXT4_INODE_INDEX); + dx_fallback++; + ext4_mark_inode_dirty(handle, dir); +@@ -1912,14 +1912,15 @@ static int ext4_add_entry(handle_t *hand + return PTR_ERR(bh); + + retval = add_dirent_to_buf(handle, dentry, inode, NULL, bh); +- if (retval != -ENOSPC) { +- brelse(bh); +- return retval; +- } ++ if (retval != -ENOSPC) ++ goto out; + + if (blocks == 1 && !dx_fallback && +- EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) +- return make_indexed_dir(handle, dentry, inode, bh); ++ EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) { ++ retval = make_indexed_dir(handle, dentry, inode, bh); ++ bh = NULL; /* make_indexed_dir releases bh */ ++ goto out; ++ } + brelse(bh); + } + bh = ext4_append(handle, dir, &block); +@@ -1935,6 +1936,7 @@ static int ext4_add_entry(handle_t *hand + } + + retval = add_dirent_to_buf(handle, dentry, inode, de, bh); ++out: + brelse(bh); + if (retval == 0) + ext4_set_inode_state(inode, EXT4_STATE_NEWENTRY); diff --git a/queue-3.14/fs-binfmt_elf.c-fix-bug-in-loading-of-pie-binaries.patch b/queue-3.14/fs-binfmt_elf.c-fix-bug-in-loading-of-pie-binaries.patch new file mode 100644 index 00000000000..147735d7cbe --- /dev/null +++ b/queue-3.14/fs-binfmt_elf.c-fix-bug-in-loading-of-pie-binaries.patch @@ -0,0 +1,72 @@ +From a87938b2e246b81b4fb713edb371a9fa3c5c3c86 Mon Sep 17 00:00:00 2001 +From: Michael Davidson +Date: Tue, 14 Apr 2015 15:47:38 -0700 +Subject: fs/binfmt_elf.c: fix bug in loading of PIE binaries + +From: Michael Davidson + +commit a87938b2e246b81b4fb713edb371a9fa3c5c3c86 upstream. + +With CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE enabled, and a normal top-down +address allocation strategy, load_elf_binary() will attempt to map a PIE +binary into an address range immediately below mm->mmap_base. + +Unfortunately, load_elf_ binary() does not take account of the need to +allocate sufficient space for the entire binary which means that, while +the first PT_LOAD segment is mapped below mm->mmap_base, the subsequent +PT_LOAD segment(s) end up being mapped above mm->mmap_base into the are +that is supposed to be the "gap" between the stack and the binary. + +Since the size of the "gap" on x86_64 is only guaranteed to be 128MB this +means that binaries with large data segments > 128MB can end up mapping +part of their data segment over their stack resulting in corruption of the +stack (and the data segment once the binary starts to run). + +Any PIE binary with a data segment > 128MB is vulnerable to this although +address randomization means that the actual gap between the stack and the +end of the binary is normally greater than 128MB. The larger the data +segment of the binary the higher the probability of failure. + +Fix this by calculating the total size of the binary in the same way as +load_elf_interp(). + +Signed-off-by: Michael Davidson +Cc: Alexander Viro +Cc: Jiri Kosina +Cc: Kees Cook +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/binfmt_elf.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/fs/binfmt_elf.c ++++ b/fs/binfmt_elf.c +@@ -751,6 +751,7 @@ static int load_elf_binary(struct linux_ + i < loc->elf_ex.e_phnum; i++, elf_ppnt++) { + int elf_prot = 0, elf_flags; + unsigned long k, vaddr; ++ unsigned long total_size = 0; + + if (elf_ppnt->p_type != PT_LOAD) + continue; +@@ -815,10 +816,16 @@ static int load_elf_binary(struct linux_ + #else + load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr); + #endif ++ total_size = total_mapping_size(elf_phdata, ++ loc->elf_ex.e_phnum); ++ if (!total_size) { ++ error = -EINVAL; ++ goto out_free_dentry; ++ } + } + + error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, +- elf_prot, elf_flags, 0); ++ elf_prot, elf_flags, total_size); + if (BAD_ADDR(error)) { + send_sig(SIGKILL, current, 0); + retval = IS_ERR((void *)error) ? diff --git a/queue-3.14/input-elantech-fix-absolute-mode-setting-on-some-asus-laptops.patch b/queue-3.14/input-elantech-fix-absolute-mode-setting-on-some-asus-laptops.patch new file mode 100644 index 00000000000..6f2d0f8681f --- /dev/null +++ b/queue-3.14/input-elantech-fix-absolute-mode-setting-on-some-asus-laptops.patch @@ -0,0 +1,86 @@ +From bd884149aca61de269fd9bad83fe2a4232ffab21 Mon Sep 17 00:00:00 2001 +From: Ulrik De Bie +Date: Mon, 6 Apr 2015 15:35:38 -0700 +Subject: Input: elantech - fix absolute mode setting on some ASUS laptops + +From: Ulrik De Bie + +commit bd884149aca61de269fd9bad83fe2a4232ffab21 upstream. + +On ASUS TP500LN and X750JN, the touchpad absolute mode is reset each +time set_rate is done. + +In order to fix this, we will verify the firmware version, and if it +matches the one in those laptops, the set_rate function is overloaded +with a function elantech_set_rate_restore_reg_07 that performs the +set_rate with the original function, followed by a restore of reg_07 +(the register that sets the absolute mode on elantech v4 hardware). + +Also the ASUS TP500LN and X750JN firmware version, capabilities, and +button constellation is added to elantech.c + +Reported-and-tested-by: George Moutsopoulos +Signed-off-by: Ulrik De Bie +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/input/mouse/elantech.c | 22 ++++++++++++++++++++++ + drivers/input/mouse/elantech.h | 1 + + 2 files changed, 23 insertions(+) + +--- a/drivers/input/mouse/elantech.c ++++ b/drivers/input/mouse/elantech.c +@@ -814,6 +814,21 @@ static psmouse_ret_t elantech_process_by + } + + /* ++ * This writes the reg_07 value again to the hardware at the end of every ++ * set_rate call because the register loses its value. reg_07 allows setting ++ * absolute mode on v4 hardware ++ */ ++static void elantech_set_rate_restore_reg_07(struct psmouse *psmouse, ++ unsigned int rate) ++{ ++ struct elantech_data *etd = psmouse->private; ++ ++ etd->original_set_rate(psmouse, rate); ++ if (elantech_write_reg(psmouse, 0x07, etd->reg_07)) ++ psmouse_err(psmouse, "restoring reg_07 failed\n"); ++} ++ ++/* + * Put the touchpad into absolute mode + */ + static int elantech_set_absolute_mode(struct psmouse *psmouse) +@@ -1015,6 +1030,8 @@ static int elantech_get_resolution_v4(st + * Asus K53SV 0x450f01 78, 15, 0c 2 hw buttons + * Asus G46VW 0x460f02 00, 18, 0c 2 hw buttons + * Asus G750JX 0x360f00 00, 16, 0c 2 hw buttons ++ * Asus TP500LN 0x381f17 10, 14, 0e clickpad ++ * Asus X750JN 0x381f17 10, 14, 0e clickpad + * Asus UX31 0x361f00 20, 15, 0e clickpad + * Asus UX32VD 0x361f02 00, 15, 0e clickpad + * Avatar AVIU-145A2 0x361f00 ? clickpad +@@ -1490,6 +1507,11 @@ int elantech_init(struct psmouse *psmous + goto init_fail; + } + ++ if (etd->fw_version == 0x381f17) { ++ etd->original_set_rate = psmouse->set_rate; ++ psmouse->set_rate = elantech_set_rate_restore_reg_07; ++ } ++ + if (elantech_set_input_params(psmouse)) { + psmouse_err(psmouse, "failed to query touchpad range.\n"); + goto init_fail; +--- a/drivers/input/mouse/elantech.h ++++ b/drivers/input/mouse/elantech.h +@@ -139,6 +139,7 @@ struct elantech_data { + struct finger_pos mt[ETP_MAX_FINGERS]; + unsigned char parity[256]; + int (*send_cmd)(struct psmouse *psmouse, unsigned char c, unsigned char *param); ++ void (*original_set_rate)(struct psmouse *psmouse, unsigned int rate); + }; + + #ifdef CONFIG_MOUSE_PS2_ELANTECH diff --git a/queue-3.14/ptrace-fix-race-between-ptrace_resume-and-wait_task_stopped.patch b/queue-3.14/ptrace-fix-race-between-ptrace_resume-and-wait_task_stopped.patch new file mode 100644 index 00000000000..ad1a2f9c2fd --- /dev/null +++ b/queue-3.14/ptrace-fix-race-between-ptrace_resume-and-wait_task_stopped.patch @@ -0,0 +1,115 @@ +From b72c186999e689cb0b055ab1c7b3cd8fffbeb5ed Mon Sep 17 00:00:00 2001 +From: Oleg Nesterov +Date: Thu, 16 Apr 2015 12:47:29 -0700 +Subject: ptrace: fix race between ptrace_resume() and wait_task_stopped() + +From: Oleg Nesterov + +commit b72c186999e689cb0b055ab1c7b3cd8fffbeb5ed upstream. + +ptrace_resume() is called when the tracee is still __TASK_TRACED. We set +tracee->exit_code and then wake_up_state() changes tracee->state. If the +tracer's sub-thread does wait() in between, task_stopped_code(ptrace => T) +wrongly looks like another report from tracee. + +This confuses debugger, and since wait_task_stopped() clears ->exit_code +the tracee can miss a signal. + +Test-case: + + #include + #include + #include + #include + #include + #include + + int pid; + + void *waiter(void *arg) + { + int stat; + + for (;;) { + assert(pid == wait(&stat)); + assert(WIFSTOPPED(stat)); + if (WSTOPSIG(stat) == SIGHUP) + continue; + + assert(WSTOPSIG(stat) == SIGCONT); + printf("ERR! extra/wrong report:%x\n", stat); + } + } + + int main(void) + { + pthread_t thread; + + pid = fork(); + if (!pid) { + assert(ptrace(PTRACE_TRACEME, 0,0,0) == 0); + for (;;) + kill(getpid(), SIGHUP); + } + + assert(pthread_create(&thread, NULL, waiter, NULL) == 0); + + for (;;) + ptrace(PTRACE_CONT, pid, 0, SIGCONT); + + return 0; + } + +Note for stable: the bug is very old, but without 9899d11f6544 "ptrace: +ensure arch_ptrace/ptrace_request can never race with SIGKILL" the fix +should use lock_task_sighand(child). + +Signed-off-by: Oleg Nesterov +Reported-by: Pavel Labath +Tested-by: Pavel Labath +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/ptrace.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +--- a/kernel/ptrace.c ++++ b/kernel/ptrace.c +@@ -720,6 +720,8 @@ static int ptrace_peek_siginfo(struct ta + static int ptrace_resume(struct task_struct *child, long request, + unsigned long data) + { ++ bool need_siglock; ++ + if (!valid_signal(data)) + return -EIO; + +@@ -747,8 +749,26 @@ static int ptrace_resume(struct task_str + user_disable_single_step(child); + } + ++ /* ++ * Change ->exit_code and ->state under siglock to avoid the race ++ * with wait_task_stopped() in between; a non-zero ->exit_code will ++ * wrongly look like another report from tracee. ++ * ++ * Note that we need siglock even if ->exit_code == data and/or this ++ * status was not reported yet, the new status must not be cleared by ++ * wait_task_stopped() after resume. ++ * ++ * If data == 0 we do not care if wait_task_stopped() reports the old ++ * status and clears the code too; this can't race with the tracee, it ++ * takes siglock after resume. ++ */ ++ need_siglock = data && !thread_group_empty(current); ++ if (need_siglock) ++ spin_lock_irq(&child->sighand->siglock); + child->exit_code = data; + wake_up_state(child, __TASK_TRACED); ++ if (need_siglock) ++ spin_unlock_irq(&child->sighand->siglock); + + return 0; + } diff --git a/queue-3.14/rtlwifi-rtl8192cu-add-new-device-id.patch b/queue-3.14/rtlwifi-rtl8192cu-add-new-device-id.patch new file mode 100644 index 00000000000..9eece99c94e --- /dev/null +++ b/queue-3.14/rtlwifi-rtl8192cu-add-new-device-id.patch @@ -0,0 +1,33 @@ +From 9374e7d2fdcad3c36dafc8d3effd554bc702c4b6 Mon Sep 17 00:00:00 2001 +From: Marek Vasut +Date: Thu, 26 Mar 2015 02:16:06 +0100 +Subject: rtlwifi: rtl8192cu: Add new device ID + +From: Marek Vasut + +commit 9374e7d2fdcad3c36dafc8d3effd554bc702c4b6 upstream. + +Add new ID for ASUS N10 WiFi dongle. + +Signed-off-by: Marek Vasut +Tested-by: Marek Vasut +Cc: Larry Finger +Cc: John W. Linville +Acked-by: Larry Finger +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c ++++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +@@ -314,6 +314,7 @@ static struct usb_device_id rtl8192c_usb + {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ + {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ + {RTL_USB_DEVICE(0x0846, 0x9041, rtl92cu_hal_cfg)}, /*NetGear WNA1000M*/ ++ {RTL_USB_DEVICE(0x0b05, 0x17ba, rtl92cu_hal_cfg)}, /*ASUS-Edimax*/ + {RTL_USB_DEVICE(0x0bda, 0x5088, rtl92cu_hal_cfg)}, /*Thinkware-CC&C*/ + {RTL_USB_DEVICE(0x0df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ + {RTL_USB_DEVICE(0x0df6, 0x005c, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ diff --git a/queue-3.14/rtlwifi-rtl8192cu-add-new-usb-id.patch b/queue-3.14/rtlwifi-rtl8192cu-add-new-usb-id.patch new file mode 100644 index 00000000000..18573f331d0 --- /dev/null +++ b/queue-3.14/rtlwifi-rtl8192cu-add-new-usb-id.patch @@ -0,0 +1,29 @@ +From 2f92b314f4daff2117847ac5343c54d3d041bf78 Mon Sep 17 00:00:00 2001 +From: Larry Finger +Date: Mon, 23 Mar 2015 18:14:10 -0500 +Subject: rtlwifi: rtl8192cu: Add new USB ID + +From: Larry Finger + +commit 2f92b314f4daff2117847ac5343c54d3d041bf78 upstream. + +USB ID 2001:330d is used for a D-Link DWA-131. + +Signed-off-by: Larry Finger +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c ++++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +@@ -370,6 +370,7 @@ static struct usb_device_id rtl8192c_usb + {RTL_USB_DEVICE(0x2001, 0x3307, rtl92cu_hal_cfg)}, /*D-Link-Cameo*/ + {RTL_USB_DEVICE(0x2001, 0x3309, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/ + {RTL_USB_DEVICE(0x2001, 0x330a, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/ ++ {RTL_USB_DEVICE(0x2001, 0x330d, rtl92cu_hal_cfg)}, /*D-Link DWA-131 */ + {RTL_USB_DEVICE(0x2019, 0xab2b, rtl92cu_hal_cfg)}, /*Planex -Abocom*/ + {RTL_USB_DEVICE(0x20f4, 0x624d, rtl92cu_hal_cfg)}, /*TRENDNet*/ + {RTL_USB_DEVICE(0x2357, 0x0100, rtl92cu_hal_cfg)}, /*TP-Link WN8200ND*/ diff --git a/queue-3.14/series b/queue-3.14/series index c95d7f40ac4..63fae3213d1 100644 --- a/queue-3.14/series +++ b/queue-3.14/series @@ -37,3 +37,12 @@ usb-host-sl811-use-new-usb_resume_timeout.patch usb-dwc2-hcd-use-new-usb_resume_timeout.patch usb-core-hub-use-new-usb_resume_timeout.patch alsa-emu10k1-don-t-deadlock-in-proc-functions.patch +input-elantech-fix-absolute-mode-setting-on-some-asus-laptops.patch +fs-binfmt_elf.c-fix-bug-in-loading-of-pie-binaries.patch +ptrace-fix-race-between-ptrace_resume-and-wait_task_stopped.patch +rtlwifi-rtl8192cu-add-new-usb-id.patch +rtlwifi-rtl8192cu-add-new-device-id.patch +arm64-vdso-fix-build-error-when-switching-from-le-to-be.patch +bfa-replace-large-udelay-with-mdelay.patch +drm-msm-use-componentised-device-support.patch +ext4-make-fsync-to-sync-parent-dir-in-no-journal-for-real-this-time.patch