linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/26] bring back stack frame warning with KASAN
@ 2017-03-02 16:38 Arnd Bergmann
  2017-03-02 16:38 ` [PATCH 01/26] compiler: introduce noinline_for_kasan annotation Arnd Bergmann
                   ` (26 more replies)
  0 siblings, 27 replies; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller

It took a long while to get this done, but I'm finally ready
to send the first half of the KASAN stack size patches that
I did in response to the kernelci.org warnings.

As before, it's worth mentioning that things are generally worse
with gcc-7.0.1 because of the addition of -fsanitize-address-use-after-scope
that are not present on kernelci, so my randconfig testing found
a lot more than kernelci did.

The main areas are:

- READ_ONCE/WRITE_ONCE cause problems in lots of code
- typecheck() causes huge problems in a few places
- I'm introducing "noinline_for_kasan" and use it in a lot
  of places that suffer from inline functions with local variables
  - netlink, as used in various parts of the kernel
  - a number of drivers/media drivers
  - a handful of wireless network drivers
- kmemcheck conflicts with -fsanitize-address-use-after-scope

This series lets us add back a stack frame warning for 3072 bytes
with -fsanitize-address-use-after-scope, or 2048 bytes without it.

I have a follow-up series that further reduces the stack frame
warning limit to 1280 bytes for all 64-bit architectures, and
1536 bytes with basic KASAN support (no -fsanitize-address-use-after-scope).
For now, I'm only posting the first half, in order to keep
it (barely) reviewable.

Both series are tested with many hundred randconfig builds on both
x86 and arm64, which are the only architectures supporting KASAN.

	Arnd 

 [PATCH 01/26] compiler: introduce noinline_for_kasan annotation
 [PATCH 02/26] rewrite READ_ONCE/WRITE_ONCE
 [PATCH 03/26] typecheck.h: avoid local variables in typecheck() macro
 [PATCH 04/26] tty: kbd: reduce stack size with KASAN
 [PATCH 05/26] netlink: mark nla_put_{u8,u16,u32} noinline_for_kasan
 [PATCH 06/26] rocker: mark rocker_tlv_put_* functions as
 [PATCH 07/26] brcmsmac: reduce stack size with KASAN
 [PATCH 08/26] brcmsmac: make some local variables 'static const' to
 [PATCH 09/26] brcmsmac: split up wlc_phy_workarounds_nphy
 [PATCH 10/26] brcmsmac: reindent split functions
 [PATCH 11/26] rtlwifi: reduce stack usage for KASAN
 [PATCH 12/26] wl3501_cs: reduce stack size for KASAN
 [PATCH 13/26] rtl8180: reduce stack size for KASAN
 [PATCH 14/26] [media] dvb-frontends: reduce stack size in i2c access
 [PATCH 15/26] [media] tuners: i2c: reduce stack usage for
 [PATCH 16/26] [media] i2c: adv7604: mark register access as
 [PATCH 17/26] [media] i2c: ks0127: reduce stack frame size for KASAN
 [PATCH 18/26] [media] i2c: cx25840: avoid stack overflow with KASAN
 [PATCH 19/26] [media] r820t: mark register functions as
 [PATCH 20/26] [media] em28xx: split up em28xx_dvb_init to reduce
 [PATCH 21/26] drm/bridge: ps8622: reduce stack size for KASAN
 [PATCH 22/26] drm/i915/gvt: don't overflow the kernel stack with
 [PATCH 23/26] mtd: cfi: reduce stack size with KASAN
 [PATCH 24/26] ocfs2: reduce stack size with KASAN
 [PATCH 25/26] isdn: eicon: mark divascapi incompatible with kasan
 [PATCH 26/26] kasan: rework Kconfig settings

 arch/x86/include/asm/switch_to.h                                 |    2 +-
 drivers/gpu/drm/bridge/parade-ps8622.c                           |    2 +-
 drivers/gpu/drm/i915/gvt/mmio.h                                  |   17 +-
 drivers/isdn/hardware/eicon/Kconfig                              |    1 +
 drivers/media/dvb-frontends/ascot2e.c                            |    3 +-
 drivers/media/dvb-frontends/cxd2841er.c                          |    4 +-
 drivers/media/dvb-frontends/drx39xyj/drxj.c                      |   14 +-
 drivers/media/dvb-frontends/helene.c                             |    4 +-
 drivers/media/dvb-frontends/horus3a.c                            |    2 +-
 drivers/media/dvb-frontends/itd1000.c                            |    2 +-
 drivers/media/dvb-frontends/mt312.c                              |    2 +-
 drivers/media/dvb-frontends/si2165.c                             |   14 +-
 drivers/media/dvb-frontends/stb0899_drv.c                        |    2 +-
 drivers/media/dvb-frontends/stb6100.c                            |    2 +-
 drivers/media/dvb-frontends/stv0367.c                            |    2 +-
 drivers/media/dvb-frontends/stv090x.c                            |    2 +-
 drivers/media/dvb-frontends/stv6110.c                            |    2 +-
 drivers/media/dvb-frontends/stv6110x.c                           |    2 +-
 drivers/media/dvb-frontends/tda8083.c                            |    2 +-
 drivers/media/dvb-frontends/zl10039.c                            |    2 +-
 drivers/media/i2c/adv7604.c                                      |    4 +-
 drivers/media/i2c/cx25840/cx25840-core.c                         |    4 +-
 drivers/media/i2c/ks0127.c                                       |    2 +-
 drivers/media/tuners/r820t.c                                     |    4 +-
 drivers/media/tuners/tuner-i2c.h                                 |   15 +-
 drivers/media/usb/em28xx/em28xx-dvb.c                            |  947 +++++++++++++++++++++------------------
 drivers/mtd/chips/cfi_cmdset_0020.c                              |    8 +-
 drivers/net/ethernet/rocker/rocker_tlv.h                         |   24 +-
 drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c     | 1860 +++++++++++++++++++++++++++++++++++++----------------------------------------
 drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225se.c         |    4 +-
 drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8192e2ant.c |   41 +-
 drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c |   26 +-
 drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.c |   34 +-
 drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c |   36 +-
 drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a2ant.c |   38 +-
 drivers/net/wireless/wl3501_cs.c                                 |   10 +-
 drivers/tty/vt/keyboard.c                                        |    6 +-
 fs/ocfs2/cluster/masklog.c                                       |   10 +-
 fs/ocfs2/cluster/masklog.h                                       |    4 +-
 fs/overlayfs/util.c                                              |    6 +-
 include/linux/compiler.h                                         |   58 ++-
 include/linux/mtd/map.h                                          |    8 +-
 include/linux/typecheck.h                                        |    7 +-
 include/net/netlink.h                                            |   36 +-
 lib/Kconfig.debug                                                |    9 +-
 lib/Kconfig.kasan                                                |   11 +-
 lib/Kconfig.kmemcheck                                            |    1 +
 scripts/Makefile.kasan                                           |    3 +
 48 files changed, 1670 insertions(+), 1629 deletions(-)

^ permalink raw reply	[flat|nested] 67+ messages in thread

* [PATCH 01/26] compiler: introduce noinline_for_kasan annotation
  2017-03-02 16:38 [PATCH 00/26] bring back stack frame warning with KASAN Arnd Bergmann
@ 2017-03-02 16:38 ` Arnd Bergmann
  2017-03-03 13:50   ` Andrey Ryabinin
  2017-03-02 16:38 ` [PATCH 02/26] rewrite READ_ONCE/WRITE_ONCE Arnd Bergmann
                   ` (25 subsequent siblings)
  26 siblings, 1 reply; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann

When CONFIG_KASAN is set, we can run into some code that uses incredible
amounts of kernel stack:

drivers/staging/dgnc/dgnc_neo.c:1056:1: error: the frame size of 11112 bytes is larger than 2048 bytes [-Werror=frame-larger-than=]
drivers/media/i2c/cx25840/cx25840-core.c:4960:1: error: the frame size of 94000 bytes is larger than 2048 bytes [-Werror=frame-larger-than=]
drivers/media/dvb-frontends/stv090x.c:3430:1: error: the frame size of 5312 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]

This happens when a sanitizer uses stack memory each time an inline function
gets called. This introduces a new annotation for those functions to make
them either 'inline' or 'noinline' dependning on the CONFIG_KASAN symbol.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 include/linux/compiler.h | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index f8110051188f..56b90897a459 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -416,6 +416,17 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
  */
 #define noinline_for_stack noinline
 
+/*
+ * CONFIG_KASAN can lead to extreme stack usage with certain patterns when
+ * one function gets inlined many times and each instance requires a stack
+ * ckeck.
+ */
+#ifdef CONFIG_KASAN
+#define noinline_for_kasan noinline __maybe_unused
+#else
+#define noinline_for_kasan inline
+#endif
+
 #ifndef __always_inline
 #define __always_inline inline
 #endif
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 02/26] rewrite READ_ONCE/WRITE_ONCE
  2017-03-02 16:38 [PATCH 00/26] bring back stack frame warning with KASAN Arnd Bergmann
  2017-03-02 16:38 ` [PATCH 01/26] compiler: introduce noinline_for_kasan annotation Arnd Bergmann
@ 2017-03-02 16:38 ` Arnd Bergmann
  2017-03-02 16:51   ` Christian Borntraeger
  2017-03-02 16:38 ` [PATCH 03/26] typecheck.h: avoid local variables in typecheck() macro Arnd Bergmann
                   ` (24 subsequent siblings)
  26 siblings, 1 reply; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann, Christian Borntraeger,
	Paul McKenney

When CONFIG_KASAN is enabled, the READ_ONCE/WRITE_ONCE macros cause
rather large kernel stacks, e.g.:

mm/vmscan.c: In function 'shrink_page_list':
mm/vmscan.c:1333:1: error: the frame size of 3456 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
block/cfq-iosched.c: In function 'cfqg_stats_add_aux':
block/cfq-iosched.c:750:1: error: the frame size of 4048 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
fs/btrfs/disk-io.c: In function 'open_ctree':
fs/btrfs/disk-io.c:3314:1: error: the frame size of 3136 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
fs/btrfs/relocation.c: In function 'build_backref_tree':
fs/btrfs/relocation.c:1193:1: error: the frame size of 4336 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
fs/fscache/stats.c: In function 'fscache_stats_show':
fs/fscache/stats.c:287:1: error: the frame size of 6512 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
fs/jbd2/commit.c: In function 'jbd2_journal_commit_transaction':
fs/jbd2/commit.c:1139:1: error: the frame size of 3760 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]

This attempts a rewrite of the two macros, using a simpler implementation
for the most common case of having a naturally aligned 1, 2, 4, or (on
64-bit architectures) 8  byte object that can be accessed with a single
instruction.  For these, we go back to a volatile pointer dereference
that we had with the ACCESS_ONCE macro.

READ_ONCE/WRITE_ONCE also try to handle unaligned objects and objects
of other sizes by forcing either a word-size access (which may trap
on some architectures) or doing a non-atomic memcpy. I could not figure
out what these are actually used for, but they appear to be done
intentionally, so I'm leaving that code untouched.

I had to fix up a couple of files that either use WRITE_ONCE() as an
implicit typecast, or ignore the result of READ_ONCE(). In all cases,
the modified code seems no worse to me than the original.

Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Paul McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/x86/include/asm/switch_to.h |  2 +-
 fs/overlayfs/util.c              |  6 ++---
 include/linux/compiler.h         | 47 ++++++++++++++++++++++++++++++++--------
 3 files changed, 42 insertions(+), 13 deletions(-)

diff --git a/arch/x86/include/asm/switch_to.h b/arch/x86/include/asm/switch_to.h
index fcc5cd387fd1..0c243dd569fe 100644
--- a/arch/x86/include/asm/switch_to.h
+++ b/arch/x86/include/asm/switch_to.h
@@ -30,7 +30,7 @@ static inline void prepare_switch_to(struct task_struct *prev,
 	 *
 	 * To minimize cache pollution, just follow the stack pointer.
 	 */
-	READ_ONCE(*(unsigned char *)next->thread.sp);
+	(void)READ_ONCE(*(unsigned char *)next->thread.sp);
 #endif
 }
 
diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
index 952286f4826c..1c10632a48bb 100644
--- a/fs/overlayfs/util.c
+++ b/fs/overlayfs/util.c
@@ -222,8 +222,8 @@ void ovl_dentry_update(struct dentry *dentry, struct dentry *upperdentry)
 
 void ovl_inode_init(struct inode *inode, struct inode *realinode, bool is_upper)
 {
-	WRITE_ONCE(inode->i_private, (unsigned long) realinode |
-		   (is_upper ? OVL_ISUPPER_MASK : 0));
+	WRITE_ONCE(inode->i_private, (void *)((unsigned long) realinode |
+		   (is_upper ? OVL_ISUPPER_MASK : 0)));
 }
 
 void ovl_inode_update(struct inode *inode, struct inode *upperinode)
@@ -231,7 +231,7 @@ void ovl_inode_update(struct inode *inode, struct inode *upperinode)
 	WARN_ON(!upperinode);
 	WARN_ON(!inode_unhashed(inode));
 	WRITE_ONCE(inode->i_private,
-		   (unsigned long) upperinode | OVL_ISUPPER_MASK);
+		   (void *)((unsigned long) upperinode | OVL_ISUPPER_MASK));
 	if (!S_ISDIR(upperinode->i_mode))
 		__insert_inode_hash(inode, (unsigned long) upperinode);
 }
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 56b90897a459..b619f5853af8 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -288,6 +288,10 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
 	}
 }
 
+#define __ALIGNED_WORD(x)						\
+	((sizeof(x) == 1 || sizeof(x) == 2 || sizeof(x) == 4 ||		\
+	  sizeof(x) == sizeof(long)) && (sizeof(x) == __alignof__(x)))	\
+
 /*
  * Prevent the compiler from merging or refetching reads or writes. The
  * compiler is also forbidden from reordering successive instances of
@@ -309,8 +313,13 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
  * mutilate accesses that either do not require ordering or that interact
  * with an explicit memory barrier or atomic instruction that provides the
  * required ordering.
+ *
+ * Unaligned data is particularly tricky here: if the type that gets
+ * passed in is not naturally aligned, we cast to a type of higher
+ * alignment, which is not well-defined in C. This is fine as long
+ * as the actual data is aligned, but otherwise might require a trap
+ * to satisfy the load.
  */
-
 #define __READ_ONCE(x, check)						\
 ({									\
 	union { typeof(x) __val; char __c[1]; } __u;			\
@@ -320,7 +329,32 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
 		__read_once_size_nocheck(&(x), __u.__c, sizeof(x));	\
 	__u.__val;							\
 })
-#define READ_ONCE(x) __READ_ONCE(x, 1)
+
+#define __WRITE_ONCE(x, val)						\
+({									\
+	union { typeof(x) __val; char __c[1]; } __u =			\
+		{ .__val = (__force typeof(x)) (val) };			\
+	__write_once_size(&(x), __u.__c, sizeof(x));			\
+	__u.__val;							\
+})
+
+
+/*
+ * the common case is simple: x is naturally aligned, not an array,
+ * and accessible with a single load, avoiding the need for local
+ * variables. With KASAN, this is important as any call to
+ *__write_once_size(),__read_once_size_nocheck() or __read_once_size()
+ * uses significant amounts of stack space for checking that we don't
+ * overflow the union.
+ */
+#define __READ_ONCE_SIMPLE(x)						\
+	(typeof(x))(*(volatile typeof(&(x)))&(x))
+
+#define __WRITE_ONCE_SIMPLE(x, val)					\
+	({*(volatile typeof(&(x)))&(x) = (val); })
+
+#define READ_ONCE(x) __builtin_choose_expr(__ALIGNED_WORD(x), 		\
+	__READ_ONCE_SIMPLE(x), __READ_ONCE(x, 1))
 
 /*
  * Use READ_ONCE_NOCHECK() instead of READ_ONCE() if you need
@@ -328,13 +362,8 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
  */
 #define READ_ONCE_NOCHECK(x) __READ_ONCE(x, 0)
 
-#define WRITE_ONCE(x, val) \
-({							\
-	union { typeof(x) __val; char __c[1]; } __u =	\
-		{ .__val = (__force typeof(x)) (val) }; \
-	__write_once_size(&(x), __u.__c, sizeof(x));	\
-	__u.__val;					\
-})
+#define WRITE_ONCE(x, val) do { __builtin_choose_expr(__ALIGNED_WORD(x), \
+	__WRITE_ONCE_SIMPLE(x, val), __WRITE_ONCE(x, val)); } while (0)
 
 #endif /* __KERNEL__ */
 
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 03/26] typecheck.h: avoid local variables in typecheck() macro
  2017-03-02 16:38 [PATCH 00/26] bring back stack frame warning with KASAN Arnd Bergmann
  2017-03-02 16:38 ` [PATCH 01/26] compiler: introduce noinline_for_kasan annotation Arnd Bergmann
  2017-03-02 16:38 ` [PATCH 02/26] rewrite READ_ONCE/WRITE_ONCE Arnd Bergmann
@ 2017-03-02 16:38 ` Arnd Bergmann
  2017-03-02 16:38 ` [PATCH 04/26] tty: kbd: reduce stack size with KASAN Arnd Bergmann
                   ` (23 subsequent siblings)
  26 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann

With KASAN enabled, the typecheck macro leads to some serious stack memory,
as seen in the rt2xxx drivers:

drivers/net/wireless/ralink/rt2x00/rt2800lib.c: In function 'rt2800_init_registers':
drivers/net/wireless/ralink/rt2x00/rt2800lib.c:5068:1: error: the frame size of 23768 bytes is larger than 1024 bytes [-Werror=frame-larger-than=]
drivers/net/wireless/ralink/rt2x00/rt2800lib.c: In function 'rt2800_config_txpower_rt3593.isra.1':
drivers/net/wireless/ralink/rt2x00/rt2800lib.c:4126:1: error: the frame size of 14184 bytes is larger than 1024 bytes [-Werror=frame-larger-than=]
drivers/net/wireless/ralink/rt2x00/rt2800lib.c: In function 'rt2800_config_channel_rf3053.isra.5':
drivers/net/wireless/ralink/rt2x00/rt2800lib.c:2585:1: error: the frame size of 7632 bytes is larger than 1024 bytes [-Werror=frame-larger-than=]

If we express the macro in a way that avoids the local variables, this goes
away and the stacks are comparable to building without KASAN.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 include/linux/typecheck.h | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/include/linux/typecheck.h b/include/linux/typecheck.h
index eb5b74a575be..adb1579fa5f0 100644
--- a/include/linux/typecheck.h
+++ b/include/linux/typecheck.h
@@ -5,12 +5,7 @@
  * Check at compile time that something is of a particular type.
  * Always evaluates to 1 so you may use it easily in comparisons.
  */
-#define typecheck(type,x) \
-({	type __dummy; \
-	typeof(x) __dummy2; \
-	(void)(&__dummy == &__dummy2); \
-	1; \
-})
+#define typecheck(type,x) ({(void)((typeof(type) *)NULL == (typeof(x) *)NULL); 1;})
 
 /*
  * Check at compile time that 'function' is a certain type, or is a pointer
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 04/26] tty: kbd: reduce stack size with KASAN
  2017-03-02 16:38 [PATCH 00/26] bring back stack frame warning with KASAN Arnd Bergmann
                   ` (2 preceding siblings ...)
  2017-03-02 16:38 ` [PATCH 03/26] typecheck.h: avoid local variables in typecheck() macro Arnd Bergmann
@ 2017-03-02 16:38 ` Arnd Bergmann
  2017-03-02 16:38 ` [PATCH 05/26] netlink: mark nla_put_{u8,u16,u32} noinline_for_kasan Arnd Bergmann
                   ` (22 subsequent siblings)
  26 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann

As reported by kernelci, some functions in the VT code use significant
amounts of kernel stack when local variables get inlined into the caller
multiple times:

drivers/tty/vt/keyboard.c: In function 'kbd_keycode':
drivers/tty/vt/keyboard.c:1452:1: error: the frame size of 2240 bytes is larger than 2048 bytes [-Werror=frame-larger-than=]

Annotating those functions as noinline_for_kasan prevents the inlining
and reduces the overall stack usage in this driver.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/tty/vt/keyboard.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index 397e1509fe51..f8a183c1639f 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -300,13 +300,13 @@ int kbd_rate(struct kbd_repeat *rpt)
 /*
  * Helper Functions.
  */
-static void put_queue(struct vc_data *vc, int ch)
+static noinline_for_kasan void put_queue(struct vc_data *vc, int ch)
 {
 	tty_insert_flip_char(&vc->port, ch, 0);
 	tty_schedule_flip(&vc->port);
 }
 
-static void puts_queue(struct vc_data *vc, char *cp)
+static noinline_for_kasan void puts_queue(struct vc_data *vc, char *cp)
 {
 	while (*cp) {
 		tty_insert_flip_char(&vc->port, *cp, 0);
@@ -554,7 +554,7 @@ static void fn_inc_console(struct vc_data *vc)
 	set_console(i);
 }
 
-static void fn_send_intr(struct vc_data *vc)
+static noinline_for_kasan void fn_send_intr(struct vc_data *vc)
 {
 	tty_insert_flip_char(&vc->port, 0, TTY_BREAK);
 	tty_schedule_flip(&vc->port);
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 05/26] netlink: mark nla_put_{u8,u16,u32} noinline_for_kasan
  2017-03-02 16:38 [PATCH 00/26] bring back stack frame warning with KASAN Arnd Bergmann
                   ` (3 preceding siblings ...)
  2017-03-02 16:38 ` [PATCH 04/26] tty: kbd: reduce stack size with KASAN Arnd Bergmann
@ 2017-03-02 16:38 ` Arnd Bergmann
  2017-03-02 16:38 ` [PATCH 06/26] rocker: mark rocker_tlv_put_* functions as noinline_for_kasan Arnd Bergmann
                   ` (21 subsequent siblings)
  26 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann

When CONFIG_KASAN is enabled, the "--param asan-stack=1" causes rather large
stack frames in some functions. This goes unnoticed normally because
CONFIG_FRAME_WARN is disabled with CONFIG_KASAN by default as of commit
3f181b4d8652 ("lib/Kconfig.debug: disable -Wframe-larger-than warnings with
KASAN=y").

The kernelci.org build bot however has the warning enabled and that led
me to investigate it a little further, as every build produces these warnings:

net/wireless/nl80211.c:4389:1: warning: the frame size of 2240 bytes is larger than 2048 bytes [-Wframe-larger-than=]
net/wireless/nl80211.c:1895:1: warning: the frame size of 3776 bytes is larger than 2048 bytes [-Wframe-larger-than=]
net/wireless/nl80211.c:1410:1: warning: the frame size of 2208 bytes is larger than 2048 bytes [-Wframe-larger-than=]
net/bridge/br_netlink.c:1282:1: warning: the frame size of 2544 bytes is larger than 2048 bytes [-Wframe-larger-than=]

With the new noinline_for_kasan annotation, we can avoid the problem
when KASAN is enabled but not change anything otherwise.

Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: kasan-dev@googlegroups.com
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 include/net/netlink.h | 36 ++++++++++++++++++------------------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/include/net/netlink.h b/include/net/netlink.h
index b239fcd33d80..d84878d8347f 100644
--- a/include/net/netlink.h
+++ b/include/net/netlink.h
@@ -755,7 +755,7 @@ static inline int nla_parse_nested(struct nlattr *tb[], int maxtype,
  * @attrtype: attribute type
  * @value: numeric value
  */
-static inline int nla_put_u8(struct sk_buff *skb, int attrtype, u8 value)
+static noinline_for_kasan int nla_put_u8(struct sk_buff *skb, int attrtype, u8 value)
 {
 	return nla_put(skb, attrtype, sizeof(u8), &value);
 }
@@ -766,7 +766,7 @@ static inline int nla_put_u8(struct sk_buff *skb, int attrtype, u8 value)
  * @attrtype: attribute type
  * @value: numeric value
  */
-static inline int nla_put_u16(struct sk_buff *skb, int attrtype, u16 value)
+static noinline_for_kasan int nla_put_u16(struct sk_buff *skb, int attrtype, u16 value)
 {
 	return nla_put(skb, attrtype, sizeof(u16), &value);
 }
@@ -777,7 +777,7 @@ static inline int nla_put_u16(struct sk_buff *skb, int attrtype, u16 value)
  * @attrtype: attribute type
  * @value: numeric value
  */
-static inline int nla_put_be16(struct sk_buff *skb, int attrtype, __be16 value)
+static noinline_for_kasan int nla_put_be16(struct sk_buff *skb, int attrtype, __be16 value)
 {
 	return nla_put(skb, attrtype, sizeof(__be16), &value);
 }
@@ -788,7 +788,7 @@ static inline int nla_put_be16(struct sk_buff *skb, int attrtype, __be16 value)
  * @attrtype: attribute type
  * @value: numeric value
  */
-static inline int nla_put_net16(struct sk_buff *skb, int attrtype, __be16 value)
+static noinline_for_kasan int nla_put_net16(struct sk_buff *skb, int attrtype, __be16 value)
 {
 	return nla_put_be16(skb, attrtype | NLA_F_NET_BYTEORDER, value);
 }
@@ -799,7 +799,7 @@ static inline int nla_put_net16(struct sk_buff *skb, int attrtype, __be16 value)
  * @attrtype: attribute type
  * @value: numeric value
  */
-static inline int nla_put_le16(struct sk_buff *skb, int attrtype, __le16 value)
+static noinline_for_kasan int nla_put_le16(struct sk_buff *skb, int attrtype, __le16 value)
 {
 	return nla_put(skb, attrtype, sizeof(__le16), &value);
 }
@@ -810,7 +810,7 @@ static inline int nla_put_le16(struct sk_buff *skb, int attrtype, __le16 value)
  * @attrtype: attribute type
  * @value: numeric value
  */
-static inline int nla_put_u32(struct sk_buff *skb, int attrtype, u32 value)
+static noinline_for_kasan int nla_put_u32(struct sk_buff *skb, int attrtype, u32 value)
 {
 	return nla_put(skb, attrtype, sizeof(u32), &value);
 }
@@ -821,7 +821,7 @@ static inline int nla_put_u32(struct sk_buff *skb, int attrtype, u32 value)
  * @attrtype: attribute type
  * @value: numeric value
  */
-static inline int nla_put_be32(struct sk_buff *skb, int attrtype, __be32 value)
+static noinline_for_kasan int nla_put_be32(struct sk_buff *skb, int attrtype, __be32 value)
 {
 	return nla_put(skb, attrtype, sizeof(__be32), &value);
 }
@@ -832,7 +832,7 @@ static inline int nla_put_be32(struct sk_buff *skb, int attrtype, __be32 value)
  * @attrtype: attribute type
  * @value: numeric value
  */
-static inline int nla_put_net32(struct sk_buff *skb, int attrtype, __be32 value)
+static noinline_for_kasan int nla_put_net32(struct sk_buff *skb, int attrtype, __be32 value)
 {
 	return nla_put_be32(skb, attrtype | NLA_F_NET_BYTEORDER, value);
 }
@@ -843,7 +843,7 @@ static inline int nla_put_net32(struct sk_buff *skb, int attrtype, __be32 value)
  * @attrtype: attribute type
  * @value: numeric value
  */
-static inline int nla_put_le32(struct sk_buff *skb, int attrtype, __le32 value)
+static noinline_for_kasan int nla_put_le32(struct sk_buff *skb, int attrtype, __le32 value)
 {
 	return nla_put(skb, attrtype, sizeof(__le32), &value);
 }
@@ -855,7 +855,7 @@ static inline int nla_put_le32(struct sk_buff *skb, int attrtype, __le32 value)
  * @value: numeric value
  * @padattr: attribute type for the padding
  */
-static inline int nla_put_u64_64bit(struct sk_buff *skb, int attrtype,
+static noinline_for_kasan int nla_put_u64_64bit(struct sk_buff *skb, int attrtype,
 				    u64 value, int padattr)
 {
 	return nla_put_64bit(skb, attrtype, sizeof(u64), &value, padattr);
@@ -868,7 +868,7 @@ static inline int nla_put_u64_64bit(struct sk_buff *skb, int attrtype,
  * @value: numeric value
  * @padattr: attribute type for the padding
  */
-static inline int nla_put_be64(struct sk_buff *skb, int attrtype, __be64 value,
+static noinline_for_kasan int nla_put_be64(struct sk_buff *skb, int attrtype, __be64 value,
 			       int padattr)
 {
 	return nla_put_64bit(skb, attrtype, sizeof(__be64), &value, padattr);
@@ -881,7 +881,7 @@ static inline int nla_put_be64(struct sk_buff *skb, int attrtype, __be64 value,
  * @value: numeric value
  * @padattr: attribute type for the padding
  */
-static inline int nla_put_net64(struct sk_buff *skb, int attrtype, __be64 value,
+static noinline_for_kasan int nla_put_net64(struct sk_buff *skb, int attrtype, __be64 value,
 				int padattr)
 {
 	return nla_put_be64(skb, attrtype | NLA_F_NET_BYTEORDER, value,
@@ -895,7 +895,7 @@ static inline int nla_put_net64(struct sk_buff *skb, int attrtype, __be64 value,
  * @value: numeric value
  * @padattr: attribute type for the padding
  */
-static inline int nla_put_le64(struct sk_buff *skb, int attrtype, __le64 value,
+static noinline_for_kasan int nla_put_le64(struct sk_buff *skb, int attrtype, __le64 value,
 			       int padattr)
 {
 	return nla_put_64bit(skb, attrtype, sizeof(__le64), &value, padattr);
@@ -907,7 +907,7 @@ static inline int nla_put_le64(struct sk_buff *skb, int attrtype, __le64 value,
  * @attrtype: attribute type
  * @value: numeric value
  */
-static inline int nla_put_s8(struct sk_buff *skb, int attrtype, s8 value)
+static noinline_for_kasan int nla_put_s8(struct sk_buff *skb, int attrtype, s8 value)
 {
 	return nla_put(skb, attrtype, sizeof(s8), &value);
 }
@@ -918,7 +918,7 @@ static inline int nla_put_s8(struct sk_buff *skb, int attrtype, s8 value)
  * @attrtype: attribute type
  * @value: numeric value
  */
-static inline int nla_put_s16(struct sk_buff *skb, int attrtype, s16 value)
+static noinline_for_kasan int nla_put_s16(struct sk_buff *skb, int attrtype, s16 value)
 {
 	return nla_put(skb, attrtype, sizeof(s16), &value);
 }
@@ -929,7 +929,7 @@ static inline int nla_put_s16(struct sk_buff *skb, int attrtype, s16 value)
  * @attrtype: attribute type
  * @value: numeric value
  */
-static inline int nla_put_s32(struct sk_buff *skb, int attrtype, s32 value)
+static noinline_for_kasan int nla_put_s32(struct sk_buff *skb, int attrtype, s32 value)
 {
 	return nla_put(skb, attrtype, sizeof(s32), &value);
 }
@@ -941,7 +941,7 @@ static inline int nla_put_s32(struct sk_buff *skb, int attrtype, s32 value)
  * @value: numeric value
  * @padattr: attribute type for the padding
  */
-static inline int nla_put_s64(struct sk_buff *skb, int attrtype, s64 value,
+static noinline_for_kasan int nla_put_s64(struct sk_buff *skb, int attrtype, s64 value,
 			      int padattr)
 {
 	return nla_put_64bit(skb, attrtype, sizeof(s64), &value, padattr);
@@ -976,7 +976,7 @@ static inline int nla_put_flag(struct sk_buff *skb, int attrtype)
  * @njiffies: number of jiffies to convert to msecs
  * @padattr: attribute type for the padding
  */
-static inline int nla_put_msecs(struct sk_buff *skb, int attrtype,
+static noinline_for_kasan int nla_put_msecs(struct sk_buff *skb, int attrtype,
 				unsigned long njiffies, int padattr)
 {
 	u64 tmp = jiffies_to_msecs(njiffies);
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 06/26] rocker: mark rocker_tlv_put_* functions as noinline_for_kasan
  2017-03-02 16:38 [PATCH 00/26] bring back stack frame warning with KASAN Arnd Bergmann
                   ` (4 preceding siblings ...)
  2017-03-02 16:38 ` [PATCH 05/26] netlink: mark nla_put_{u8,u16,u32} noinline_for_kasan Arnd Bergmann
@ 2017-03-02 16:38 ` Arnd Bergmann
  2017-03-02 16:38 ` [PATCH 07/26] brcmsmac: reduce stack size with KASAN Arnd Bergmann
                   ` (20 subsequent siblings)
  26 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann

Inlining these functions creates lots of stack variables when KASAN is
enabled, leading to this warning about potential stack overflow:

drivers/net/ethernet/rocker/rocker_ofdpa.c: In function 'ofdpa_cmd_flow_tbl_add':
drivers/net/ethernet/rocker/rocker_ofdpa.c:621:1: error: the frame size of 2752 bytes is larger than 1536 bytes [-Werror=frame-larger-than=]

This marks all of them noinline_for_kasan, which solves the problem by
keeping the redzone inside of the separate stack frames.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/net/ethernet/rocker/rocker_tlv.h | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/rocker/rocker_tlv.h b/drivers/net/ethernet/rocker/rocker_tlv.h
index a63ef82e7c72..3a9573fe0191 100644
--- a/drivers/net/ethernet/rocker/rocker_tlv.h
+++ b/drivers/net/ethernet/rocker/rocker_tlv.h
@@ -139,38 +139,38 @@ rocker_tlv_start(struct rocker_desc_info *desc_info)
 int rocker_tlv_put(struct rocker_desc_info *desc_info,
 		   int attrtype, int attrlen, const void *data);
 
-static inline int rocker_tlv_put_u8(struct rocker_desc_info *desc_info,
-				    int attrtype, u8 value)
+static noinline_for_kasan int
+rocker_tlv_put_u8(struct rocker_desc_info *desc_info, int attrtype, u8 value)
 {
 	return rocker_tlv_put(desc_info, attrtype, sizeof(u8), &value);
 }
 
-static inline int rocker_tlv_put_u16(struct rocker_desc_info *desc_info,
-				     int attrtype, u16 value)
+static noinline_for_kasan int
+rocker_tlv_put_u16(struct rocker_desc_info *desc_info, int attrtype, u16 value)
 {
 	return rocker_tlv_put(desc_info, attrtype, sizeof(u16), &value);
 }
 
-static inline int rocker_tlv_put_be16(struct rocker_desc_info *desc_info,
-				      int attrtype, __be16 value)
+static noinline_for_kasan int
+rocker_tlv_put_be16(struct rocker_desc_info *desc_info, int attrtype, __be16 value)
 {
 	return rocker_tlv_put(desc_info, attrtype, sizeof(__be16), &value);
 }
 
-static inline int rocker_tlv_put_u32(struct rocker_desc_info *desc_info,
-				     int attrtype, u32 value)
+static noinline_for_kasan int
+rocker_tlv_put_u32(struct rocker_desc_info *desc_info, int attrtype, u32 value)
 {
 	return rocker_tlv_put(desc_info, attrtype, sizeof(u32), &value);
 }
 
-static inline int rocker_tlv_put_be32(struct rocker_desc_info *desc_info,
-				      int attrtype, __be32 value)
+static noinline_for_kasan int
+rocker_tlv_put_be32(struct rocker_desc_info *desc_info, int attrtype, __be32 value)
 {
 	return rocker_tlv_put(desc_info, attrtype, sizeof(__be32), &value);
 }
 
-static inline int rocker_tlv_put_u64(struct rocker_desc_info *desc_info,
-				     int attrtype, u64 value)
+static noinline_for_kasan int
+rocker_tlv_put_u64(struct rocker_desc_info *desc_info, int attrtype, u64 value)
 {
 	return rocker_tlv_put(desc_info, attrtype, sizeof(u64), &value);
 }
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 07/26] brcmsmac: reduce stack size with KASAN
  2017-03-02 16:38 [PATCH 00/26] bring back stack frame warning with KASAN Arnd Bergmann
                   ` (5 preceding siblings ...)
  2017-03-02 16:38 ` [PATCH 06/26] rocker: mark rocker_tlv_put_* functions as noinline_for_kasan Arnd Bergmann
@ 2017-03-02 16:38 ` Arnd Bergmann
  2017-03-06  9:16   ` Arend Van Spriel
  2017-03-02 16:38 ` [PATCH 08/26] brcmsmac: make some local variables 'static const' to reduce stack size Arnd Bergmann
                   ` (19 subsequent siblings)
  26 siblings, 1 reply; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann

The wlc_phy_table_write_nphy/wlc_phy_table_read_nphy functions always put an object
on the stack, which will each require a redzone with KASAN and lead to possible
stack overflow:

drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c: In function 'wlc_phy_workarounds_nphy':
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c:17135:1: warning: the frame size of 6312 bytes is larger than 1000 bytes [-Wframe-larger-than=]

This marks the two functions as noinline_for_kasan, avoiding the problem entirely.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
index b3aab2fe96eb..42dc8e1f483d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
@@ -14157,7 +14157,7 @@ static void wlc_phy_bphy_init_nphy(struct brcms_phy *pi)
 	write_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_STEP, 0x668);
 }
 
-void
+noinline_for_kasan void
 wlc_phy_table_write_nphy(struct brcms_phy *pi, u32 id, u32 len, u32 offset,
 			 u32 width, const void *data)
 {
@@ -14171,7 +14171,7 @@ wlc_phy_table_write_nphy(struct brcms_phy *pi, u32 id, u32 len, u32 offset,
 	wlc_phy_write_table_nphy(pi, &tbl);
 }
 
-void
+noinline_for_kasan void
 wlc_phy_table_read_nphy(struct brcms_phy *pi, u32 id, u32 len, u32 offset,
 			u32 width, void *data)
 {
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 08/26] brcmsmac: make some local variables 'static const' to reduce stack size
  2017-03-02 16:38 [PATCH 00/26] bring back stack frame warning with KASAN Arnd Bergmann
                   ` (6 preceding siblings ...)
  2017-03-02 16:38 ` [PATCH 07/26] brcmsmac: reduce stack size with KASAN Arnd Bergmann
@ 2017-03-02 16:38 ` Arnd Bergmann
  2017-03-06  9:30   ` Arend Van Spriel
  2017-03-02 16:38 ` [PATCH 09/26] brcmsmac: split up wlc_phy_workarounds_nphy Arnd Bergmann
                   ` (18 subsequent siblings)
  26 siblings, 1 reply; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann

With KASAN and a couple of other patches applied, this driver is one
of the few remaining ones that actually use more than 2048 bytes of
kernel stack:

broadcom/brcm80211/brcmsmac/phy/phy_n.c: In function 'wlc_phy_workarounds_nphy_gainctrl':
broadcom/brcm80211/brcmsmac/phy/phy_n.c:16065:1: warning: the frame size of 3264 bytes is larger than 2048 bytes [-Wframe-larger-than=]
broadcom/brcm80211/brcmsmac/phy/phy_n.c: In function 'wlc_phy_workarounds_nphy':
broadcom/brcm80211/brcmsmac/phy/phy_n.c:17138:1: warning: the frame size of 2864 bytes is larger than 2048 bytes [-Wframe-larger-than=]

Here, I'm reducing the stack size by marking as many local variables as
'static const' as I can without changing the actual code.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 .../broadcom/brcm80211/brcmsmac/phy/phy_n.c        | 197 ++++++++++-----------
 1 file changed, 97 insertions(+), 100 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
index 42dc8e1f483d..48a4df488d75 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
@@ -14764,8 +14764,8 @@ static void wlc_phy_ipa_restore_tx_digi_filts_nphy(struct brcms_phy *pi)
 }
 
 static void
-wlc_phy_set_rfseq_nphy(struct brcms_phy *pi, u8 cmd, u8 *events, u8 *dlys,
-		       u8 len)
+wlc_phy_set_rfseq_nphy(struct brcms_phy *pi, u8 cmd, const u8 *events,
+		       const u8 *dlys, u8 len)
 {
 	u32 t1_offset, t2_offset;
 	u8 ctr;
@@ -15240,16 +15240,16 @@ static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(struct brcms_phy *pi)
 static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi)
 {
 	u16 currband;
-	s8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 };
-	s8 *lna1_gain_db = NULL;
-	s8 *lna1_gain_db_2 = NULL;
-	s8 *lna2_gain_db = NULL;
-	s8 tiaA_gain_db_rev7[] = { -9, -6, -3, 0, 3, 3, 3, 3, 3, 3 };
-	s8 *tia_gain_db;
-	s8 tiaA_gainbits_rev7[] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 };
-	s8 *tia_gainbits;
-	u16 rfseqA_init_gain_rev7[] = { 0x624f, 0x624f };
-	u16 *rfseq_init_gain;
+	static const s8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 };
+	const s8 *lna1_gain_db = NULL;
+	const s8 *lna1_gain_db_2 = NULL;
+	const s8 *lna2_gain_db = NULL;
+	static const s8 tiaA_gain_db_rev7[] = { -9, -6, -3, 0, 3, 3, 3, 3, 3, 3 };
+	const s8 *tia_gain_db;
+	static const s8 tiaA_gainbits_rev7[] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 };
+	const s8 *tia_gainbits;
+	static const u16 rfseqA_init_gain_rev7[] = { 0x624f, 0x624f };
+	const u16 *rfseq_init_gain;
 	u16 init_gaincode;
 	u16 clip1hi_gaincode;
 	u16 clip1md_gaincode = 0;
@@ -15310,10 +15310,9 @@ static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi)
 
 			if ((freq <= 5080) || (freq == 5825)) {
 
-				s8 lna1A_gain_db_rev7[] = { 11, 16, 20, 24 };
-				s8 lna1A_gain_db_2_rev7[] = {
-					11, 17, 22, 25};
-				s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
+				static const s8 lna1A_gain_db_rev7[] = { 11, 16, 20, 24 };
+				static const s8 lna1A_gain_db_2_rev7[] = { 11, 17, 22, 25};
+				static const s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
 
 				crsminu_th = 0x3e;
 				lna1_gain_db = lna1A_gain_db_rev7;
@@ -15321,10 +15320,9 @@ static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi)
 				lna2_gain_db = lna2A_gain_db_rev7;
 			} else if ((freq >= 5500) && (freq <= 5700)) {
 
-				s8 lna1A_gain_db_rev7[] = { 11, 17, 21, 25 };
-				s8 lna1A_gain_db_2_rev7[] = {
-					12, 18, 22, 26};
-				s8 lna2A_gain_db_rev7[] = { 1, 8, 12, 16 };
+				static const s8 lna1A_gain_db_rev7[] = { 11, 17, 21, 25 };
+				static const s8 lna1A_gain_db_2_rev7[] = { 12, 18, 22, 26};
+				static const s8 lna2A_gain_db_rev7[] = { 1, 8, 12, 16 };
 
 				crsminu_th = 0x45;
 				clip1md_gaincode_B = 0x14;
@@ -15335,10 +15333,9 @@ static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi)
 				lna2_gain_db = lna2A_gain_db_rev7;
 			} else {
 
-				s8 lna1A_gain_db_rev7[] = { 12, 18, 22, 26 };
-				s8 lna1A_gain_db_2_rev7[] = {
-					12, 18, 22, 26};
-				s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
+				static const s8 lna1A_gain_db_rev7[] = { 12, 18, 22, 26 };
+				static const s8 lna1A_gain_db_2_rev7[] = { 12, 18, 22, 26};
+				static const s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
 
 				crsminu_th = 0x41;
 				lna1_gain_db = lna1A_gain_db_rev7;
@@ -15450,65 +15447,65 @@ static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi)
 		NPHY_RFSEQ_CMD_CLR_HIQ_DIS,
 		NPHY_RFSEQ_CMD_SET_HPF_BW
 	};
-	u8 rfseq_updategainu_dlys[] = { 10, 30, 1 };
-	s8 lna1G_gain_db[] = { 7, 11, 16, 23 };
-	s8 lna1G_gain_db_rev4[] = { 8, 12, 17, 25 };
-	s8 lna1G_gain_db_rev5[] = { 9, 13, 18, 26 };
-	s8 lna1G_gain_db_rev6[] = { 8, 13, 18, 25 };
-	s8 lna1G_gain_db_rev6_224B0[] = { 10, 14, 19, 27 };
-	s8 lna1A_gain_db[] = { 7, 11, 17, 23 };
-	s8 lna1A_gain_db_rev4[] = { 8, 12, 18, 23 };
-	s8 lna1A_gain_db_rev5[] = { 6, 10, 16, 21 };
-	s8 lna1A_gain_db_rev6[] = { 6, 10, 16, 21 };
-	s8 *lna1_gain_db = NULL;
-	s8 lna2G_gain_db[] = { -5, 6, 10, 14 };
-	s8 lna2G_gain_db_rev5[] = { -3, 7, 11, 16 };
-	s8 lna2G_gain_db_rev6[] = { -5, 6, 10, 14 };
-	s8 lna2G_gain_db_rev6_224B0[] = { -5, 6, 10, 15 };
-	s8 lna2A_gain_db[] = { -6, 2, 6, 10 };
-	s8 lna2A_gain_db_rev4[] = { -5, 2, 6, 10 };
-	s8 lna2A_gain_db_rev5[] = { -7, 0, 4, 8 };
-	s8 lna2A_gain_db_rev6[] = { -7, 0, 4, 8 };
-	s8 *lna2_gain_db = NULL;
-	s8 tiaG_gain_db[] = {
+	static const u8 rfseq_updategainu_dlys[] = { 10, 30, 1 };
+	static const s8 lna1G_gain_db[] = { 7, 11, 16, 23 };
+	static const s8 lna1G_gain_db_rev4[] = { 8, 12, 17, 25 };
+	static const s8 lna1G_gain_db_rev5[] = { 9, 13, 18, 26 };
+	static const s8 lna1G_gain_db_rev6[] = { 8, 13, 18, 25 };
+	static const s8 lna1G_gain_db_rev6_224B0[] = { 10, 14, 19, 27 };
+	static const s8 lna1A_gain_db[] = { 7, 11, 17, 23 };
+	static const s8 lna1A_gain_db_rev4[] = { 8, 12, 18, 23 };
+	static const s8 lna1A_gain_db_rev5[] = { 6, 10, 16, 21 };
+	static const s8 lna1A_gain_db_rev6[] = { 6, 10, 16, 21 };
+	const s8 *lna1_gain_db = NULL;
+	static const s8 lna2G_gain_db[] = { -5, 6, 10, 14 };
+	static const s8 lna2G_gain_db_rev5[] = { -3, 7, 11, 16 };
+	static const s8 lna2G_gain_db_rev6[] = { -5, 6, 10, 14 };
+	static const s8 lna2G_gain_db_rev6_224B0[] = { -5, 6, 10, 15 };
+	static const s8 lna2A_gain_db[] = { -6, 2, 6, 10 };
+	static const s8 lna2A_gain_db_rev4[] = { -5, 2, 6, 10 };
+	static const s8 lna2A_gain_db_rev5[] = { -7, 0, 4, 8 };
+	static const s8 lna2A_gain_db_rev6[] = { -7, 0, 4, 8 };
+	const s8 *lna2_gain_db = NULL;
+	static const s8 tiaG_gain_db[] = {
 		0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A };
-	s8 tiaA_gain_db[] = {
+	static const s8 tiaA_gain_db[] = {
 		0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 };
-	s8 tiaA_gain_db_rev4[] = {
+	static const s8 tiaA_gain_db_rev4[] = {
 		0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
-	s8 tiaA_gain_db_rev5[] = {
+	static const s8 tiaA_gain_db_rev5[] = {
 		0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
-	s8 tiaA_gain_db_rev6[] = {
+	static const s8 tiaA_gain_db_rev6[] = {
 		0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
-	s8 *tia_gain_db;
-	s8 tiaG_gainbits[] = {
+	const s8 *tia_gain_db;
+	static const s8 tiaG_gainbits[] = {
 		0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 };
-	s8 tiaA_gainbits[] = {
+	static const s8 tiaA_gainbits[] = {
 		0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06 };
-	s8 tiaA_gainbits_rev4[] = {
+	static const s8 tiaA_gainbits_rev4[] = {
 		0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
-	s8 tiaA_gainbits_rev5[] = {
+	static const s8 tiaA_gainbits_rev5[] = {
 		0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
-	s8 tiaA_gainbits_rev6[] = {
+	static const s8 tiaA_gainbits_rev6[] = {
 		0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
-	s8 *tia_gainbits;
-	s8 lpf_gain_db[] = { 0x00, 0x06, 0x0c, 0x12, 0x12, 0x12 };
-	s8 lpf_gainbits[] = { 0x00, 0x01, 0x02, 0x03, 0x03, 0x03 };
-	u16 rfseqG_init_gain[] = { 0x613f, 0x613f, 0x613f, 0x613f };
-	u16 rfseqG_init_gain_rev4[] = { 0x513f, 0x513f, 0x513f, 0x513f };
-	u16 rfseqG_init_gain_rev5[] = { 0x413f, 0x413f, 0x413f, 0x413f };
-	u16 rfseqG_init_gain_rev5_elna[] = {
+	const s8 *tia_gainbits;
+	static const s8 lpf_gain_db[] = { 0x00, 0x06, 0x0c, 0x12, 0x12, 0x12 };
+	static const s8 lpf_gainbits[] = { 0x00, 0x01, 0x02, 0x03, 0x03, 0x03 };
+	static const u16 rfseqG_init_gain[] = { 0x613f, 0x613f, 0x613f, 0x613f };
+	static const u16 rfseqG_init_gain_rev4[] = { 0x513f, 0x513f, 0x513f, 0x513f };
+	static const u16 rfseqG_init_gain_rev5[] = { 0x413f, 0x413f, 0x413f, 0x413f };
+	static const u16 rfseqG_init_gain_rev5_elna[] = {
 		0x013f, 0x013f, 0x013f, 0x013f };
-	u16 rfseqG_init_gain_rev6[] = { 0x513f, 0x513f };
-	u16 rfseqG_init_gain_rev6_224B0[] = { 0x413f, 0x413f };
-	u16 rfseqG_init_gain_rev6_elna[] = { 0x113f, 0x113f };
-	u16 rfseqA_init_gain[] = { 0x516f, 0x516f, 0x516f, 0x516f };
-	u16 rfseqA_init_gain_rev4[] = { 0x614f, 0x614f, 0x614f, 0x614f };
-	u16 rfseqA_init_gain_rev4_elna[] = {
+	static const u16 rfseqG_init_gain_rev6[] = { 0x513f, 0x513f };
+	static const u16 rfseqG_init_gain_rev6_224B0[] = { 0x413f, 0x413f };
+	static const u16 rfseqG_init_gain_rev6_elna[] = { 0x113f, 0x113f };
+	static const u16 rfseqA_init_gain[] = { 0x516f, 0x516f, 0x516f, 0x516f };
+	static const u16 rfseqA_init_gain_rev4[] = { 0x614f, 0x614f, 0x614f, 0x614f };
+	static const u16 rfseqA_init_gain_rev4_elna[] = {
 		0x314f, 0x314f, 0x314f, 0x314f };
-	u16 rfseqA_init_gain_rev5[] = { 0x714f, 0x714f, 0x714f, 0x714f };
-	u16 rfseqA_init_gain_rev6[] = { 0x714f, 0x714f };
-	u16 *rfseq_init_gain;
+	static const u16 rfseqA_init_gain_rev5[] = { 0x714f, 0x714f, 0x714f, 0x714f };
+	static const u16 rfseqA_init_gain_rev6[] = { 0x714f, 0x714f };
+	const u16 *rfseq_init_gain;
 	u16 initG_gaincode = 0x627e;
 	u16 initG_gaincode_rev4 = 0x527e;
 	u16 initG_gaincode_rev5 = 0x427e;
@@ -15538,10 +15535,10 @@ static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi)
 	u16 clip1mdA_gaincode_rev6 = 0x2084;
 	u16 clip1md_gaincode = 0;
 	u16 clip1loG_gaincode = 0x0074;
-	u16 clip1loG_gaincode_rev5[] = {
+	static const u16 clip1loG_gaincode_rev5[] = {
 		0x0062, 0x0064, 0x006a, 0x106a, 0x106c, 0x1074, 0x107c, 0x207c
 	};
-	u16 clip1loG_gaincode_rev6[] = {
+	static const u16 clip1loG_gaincode_rev6[] = {
 		0x106a, 0x106c, 0x1074, 0x107c, 0x007e, 0x107e, 0x207e, 0x307e
 	};
 	u16 clip1loG_gaincode_rev6_224B0 = 0x1074;
@@ -16066,7 +16063,7 @@ static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi)
 
 static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
 {
-	u8 rfseq_rx2tx_events[] = {
+	static const u8 rfseq_rx2tx_events[] = {
 		NPHY_RFSEQ_CMD_NOP,
 		NPHY_RFSEQ_CMD_RXG_FBW,
 		NPHY_RFSEQ_CMD_TR_SWITCH,
@@ -16076,7 +16073,7 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
 		NPHY_RFSEQ_CMD_EXT_PA
 	};
 	u8 rfseq_rx2tx_dlys[] = { 8, 6, 6, 2, 4, 60, 1 };
-	u8 rfseq_tx2rx_events[] = {
+	static const u8 rfseq_tx2rx_events[] = {
 		NPHY_RFSEQ_CMD_NOP,
 		NPHY_RFSEQ_CMD_EXT_PA,
 		NPHY_RFSEQ_CMD_TX_GAIN,
@@ -16085,8 +16082,8 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
 		NPHY_RFSEQ_CMD_RXG_FBW,
 		NPHY_RFSEQ_CMD_CLR_HIQ_DIS
 	};
-	u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 };
-	u8 rfseq_tx2rx_events_rev3[] = {
+	static const u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 };
+	static const u8 rfseq_tx2rx_events_rev3[] = {
 		NPHY_REV3_RFSEQ_CMD_EXT_PA,
 		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
 		NPHY_REV3_RFSEQ_CMD_TX_GAIN,
@@ -16096,7 +16093,7 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
 		NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
 		NPHY_REV3_RFSEQ_CMD_END
 	};
-	u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 };
+	static const u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 };
 	u8 rfseq_rx2tx_events_rev3[] = {
 		NPHY_REV3_RFSEQ_CMD_NOP,
 		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
@@ -16110,7 +16107,7 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
 	};
 	u8 rfseq_rx2tx_dlys_rev3[] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 };
 
-	u8 rfseq_rx2tx_events_rev3_ipa[] = {
+	static const u8 rfseq_rx2tx_events_rev3_ipa[] = {
 		NPHY_REV3_RFSEQ_CMD_NOP,
 		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
 		NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
@@ -16121,15 +16118,15 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
 		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
 		NPHY_REV3_RFSEQ_CMD_END
 	};
-	u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
-	u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f };
+	static const u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
+	static const u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f };
 
 	s16 alpha0, alpha1, alpha2;
 	s16 beta0, beta1, beta2;
 	u32 leg_data_weights, ht_data_weights, nss1_data_weights,
 	    stbc_data_weights;
 	u8 chan_freq_range = 0;
-	u16 dac_control = 0x0002;
+	static const u16 dac_control = 0x0002;
 	u16 aux_adc_vmid_rev7_core0[] = { 0x8e, 0x96, 0x96, 0x96 };
 	u16 aux_adc_vmid_rev7_core1[] = { 0x8f, 0x9f, 0x9f, 0x96 };
 	u16 aux_adc_vmid_rev4[] = { 0xa2, 0xb4, 0xb4, 0x89 };
@@ -16139,8 +16136,8 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
 	u16 aux_adc_gain_rev4[] = { 0x02, 0x02, 0x02, 0x00 };
 	u16 aux_adc_gain_rev3[] = { 0x02, 0x02, 0x02, 0x00 };
 	u16 *aux_adc_gain;
-	u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 };
-	u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 };
+	static const u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 };
+	static const u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 };
 	s32 min_nvar_val = 0x18d;
 	s32 min_nvar_offset_6mbps = 20;
 	u8 pdetrange;
@@ -16151,9 +16148,9 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
 	u16 rfseq_rx2tx_lpf_h_hpc_rev7 = 0x77;
 	u16 rfseq_tx2rx_lpf_h_hpc_rev7 = 0x77;
 	u16 rfseq_pktgn_lpf_h_hpc_rev7 = 0x77;
-	u16 rfseq_htpktgn_lpf_hpc_rev7[] = { 0x77, 0x11, 0x11 };
-	u16 rfseq_pktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
-	u16 rfseq_cckpktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
+	static const u16 rfseq_htpktgn_lpf_hpc_rev7[] = { 0x77, 0x11, 0x11 };
+	static const u16 rfseq_pktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
+	static const u16 rfseq_cckpktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
 	u16 ipalvlshift_3p3_war_en = 0;
 	u16 rccal_bcap_val, rccal_scap_val;
 	u16 rccal_tx20_11b_bcap = 0;
@@ -24291,13 +24288,13 @@ static void wlc_phy_update_txcal_ladder_nphy(struct brcms_phy *pi, u16 core)
 	u16 bbmult;
 	u16 tblentry;
 
-	struct nphy_txiqcal_ladder ladder_lo[] = {
+	static const struct nphy_txiqcal_ladder ladder_lo[] = {
 		{3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0},
 		{25, 0}, {25, 1}, {25, 2}, {25, 3}, {25, 4}, {25, 5},
 		{25, 6}, {25, 7}, {35, 7}, {50, 7}, {71, 7}, {100, 7}
 	};
 
-	struct nphy_txiqcal_ladder ladder_iq[] = {
+	static const struct nphy_txiqcal_ladder ladder_iq[] = {
 		{3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0},
 		{25, 0}, {35, 0}, {50, 0}, {71, 0}, {100, 0}, {100, 1},
 		{100, 2}, {100, 3}, {100, 4}, {100, 5}, {100, 6}, {100, 7}
@@ -25773,67 +25770,67 @@ wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain,
 	u16 cal_gain[2];
 	struct nphy_iqcal_params cal_params[2];
 	u32 tbl_len;
-	void *tbl_ptr;
+	const void *tbl_ptr;
 	bool ladder_updated[2];
 	u8 mphase_cal_lastphase = 0;
 	int bcmerror = 0;
 	bool phyhang_avoid_state = false;
 
-	u16 tbl_tx_iqlo_cal_loft_ladder_20[] = {
+	static const u16 tbl_tx_iqlo_cal_loft_ladder_20[] = {
 		0x0300, 0x0500, 0x0700, 0x0900, 0x0d00, 0x1100, 0x1900, 0x1901,
 		0x1902,
 		0x1903, 0x1904, 0x1905, 0x1906, 0x1907, 0x2407, 0x3207, 0x4607,
 		0x6407
 	};
 
-	u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = {
+	static const u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = {
 		0x0200, 0x0300, 0x0600, 0x0900, 0x0d00, 0x1100, 0x1900, 0x2400,
 		0x3200,
 		0x4600, 0x6400, 0x6401, 0x6402, 0x6403, 0x6404, 0x6405, 0x6406,
 		0x6407
 	};
 
-	u16 tbl_tx_iqlo_cal_loft_ladder_40[] = {
+	static const u16 tbl_tx_iqlo_cal_loft_ladder_40[] = {
 		0x0200, 0x0300, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1201,
 		0x1202,
 		0x1203, 0x1204, 0x1205, 0x1206, 0x1207, 0x1907, 0x2307, 0x3207,
 		0x4707
 	};
 
-	u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = {
+	static const u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = {
 		0x0100, 0x0200, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1900,
 		0x2300,
 		0x3200, 0x4700, 0x4701, 0x4702, 0x4703, 0x4704, 0x4705, 0x4706,
 		0x4707
 	};
 
-	u16 tbl_tx_iqlo_cal_startcoefs[] = {
+	static const u16 tbl_tx_iqlo_cal_startcoefs[] = {
 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 		0x0000
 	};
 
-	u16 tbl_tx_iqlo_cal_cmds_fullcal[] = {
+	static const u16 tbl_tx_iqlo_cal_cmds_fullcal[] = {
 		0x8123, 0x8264, 0x8086, 0x8245, 0x8056,
 		0x9123, 0x9264, 0x9086, 0x9245, 0x9056
 	};
 
-	u16 tbl_tx_iqlo_cal_cmds_recal[] = {
+	static const u16 tbl_tx_iqlo_cal_cmds_recal[] = {
 		0x8101, 0x8253, 0x8053, 0x8234, 0x8034,
 		0x9101, 0x9253, 0x9053, 0x9234, 0x9034
 	};
 
-	u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[] = {
+	static const u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[] = {
 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 		0x0000
 	};
 
-	u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = {
+	static const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = {
 		0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234,
 		0x9434, 0x9334, 0x9084, 0x9267, 0x9056, 0x9234
 	};
 
-	u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = {
+	static const u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = {
 		0x8423, 0x8323, 0x8073, 0x8256, 0x8045, 0x8223,
 		0x9423, 0x9323, 0x9073, 0x9256, 0x9045, 0x9223
 	};
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 09/26] brcmsmac: split up wlc_phy_workarounds_nphy
  2017-03-02 16:38 [PATCH 00/26] bring back stack frame warning with KASAN Arnd Bergmann
                   ` (7 preceding siblings ...)
  2017-03-02 16:38 ` [PATCH 08/26] brcmsmac: make some local variables 'static const' to reduce stack size Arnd Bergmann
@ 2017-03-02 16:38 ` Arnd Bergmann
  2017-03-06  9:31   ` Arend Van Spriel
  2017-03-02 16:38 ` [PATCH 10/26] brcmsmac: reindent split functions Arnd Bergmann
                   ` (17 subsequent siblings)
  26 siblings, 1 reply; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann

The stack consumption in this driver is still relatively high, with one
remaining warning if the warning level is lowered to 1536 bytes:

drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c:17135:1: error: the frame size of 1880 bytes is larger than 1536 bytes [-Werror=frame-larger-than=]

The affected function is actually a collection of three separate implementations,
and each of them is fairly large by itself. Splitting them up is done easily
and improves readability at the same time.

I'm leaving the original indentation to make the review easier.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 .../broadcom/brcm80211/brcmsmac/phy/phy_n.c        | 178 ++++++++++++---------
 1 file changed, 104 insertions(+), 74 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
index 48a4df488d75..d76c092bb6b4 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
@@ -16061,52 +16061,8 @@ static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi)
 	}
 }
 
-static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
+static void wlc_phy_workarounds_nphy_rev7(struct brcms_phy *pi)
 {
-	static const u8 rfseq_rx2tx_events[] = {
-		NPHY_RFSEQ_CMD_NOP,
-		NPHY_RFSEQ_CMD_RXG_FBW,
-		NPHY_RFSEQ_CMD_TR_SWITCH,
-		NPHY_RFSEQ_CMD_CLR_HIQ_DIS,
-		NPHY_RFSEQ_CMD_RXPD_TXPD,
-		NPHY_RFSEQ_CMD_TX_GAIN,
-		NPHY_RFSEQ_CMD_EXT_PA
-	};
-	u8 rfseq_rx2tx_dlys[] = { 8, 6, 6, 2, 4, 60, 1 };
-	static const u8 rfseq_tx2rx_events[] = {
-		NPHY_RFSEQ_CMD_NOP,
-		NPHY_RFSEQ_CMD_EXT_PA,
-		NPHY_RFSEQ_CMD_TX_GAIN,
-		NPHY_RFSEQ_CMD_RXPD_TXPD,
-		NPHY_RFSEQ_CMD_TR_SWITCH,
-		NPHY_RFSEQ_CMD_RXG_FBW,
-		NPHY_RFSEQ_CMD_CLR_HIQ_DIS
-	};
-	static const u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 };
-	static const u8 rfseq_tx2rx_events_rev3[] = {
-		NPHY_REV3_RFSEQ_CMD_EXT_PA,
-		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
-		NPHY_REV3_RFSEQ_CMD_TX_GAIN,
-		NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
-		NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
-		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
-		NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
-		NPHY_REV3_RFSEQ_CMD_END
-	};
-	static const u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 };
-	u8 rfseq_rx2tx_events_rev3[] = {
-		NPHY_REV3_RFSEQ_CMD_NOP,
-		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
-		NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
-		NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
-		NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
-		NPHY_REV3_RFSEQ_CMD_TX_GAIN,
-		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
-		NPHY_REV3_RFSEQ_CMD_EXT_PA,
-		NPHY_REV3_RFSEQ_CMD_END
-	};
-	u8 rfseq_rx2tx_dlys_rev3[] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 };
-
 	static const u8 rfseq_rx2tx_events_rev3_ipa[] = {
 		NPHY_REV3_RFSEQ_CMD_NOP,
 		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
@@ -16120,29 +16076,15 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
 	};
 	static const u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
 	static const u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f };
-
-	s16 alpha0, alpha1, alpha2;
-	s16 beta0, beta1, beta2;
-	u32 leg_data_weights, ht_data_weights, nss1_data_weights,
-	    stbc_data_weights;
+	u32 leg_data_weights;
 	u8 chan_freq_range = 0;
 	static const u16 dac_control = 0x0002;
 	u16 aux_adc_vmid_rev7_core0[] = { 0x8e, 0x96, 0x96, 0x96 };
 	u16 aux_adc_vmid_rev7_core1[] = { 0x8f, 0x9f, 0x9f, 0x96 };
-	u16 aux_adc_vmid_rev4[] = { 0xa2, 0xb4, 0xb4, 0x89 };
-	u16 aux_adc_vmid_rev3[] = { 0xa2, 0xb4, 0xb4, 0x89 };
-	u16 *aux_adc_vmid;
 	u16 aux_adc_gain_rev7[] = { 0x02, 0x02, 0x02, 0x02 };
-	u16 aux_adc_gain_rev4[] = { 0x02, 0x02, 0x02, 0x00 };
-	u16 aux_adc_gain_rev3[] = { 0x02, 0x02, 0x02, 0x00 };
-	u16 *aux_adc_gain;
-	static const u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 };
-	static const u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 };
 	s32 min_nvar_val = 0x18d;
 	s32 min_nvar_offset_6mbps = 20;
 	u8 pdetrange;
-	u8 triso;
-	u16 regval;
 	u16 afectrl_adc_ctrl1_rev7 = 0x20;
 	u16 afectrl_adc_ctrl2_rev7 = 0x0;
 	u16 rfseq_rx2tx_lpf_h_hpc_rev7 = 0x77;
@@ -16171,17 +16113,6 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
 	u16 freq;
 	int coreNum;
 
-	if (CHSPEC_IS5G(pi->radio_chanspec))
-		wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 0);
-	else
-		wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 1);
-
-	if (pi->phyhang_avoid)
-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
-
-	or_phy_reg(pi, 0xb1, NPHY_IQFlip_ADC1 | NPHY_IQFlip_ADC2);
-
-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
 
 		if (NREV_IS(pi->pubpi.phy_rev, 7)) {
 			mod_phy_reg(pi, 0x221, (0x1 << 4), (1 << 4));
@@ -16703,8 +16634,62 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
 					 &aux_adc_gain_rev7);
 		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x1c, 16,
 					 &aux_adc_gain_rev7);
+}
 
-	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+static void wlc_phy_workarounds_nphy_rev3(struct brcms_phy *pi)
+{
+	static const u8 rfseq_tx2rx_events_rev3[] = {
+		NPHY_REV3_RFSEQ_CMD_EXT_PA,
+		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
+		NPHY_REV3_RFSEQ_CMD_TX_GAIN,
+		NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
+		NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
+		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
+		NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
+		NPHY_REV3_RFSEQ_CMD_END
+	};
+	static const u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 };
+	u8 rfseq_rx2tx_events_rev3[] = {
+		NPHY_REV3_RFSEQ_CMD_NOP,
+		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
+		NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
+		NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
+		NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
+		NPHY_REV3_RFSEQ_CMD_TX_GAIN,
+		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
+		NPHY_REV3_RFSEQ_CMD_EXT_PA,
+		NPHY_REV3_RFSEQ_CMD_END
+	};
+	u8 rfseq_rx2tx_dlys_rev3[] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 };
+	static const u8 rfseq_rx2tx_events_rev3_ipa[] = {
+		NPHY_REV3_RFSEQ_CMD_NOP,
+		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
+		NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
+		NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
+		NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
+		NPHY_REV3_RFSEQ_CMD_TX_GAIN,
+		NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS,
+		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
+		NPHY_REV3_RFSEQ_CMD_END
+	};
+	static const u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
+	s16 alpha0, alpha1, alpha2;
+	s16 beta0, beta1, beta2;
+	u32 leg_data_weights, ht_data_weights, nss1_data_weights,
+	    stbc_data_weights;
+	u8 chan_freq_range = 0;
+	static const u16 dac_control = 0x0002;
+	u16 aux_adc_vmid_rev4[] = { 0xa2, 0xb4, 0xb4, 0x89 };
+	u16 aux_adc_vmid_rev3[] = { 0xa2, 0xb4, 0xb4, 0x89 };
+	u16 *aux_adc_vmid;
+	u16 aux_adc_gain_rev4[] = { 0x02, 0x02, 0x02, 0x00 };
+	u16 aux_adc_gain_rev3[] = { 0x02, 0x02, 0x02, 0x00 };
+	u16 *aux_adc_gain;
+	static const u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 };
+	static const u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 };
+	s32 min_nvar_val = 0x18d;
+	u8 pdetrange;
+	u8 triso;
 
 		write_phy_reg(pi, 0x23f, 0x1f8);
 		write_phy_reg(pi, 0x240, 0x1f8);
@@ -17030,7 +17015,33 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
 					      MHF4_BPHY_TXCORE0,
 					      MHF4_BPHY_TXCORE0, BRCM_BAND_ALL);
 		}
-	} else {
+}
+
+void wlc_phy_workarounds_nphy_rev1(struct brcms_phy *pi)
+{
+	static const u8 rfseq_rx2tx_events[] = {
+		NPHY_RFSEQ_CMD_NOP,
+		NPHY_RFSEQ_CMD_RXG_FBW,
+		NPHY_RFSEQ_CMD_TR_SWITCH,
+		NPHY_RFSEQ_CMD_CLR_HIQ_DIS,
+		NPHY_RFSEQ_CMD_RXPD_TXPD,
+		NPHY_RFSEQ_CMD_TX_GAIN,
+		NPHY_RFSEQ_CMD_EXT_PA
+	};
+	u8 rfseq_rx2tx_dlys[] = { 8, 6, 6, 2, 4, 60, 1 };
+	static const u8 rfseq_tx2rx_events[] = {
+		NPHY_RFSEQ_CMD_NOP,
+		NPHY_RFSEQ_CMD_EXT_PA,
+		NPHY_RFSEQ_CMD_TX_GAIN,
+		NPHY_RFSEQ_CMD_RXPD_TXPD,
+		NPHY_RFSEQ_CMD_TR_SWITCH,
+		NPHY_RFSEQ_CMD_RXG_FBW,
+		NPHY_RFSEQ_CMD_CLR_HIQ_DIS
+	};
+	static const u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 };
+	s16 alpha0, alpha1, alpha2;
+	s16 beta0, beta1, beta2;
+	u16 regval;
 
 		if (pi->sh->boardflags2 & BFL2_SKWRKFEM_BRD ||
 		    (pi->sh->boardtype == 0x8b)) {
@@ -17128,7 +17139,26 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
 			mod_phy_reg(pi, 0x221,
 				    NPHY_FORCESIG_DECODEGATEDCLKS,
 				    NPHY_FORCESIG_DECODEGATEDCLKS);
-	}
+}
+
+static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
+{
+	if (CHSPEC_IS5G(pi->radio_chanspec))
+		wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 0);
+	else
+		wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 1);
+
+	if (pi->phyhang_avoid)
+		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+
+	or_phy_reg(pi, 0xb1, NPHY_IQFlip_ADC1 | NPHY_IQFlip_ADC2);
+
+	if (NREV_GE(pi->pubpi.phy_rev, 7))
+		wlc_phy_workarounds_nphy_rev7(pi);
+	else if (NREV_GE(pi->pubpi.phy_rev, 3))
+		wlc_phy_workarounds_nphy_rev3(pi);
+	else
+		wlc_phy_workarounds_nphy_rev1(pi);
 
 	if (pi->phyhang_avoid)
 		wlc_phy_stay_in_carriersearch_nphy(pi, false);
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 10/26] brcmsmac: reindent split functions
  2017-03-02 16:38 [PATCH 00/26] bring back stack frame warning with KASAN Arnd Bergmann
                   ` (8 preceding siblings ...)
  2017-03-02 16:38 ` [PATCH 09/26] brcmsmac: split up wlc_phy_workarounds_nphy Arnd Bergmann
@ 2017-03-02 16:38 ` Arnd Bergmann
  2017-03-06  9:33   ` Arend Van Spriel
  2017-03-02 16:38 ` [PATCH 11/26] rtlwifi: reduce stack usage for KASAN Arnd Bergmann
                   ` (16 subsequent siblings)
  26 siblings, 1 reply; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann

In the previous commit I left the indentation alone to help reviewing
the patch, this one now runs the three new functions through 'indent -kr -8'
with some manual fixups to avoid silliness.

No changes other than whitespace are intended here.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 .../broadcom/brcm80211/brcmsmac/phy/phy_n.c        | 1507 +++++++++-----------
 1 file changed, 697 insertions(+), 810 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
index d76c092bb6b4..9b39789c673d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
@@ -16074,7 +16074,8 @@ static void wlc_phy_workarounds_nphy_rev7(struct brcms_phy *pi)
 		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
 		NPHY_REV3_RFSEQ_CMD_END
 	};
-	static const u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
+	static const u8 rfseq_rx2tx_dlys_rev3_ipa[] =
+		{ 8, 6, 6, 4, 4, 16, 43, 1, 1 };
 	static const u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f };
 	u32 leg_data_weights;
 	u8 chan_freq_range = 0;
@@ -16114,526 +16115,452 @@ static void wlc_phy_workarounds_nphy_rev7(struct brcms_phy *pi)
 	int coreNum;
 
 
-		if (NREV_IS(pi->pubpi.phy_rev, 7)) {
-			mod_phy_reg(pi, 0x221, (0x1 << 4), (1 << 4));
-
-			mod_phy_reg(pi, 0x160, (0x7f << 0), (32 << 0));
-			mod_phy_reg(pi, 0x160, (0x7f << 8), (39 << 8));
-			mod_phy_reg(pi, 0x161, (0x7f << 0), (46 << 0));
-			mod_phy_reg(pi, 0x161, (0x7f << 8), (51 << 8));
-			mod_phy_reg(pi, 0x162, (0x7f << 0), (55 << 0));
-			mod_phy_reg(pi, 0x162, (0x7f << 8), (58 << 8));
-			mod_phy_reg(pi, 0x163, (0x7f << 0), (60 << 0));
-			mod_phy_reg(pi, 0x163, (0x7f << 8), (62 << 8));
-			mod_phy_reg(pi, 0x164, (0x7f << 0), (62 << 0));
-			mod_phy_reg(pi, 0x164, (0x7f << 8), (63 << 8));
-			mod_phy_reg(pi, 0x165, (0x7f << 0), (63 << 0));
-			mod_phy_reg(pi, 0x165, (0x7f << 8), (64 << 8));
-			mod_phy_reg(pi, 0x166, (0x7f << 0), (64 << 0));
-			mod_phy_reg(pi, 0x166, (0x7f << 8), (64 << 8));
-			mod_phy_reg(pi, 0x167, (0x7f << 0), (64 << 0));
-			mod_phy_reg(pi, 0x167, (0x7f << 8), (64 << 8));
-		}
-
-		if (NREV_LE(pi->pubpi.phy_rev, 8)) {
-			write_phy_reg(pi, 0x23f, 0x1b0);
-			write_phy_reg(pi, 0x240, 0x1b0);
-		}
+	if (NREV_IS(pi->pubpi.phy_rev, 7)) {
+		mod_phy_reg(pi, 0x221, (0x1 << 4), (1 << 4));
+
+		mod_phy_reg(pi, 0x160, (0x7f << 0), (32 << 0));
+		mod_phy_reg(pi, 0x160, (0x7f << 8), (39 << 8));
+		mod_phy_reg(pi, 0x161, (0x7f << 0), (46 << 0));
+		mod_phy_reg(pi, 0x161, (0x7f << 8), (51 << 8));
+		mod_phy_reg(pi, 0x162, (0x7f << 0), (55 << 0));
+		mod_phy_reg(pi, 0x162, (0x7f << 8), (58 << 8));
+		mod_phy_reg(pi, 0x163, (0x7f << 0), (60 << 0));
+		mod_phy_reg(pi, 0x163, (0x7f << 8), (62 << 8));
+		mod_phy_reg(pi, 0x164, (0x7f << 0), (62 << 0));
+		mod_phy_reg(pi, 0x164, (0x7f << 8), (63 << 8));
+		mod_phy_reg(pi, 0x165, (0x7f << 0), (63 << 0));
+		mod_phy_reg(pi, 0x165, (0x7f << 8), (64 << 8));
+		mod_phy_reg(pi, 0x166, (0x7f << 0), (64 << 0));
+		mod_phy_reg(pi, 0x166, (0x7f << 8), (64 << 8));
+		mod_phy_reg(pi, 0x167, (0x7f << 0), (64 << 0));
+		mod_phy_reg(pi, 0x167, (0x7f << 8), (64 << 8));
+	}
 
-		if (NREV_GE(pi->pubpi.phy_rev, 8))
-			mod_phy_reg(pi, 0xbd, (0xff << 0), (114 << 0));
+	if (NREV_LE(pi->pubpi.phy_rev, 8)) {
+		write_phy_reg(pi, 0x23f, 0x1b0);
+		write_phy_reg(pi, 0x240, 0x1b0);
+	}
 
-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16,
-					 &dac_control);
-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x10, 16,
-					 &dac_control);
+	if (NREV_GE(pi->pubpi.phy_rev, 8))
+		mod_phy_reg(pi, 0xbd, (0xff << 0), (114 << 0));
 
-		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
-					1, 0, 32, &leg_data_weights);
-		leg_data_weights = leg_data_weights & 0xffffff;
-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
-					 1, 0, 32, &leg_data_weights);
+	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16,
+				 &dac_control);
+	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x10, 16,
+				 &dac_control);
 
-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
-					 2, 0x15e, 16,
-					 rfseq_rx2tx_dacbufpu_rev7);
-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x16e, 16,
-					 rfseq_rx2tx_dacbufpu_rev7);
+	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
+				1, 0, 32, &leg_data_weights);
+	leg_data_weights = leg_data_weights & 0xffffff;
+	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
+				 1, 0, 32, &leg_data_weights);
 
-		if (PHY_IPA(pi))
-			wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
-					       rfseq_rx2tx_events_rev3_ipa,
-					       rfseq_rx2tx_dlys_rev3_ipa,
-					       ARRAY_SIZE(rfseq_rx2tx_events_rev3_ipa));
+	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+				 2, 0x15e, 16, rfseq_rx2tx_dacbufpu_rev7);
+	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x16e, 16,
+				 rfseq_rx2tx_dacbufpu_rev7);
 
-		mod_phy_reg(pi, 0x299, (0x3 << 14), (0x1 << 14));
-		mod_phy_reg(pi, 0x29d, (0x3 << 14), (0x1 << 14));
+	if (PHY_IPA(pi))
+		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
+				       rfseq_rx2tx_events_rev3_ipa,
+				       rfseq_rx2tx_dlys_rev3_ipa,
+				       ARRAY_SIZE
+				       (rfseq_rx2tx_events_rev3_ipa));
 
-		tx_lpf_bw_ofdm_20mhz = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x154);
-		tx_lpf_bw_ofdm_40mhz = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x159);
-		tx_lpf_bw_11b = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x152);
+	mod_phy_reg(pi, 0x299, (0x3 << 14), (0x1 << 14));
+	mod_phy_reg(pi, 0x29d, (0x3 << 14), (0x1 << 14));
 
-		if (PHY_IPA(pi)) {
+	tx_lpf_bw_ofdm_20mhz = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x154);
+	tx_lpf_bw_ofdm_40mhz = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x159);
+	tx_lpf_bw_11b = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x152);
 
-			if (((pi->pubpi.radiorev == 5)
-			     && (CHSPEC_IS40(pi->radio_chanspec) == 1))
-			    || (pi->pubpi.radiorev == 7)
-			    || (pi->pubpi.radiorev == 8)) {
+	if (PHY_IPA(pi)) {
 
-				rccal_bcap_val =
-					read_radio_reg(
-						pi,
-						RADIO_2057_RCCAL_BCAP_VAL);
-				rccal_scap_val =
-					read_radio_reg(
-						pi,
-						RADIO_2057_RCCAL_SCAP_VAL);
+		if (((pi->pubpi.radiorev == 5)
+		     && (CHSPEC_IS40(pi->radio_chanspec) == 1))
+		    || (pi->pubpi.radiorev == 7)
+		    || (pi->pubpi.radiorev == 8)) {
 
-				rccal_tx20_11b_bcap = rccal_bcap_val;
-				rccal_tx20_11b_scap = rccal_scap_val;
+			rccal_bcap_val =
+			    read_radio_reg(pi, RADIO_2057_RCCAL_BCAP_VAL);
+			rccal_scap_val =
+			    read_radio_reg(pi, RADIO_2057_RCCAL_SCAP_VAL);
 
-				if ((pi->pubpi.radiorev == 5) &&
-				    (CHSPEC_IS40(pi->radio_chanspec) == 1)) {
+			rccal_tx20_11b_bcap = rccal_bcap_val;
+			rccal_tx20_11b_scap = rccal_scap_val;
 
-					rccal_tx20_11n_bcap = rccal_bcap_val;
-					rccal_tx20_11n_scap = rccal_scap_val;
-					rccal_tx40_11n_bcap = 0xc;
-					rccal_tx40_11n_scap = 0xc;
+			if ((pi->pubpi.radiorev == 5) &&
+			    (CHSPEC_IS40(pi->radio_chanspec) == 1)) {
 
-					rccal_ovrd = true;
+				rccal_tx20_11n_bcap = rccal_bcap_val;
+				rccal_tx20_11n_scap = rccal_scap_val;
+				rccal_tx40_11n_bcap = 0xc;
+				rccal_tx40_11n_scap = 0xc;
 
-				} else if ((pi->pubpi.radiorev == 7)
-					   || (pi->pubpi.radiorev == 8)) {
+				rccal_ovrd = true;
 
-					tx_lpf_bw_ofdm_20mhz = 4;
-					tx_lpf_bw_11b = 1;
+			} else if ((pi->pubpi.radiorev == 7)
+				   || (pi->pubpi.radiorev == 8)) {
 
-					if (CHSPEC_IS2G(pi->radio_chanspec)) {
-						rccal_tx20_11n_bcap = 0xc;
-						rccal_tx20_11n_scap = 0xc;
-						rccal_tx40_11n_bcap = 0xa;
-						rccal_tx40_11n_scap = 0xa;
-					} else {
-						rccal_tx20_11n_bcap = 0x14;
-						rccal_tx20_11n_scap = 0x14;
-						rccal_tx40_11n_bcap = 0xf;
-						rccal_tx40_11n_scap = 0xf;
-					}
+				tx_lpf_bw_ofdm_20mhz = 4;
+				tx_lpf_bw_11b = 1;
 
-					rccal_ovrd = true;
+				if (CHSPEC_IS2G(pi->radio_chanspec)) {
+					rccal_tx20_11n_bcap = 0xc;
+					rccal_tx20_11n_scap = 0xc;
+					rccal_tx40_11n_bcap = 0xa;
+					rccal_tx40_11n_scap = 0xa;
+				} else {
+					rccal_tx20_11n_bcap = 0x14;
+					rccal_tx20_11n_scap = 0x14;
+					rccal_tx40_11n_bcap = 0xf;
+					rccal_tx40_11n_scap = 0xf;
 				}
+
+				rccal_ovrd = true;
 			}
+		}
 
-		} else {
+	} else {
 
-			if (pi->pubpi.radiorev == 5) {
+		if (pi->pubpi.radiorev == 5) {
 
-				tx_lpf_bw_ofdm_20mhz = 1;
-				tx_lpf_bw_ofdm_40mhz = 3;
+			tx_lpf_bw_ofdm_20mhz = 1;
+			tx_lpf_bw_ofdm_40mhz = 3;
 
-				rccal_bcap_val =
-					read_radio_reg(
-						pi,
-						RADIO_2057_RCCAL_BCAP_VAL);
-				rccal_scap_val =
-					read_radio_reg(
-						pi,
-						RADIO_2057_RCCAL_SCAP_VAL);
+			rccal_bcap_val =
+			    read_radio_reg(pi, RADIO_2057_RCCAL_BCAP_VAL);
+			rccal_scap_val =
+			    read_radio_reg(pi, RADIO_2057_RCCAL_SCAP_VAL);
 
-				rccal_tx20_11b_bcap = rccal_bcap_val;
-				rccal_tx20_11b_scap = rccal_scap_val;
+			rccal_tx20_11b_bcap = rccal_bcap_val;
+			rccal_tx20_11b_scap = rccal_scap_val;
 
-				rccal_tx20_11n_bcap = 0x13;
-				rccal_tx20_11n_scap = 0x11;
-				rccal_tx40_11n_bcap = 0x13;
-				rccal_tx40_11n_scap = 0x11;
+			rccal_tx20_11n_bcap = 0x13;
+			rccal_tx20_11n_scap = 0x11;
+			rccal_tx40_11n_bcap = 0x13;
+			rccal_tx40_11n_scap = 0x11;
 
-				rccal_ovrd = true;
-			}
+			rccal_ovrd = true;
 		}
+	}
 
-		if (rccal_ovrd) {
-
-			rx2tx_lpf_rc_lut_tx20_11b =
-				(rccal_tx20_11b_bcap << 8) |
-				(rccal_tx20_11b_scap << 3) |
-				tx_lpf_bw_11b;
-			rx2tx_lpf_rc_lut_tx20_11n =
-				(rccal_tx20_11n_bcap << 8) |
-				(rccal_tx20_11n_scap << 3) |
-				tx_lpf_bw_ofdm_20mhz;
-			rx2tx_lpf_rc_lut_tx40_11n =
-				(rccal_tx40_11n_bcap << 8) |
-				(rccal_tx40_11n_scap << 3) |
-				tx_lpf_bw_ofdm_40mhz;
+	if (rccal_ovrd) {
 
-			for (coreNum = 0; coreNum <= 1; coreNum++) {
-				wlc_phy_table_write_nphy(
-					pi, NPHY_TBL_ID_RFSEQ,
-					1,
-					0x152 + coreNum * 0x10,
-					16,
-					&rx2tx_lpf_rc_lut_tx20_11b);
-				wlc_phy_table_write_nphy(
-					pi, NPHY_TBL_ID_RFSEQ,
-					1,
-					0x153 + coreNum * 0x10,
-					16,
-					&rx2tx_lpf_rc_lut_tx20_11n);
-				wlc_phy_table_write_nphy(
-					pi, NPHY_TBL_ID_RFSEQ,
-					1,
-					0x154 + coreNum * 0x10,
-					16,
-					&rx2tx_lpf_rc_lut_tx20_11n);
-				wlc_phy_table_write_nphy(
-					pi, NPHY_TBL_ID_RFSEQ,
-					1,
-					0x155 + coreNum * 0x10,
-					16,
-					&rx2tx_lpf_rc_lut_tx40_11n);
-				wlc_phy_table_write_nphy(
-					pi, NPHY_TBL_ID_RFSEQ,
-					1,
-					0x156 + coreNum * 0x10,
-					16,
-					&rx2tx_lpf_rc_lut_tx40_11n);
-				wlc_phy_table_write_nphy(
-					pi, NPHY_TBL_ID_RFSEQ,
-					1,
-					0x157 + coreNum * 0x10,
-					16,
-					&rx2tx_lpf_rc_lut_tx40_11n);
-				wlc_phy_table_write_nphy(
-					pi, NPHY_TBL_ID_RFSEQ,
-					1,
-					0x158 + coreNum * 0x10,
-					16,
-					&rx2tx_lpf_rc_lut_tx40_11n);
-				wlc_phy_table_write_nphy(
-					pi, NPHY_TBL_ID_RFSEQ,
-					1,
-					0x159 + coreNum * 0x10,
-					16,
-					&rx2tx_lpf_rc_lut_tx40_11n);
-			}
+		rx2tx_lpf_rc_lut_tx20_11b =
+		    (rccal_tx20_11b_bcap << 8) |
+		    (rccal_tx20_11b_scap << 3) | tx_lpf_bw_11b;
+		rx2tx_lpf_rc_lut_tx20_11n =
+		    (rccal_tx20_11n_bcap << 8) |
+		    (rccal_tx20_11n_scap << 3) | tx_lpf_bw_ofdm_20mhz;
+		rx2tx_lpf_rc_lut_tx40_11n =
+		    (rccal_tx40_11n_bcap << 8) |
+		    (rccal_tx40_11n_scap << 3) | tx_lpf_bw_ofdm_40mhz;
 
-			wlc_phy_rfctrl_override_nphy_rev7(
-				pi, (0x1 << 4),
-				1, 0x3, 0,
-				NPHY_REV7_RFCTRLOVERRIDE_ID2);
+		for (coreNum = 0; coreNum <= 1; coreNum++) {
+			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
+						 0x152 + coreNum * 0x10, 16,
+						 &rx2tx_lpf_rc_lut_tx20_11b);
+			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
+						 0x153 + coreNum * 0x10, 16,
+						 &rx2tx_lpf_rc_lut_tx20_11n);
+			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
+						 0x154 + coreNum * 0x10, 16,
+						 &rx2tx_lpf_rc_lut_tx20_11n);
+			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
+						 0x155 + coreNum * 0x10, 16,
+						 &rx2tx_lpf_rc_lut_tx40_11n);
+			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
+						 0x156 + coreNum * 0x10, 16,
+						 &rx2tx_lpf_rc_lut_tx40_11n);
+			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
+						 0x157 + coreNum * 0x10, 16,
+						 &rx2tx_lpf_rc_lut_tx40_11n);
+			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
+						 0x158 + coreNum * 0x10, 16,
+						 &rx2tx_lpf_rc_lut_tx40_11n);
+			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
+						 0x159 + coreNum * 0x10, 16,
+						 &rx2tx_lpf_rc_lut_tx40_11n);
 		}
 
-		write_phy_reg(pi, 0x32f, 0x3);
+		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 1, 0x3, 0,
+						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
+	}
 
-		if ((pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6))
-			wlc_phy_rfctrl_override_nphy_rev7(
-				pi, (0x1 << 2),
-				1, 0x3, 0,
-				NPHY_REV7_RFCTRLOVERRIDE_ID0);
+	write_phy_reg(pi, 0x32f, 0x3);
 
-		if ((pi->pubpi.radiorev == 3) || (pi->pubpi.radiorev == 4) ||
-		    (pi->pubpi.radiorev == 6)) {
-			if ((pi->sh->sromrev >= 8)
-			    && (pi->sh->boardflags2 & BFL2_IPALVLSHIFT_3P3))
-				ipalvlshift_3p3_war_en = 1;
-
-			if (ipalvlshift_3p3_war_en) {
-				write_radio_reg(pi, RADIO_2057_GPAIO_CONFIG,
-						0x5);
-				write_radio_reg(pi, RADIO_2057_GPAIO_SEL1,
-						0x30);
-				write_radio_reg(pi, RADIO_2057_GPAIO_SEL0, 0x0);
-				or_radio_reg(pi,
-					     RADIO_2057_RXTXBIAS_CONFIG_CORE0,
-					     0x1);
-				or_radio_reg(pi,
-					     RADIO_2057_RXTXBIAS_CONFIG_CORE1,
-					     0x1);
-
-				ipa2g_mainbias = 0x1f;
-
-				ipa2g_casconv = 0x6f;
-
-				ipa2g_biasfilt = 0xaa;
-			} else {
+	if ((pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6))
+		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 1, 0x3, 0,
+						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
 
-				ipa2g_mainbias = 0x2b;
+	if ((pi->pubpi.radiorev == 3) || (pi->pubpi.radiorev == 4) ||
+	    (pi->pubpi.radiorev == 6)) {
+		if ((pi->sh->sromrev >= 8)
+		    && (pi->sh->boardflags2 & BFL2_IPALVLSHIFT_3P3))
+			ipalvlshift_3p3_war_en = 1;
 
-				ipa2g_casconv = 0x7f;
+		if (ipalvlshift_3p3_war_en) {
+			write_radio_reg(pi, RADIO_2057_GPAIO_CONFIG, 0x5);
+			write_radio_reg(pi, RADIO_2057_GPAIO_SEL1, 0x30);
+			write_radio_reg(pi, RADIO_2057_GPAIO_SEL0, 0x0);
+			or_radio_reg(pi, RADIO_2057_RXTXBIAS_CONFIG_CORE0, 0x1);
+			or_radio_reg(pi, RADIO_2057_RXTXBIAS_CONFIG_CORE1, 0x1);
 
-				ipa2g_biasfilt = 0xee;
-			}
+			ipa2g_mainbias = 0x1f;
 
-			if (CHSPEC_IS2G(pi->radio_chanspec)) {
-				for (coreNum = 0; coreNum <= 1; coreNum++) {
-					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
-							 coreNum, IPA2G_IMAIN,
-							 ipa2g_mainbias);
-					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
-							 coreNum, IPA2G_CASCONV,
-							 ipa2g_casconv);
-					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
-							 coreNum,
-							 IPA2G_BIAS_FILTER,
-							 ipa2g_biasfilt);
-				}
-			}
-		}
+			ipa2g_casconv = 0x6f;
 
-		if (PHY_IPA(pi)) {
-			if (CHSPEC_IS2G(pi->radio_chanspec)) {
-				if ((pi->pubpi.radiorev == 3)
-				    || (pi->pubpi.radiorev == 4)
-				    || (pi->pubpi.radiorev == 6))
-					txgm_idac_bleed = 0x7f;
+			ipa2g_biasfilt = 0xaa;
+		} else {
 
-				for (coreNum = 0; coreNum <= 1; coreNum++) {
-					if (txgm_idac_bleed != 0)
-						WRITE_RADIO_REG4(
-							pi, RADIO_2057,
-							CORE, coreNum,
-							TXGM_IDAC_BLEED,
-							txgm_idac_bleed);
-				}
+			ipa2g_mainbias = 0x2b;
 
-				if (pi->pubpi.radiorev == 5) {
-
-					for (coreNum = 0; coreNum <= 1;
-					     coreNum++) {
-						WRITE_RADIO_REG4(pi, RADIO_2057,
-								 CORE, coreNum,
-								 IPA2G_CASCONV,
-								 0x13);
-						WRITE_RADIO_REG4(pi, RADIO_2057,
-								 CORE, coreNum,
-								 IPA2G_IMAIN,
-								 0x1f);
-						WRITE_RADIO_REG4(
-							pi, RADIO_2057,
-							CORE, coreNum,
-							IPA2G_BIAS_FILTER,
-							0xee);
-						WRITE_RADIO_REG4(pi, RADIO_2057,
-								 CORE, coreNum,
-								 PAD2G_IDACS,
-								 0x8a);
-						WRITE_RADIO_REG4(
-							pi, RADIO_2057,
-							CORE, coreNum,
-							PAD_BIAS_FILTER_BWS,
-							0x3e);
-					}
+			ipa2g_casconv = 0x7f;
 
-				} else if ((pi->pubpi.radiorev == 7)
-					   || (pi->pubpi.radiorev == 8)) {
+			ipa2g_biasfilt = 0xee;
+		}
 
-					if (CHSPEC_IS40(pi->radio_chanspec) ==
-					    0) {
-						WRITE_RADIO_REG4(pi, RADIO_2057,
-								 CORE, 0,
-								 IPA2G_IMAIN,
-								 0x14);
-						WRITE_RADIO_REG4(pi, RADIO_2057,
-								 CORE, 1,
-								 IPA2G_IMAIN,
-								 0x12);
-					} else {
-						WRITE_RADIO_REG4(pi, RADIO_2057,
-								 CORE, 0,
-								 IPA2G_IMAIN,
-								 0x16);
-						WRITE_RADIO_REG4(pi, RADIO_2057,
-								 CORE, 1,
-								 IPA2G_IMAIN,
-								 0x16);
-					}
-				}
+		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+			for (coreNum = 0; coreNum <= 1; coreNum++) {
+				WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
+						 coreNum, IPA2G_IMAIN,
+						 ipa2g_mainbias);
+				WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
+						 coreNum, IPA2G_CASCONV,
+						 ipa2g_casconv);
+				WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
+						 coreNum,
+						 IPA2G_BIAS_FILTER,
+						 ipa2g_biasfilt);
+			}
+		}
+	}
 
-			} else {
-				freq = CHAN5G_FREQ(CHSPEC_CHANNEL(
-							pi->radio_chanspec));
-				if (((freq >= 5180) && (freq <= 5230))
-				    || ((freq >= 5745) && (freq <= 5805))) {
-					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
-							 0, IPA5G_BIAS_FILTER,
-							 0xff);
-					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
-							 1, IPA5G_BIAS_FILTER,
-							 0xff);
-				}
+	if (PHY_IPA(pi)) {
+		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+			if ((pi->pubpi.radiorev == 3)
+			    || (pi->pubpi.radiorev == 4)
+			    || (pi->pubpi.radiorev == 6))
+				txgm_idac_bleed = 0x7f;
+
+			for (coreNum = 0; coreNum <= 1; coreNum++) {
+				if (txgm_idac_bleed != 0)
+					WRITE_RADIO_REG4(pi, RADIO_2057,
+							 CORE, coreNum,
+							 TXGM_IDAC_BLEED,
+							 txgm_idac_bleed);
 			}
-		} else {
 
-			if (pi->pubpi.radiorev != 5) {
+			if (pi->pubpi.radiorev == 5) {
 				for (coreNum = 0; coreNum <= 1; coreNum++) {
+					WRITE_RADIO_REG4(pi, RADIO_2057,
+							 CORE, coreNum,
+							 IPA2G_CASCONV,
+							 0x13);
+					WRITE_RADIO_REG4(pi, RADIO_2057,
+							 CORE, coreNum,
+							 IPA2G_IMAIN,
+							 0x1f);
+					WRITE_RADIO_REG4(pi, RADIO_2057,
+							 CORE, coreNum,
+							 IPA2G_BIAS_FILTER,
+							 0xee);
+					WRITE_RADIO_REG4(pi, RADIO_2057,
+							 CORE, coreNum,
+							 PAD2G_IDACS,
+							 0x8a);
+					WRITE_RADIO_REG4(pi, RADIO_2057,
+							 CORE, coreNum,
+							 PAD_BIAS_FILTER_BWS,
+							 0x3e);
+				}
+			} else if ((pi->pubpi.radiorev == 7) ||
+				   (pi->pubpi.radiorev == 8)) {
+
+				if (CHSPEC_IS40(pi->radio_chanspec) == 0) {
+					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
+							 0, IPA2G_IMAIN, 0x14);
+					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
+							 1, IPA2G_IMAIN, 0x12);
+				} else {
 					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
-							 coreNum,
-							 TXMIX2G_TUNE_BOOST_PU,
-							 0x61);
+							 0, IPA2G_IMAIN, 0x16);
 					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
-							 coreNum,
-							 TXGM_IDAC_BLEED, 0x70);
+							 1, IPA2G_IMAIN, 0x16);
 				}
 			}
-		}
 
-		if (pi->pubpi.radiorev == 4) {
-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
-						 0x05, 16,
-						 &afectrl_adc_ctrl1_rev7);
-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
-						 0x15, 16,
-						 &afectrl_adc_ctrl1_rev7);
+		} else {
+			freq =
+			    CHAN5G_FREQ(CHSPEC_CHANNEL
+					(pi->radio_chanspec));
+			if (((freq >= 5180) && (freq <= 5230))
+			    || ((freq >= 5745) && (freq <= 5805))) {
+				WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
+						 0, IPA5G_BIAS_FILTER, 0xff);
+				WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
+						 1, IPA5G_BIAS_FILTER, 0xff);
+			}
+		}
+	} else {
 
+		if (pi->pubpi.radiorev != 5) {
 			for (coreNum = 0; coreNum <= 1; coreNum++) {
 				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
-						 AFE_VCM_CAL_MASTER, 0x0);
-				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
-						 AFE_SET_VCM_I, 0x3f);
+						 TXMIX2G_TUNE_BOOST_PU, 0x61);
 				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
-						 AFE_SET_VCM_Q, 0x3f);
+						 TXGM_IDAC_BLEED, 0x70);
 			}
-		} else {
-			mod_phy_reg(pi, 0xa6, (0x1 << 2), (0x1 << 2));
-			mod_phy_reg(pi, 0x8f, (0x1 << 2), (0x1 << 2));
-			mod_phy_reg(pi, 0xa7, (0x1 << 2), (0x1 << 2));
-			mod_phy_reg(pi, 0xa5, (0x1 << 2), (0x1 << 2));
-
-			mod_phy_reg(pi, 0xa6, (0x1 << 0), 0);
-			mod_phy_reg(pi, 0x8f, (0x1 << 0), (0x1 << 0));
-			mod_phy_reg(pi, 0xa7, (0x1 << 0), 0);
-			mod_phy_reg(pi, 0xa5, (0x1 << 0), (0x1 << 0));
-
-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
-						 0x05, 16,
-						 &afectrl_adc_ctrl2_rev7);
-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
-						 0x15, 16,
-						 &afectrl_adc_ctrl2_rev7);
-
-			mod_phy_reg(pi, 0xa6, (0x1 << 2), 0);
-			mod_phy_reg(pi, 0x8f, (0x1 << 2), 0);
-			mod_phy_reg(pi, 0xa7, (0x1 << 2), 0);
-			mod_phy_reg(pi, 0xa5, (0x1 << 2), 0);
 		}
+	}
 
-		write_phy_reg(pi, 0x6a, 0x2);
+	if (pi->pubpi.radiorev == 4) {
+		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x05, 16,
+					 &afectrl_adc_ctrl1_rev7);
+		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x15, 16,
+					 &afectrl_adc_ctrl1_rev7);
 
-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 256, 32,
-					 &min_nvar_offset_6mbps);
+		for (coreNum = 0; coreNum <= 1; coreNum++) {
+			WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
+					 AFE_VCM_CAL_MASTER, 0x0);
+			WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
+					 AFE_SET_VCM_I, 0x3f);
+			WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
+					 AFE_SET_VCM_Q, 0x3f);
+		}
+	} else {
+		mod_phy_reg(pi, 0xa6, (0x1 << 2), (0x1 << 2));
+		mod_phy_reg(pi, 0x8f, (0x1 << 2), (0x1 << 2));
+		mod_phy_reg(pi, 0xa7, (0x1 << 2), (0x1 << 2));
+		mod_phy_reg(pi, 0xa5, (0x1 << 2), (0x1 << 2));
 
-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x138, 16,
-					 &rfseq_pktgn_lpf_hpc_rev7);
+		mod_phy_reg(pi, 0xa6, (0x1 << 0), 0);
+		mod_phy_reg(pi, 0x8f, (0x1 << 0), (0x1 << 0));
+		mod_phy_reg(pi, 0xa7, (0x1 << 0), 0);
+		mod_phy_reg(pi, 0xa5, (0x1 << 0), (0x1 << 0));
 
-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x141, 16,
-					 &rfseq_pktgn_lpf_h_hpc_rev7);
+		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x05, 16,
+					 &afectrl_adc_ctrl2_rev7);
+		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x15, 16,
+					 &afectrl_adc_ctrl2_rev7);
 
-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 3, 0x133, 16,
-					 &rfseq_htpktgn_lpf_hpc_rev7);
+		mod_phy_reg(pi, 0xa6, (0x1 << 2), 0);
+		mod_phy_reg(pi, 0x8f, (0x1 << 2), 0);
+		mod_phy_reg(pi, 0xa7, (0x1 << 2), 0);
+		mod_phy_reg(pi, 0xa5, (0x1 << 2), 0);
+	}
 
-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x146, 16,
-					 &rfseq_cckpktgn_lpf_hpc_rev7);
+	write_phy_reg(pi, 0x6a, 0x2);
 
-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x123, 16,
-					 &rfseq_tx2rx_lpf_h_hpc_rev7);
+	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 256, 32,
+				 &min_nvar_offset_6mbps);
 
-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x12A, 16,
-					 &rfseq_rx2tx_lpf_h_hpc_rev7);
+	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x138, 16,
+				 &rfseq_pktgn_lpf_hpc_rev7);
 
-		if (CHSPEC_IS40(pi->radio_chanspec) == 0) {
-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
-						 32, &min_nvar_val);
-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
-						 127, 32, &min_nvar_val);
-		} else {
-			min_nvar_val = noise_var_tbl_rev7[3];
-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
-						 32, &min_nvar_val);
+	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x141, 16,
+				 &rfseq_pktgn_lpf_h_hpc_rev7);
 
-			min_nvar_val = noise_var_tbl_rev7[127];
-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
-						 127, 32, &min_nvar_val);
-		}
+	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 3, 0x133, 16,
+				 &rfseq_htpktgn_lpf_hpc_rev7);
 
-		wlc_phy_workarounds_nphy_gainctrl(pi);
+	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x146, 16,
+				 &rfseq_cckpktgn_lpf_hpc_rev7);
 
-		pdetrange =
-			(CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
-			pdetrange : pi->srom_fem2g.pdetrange;
+	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x123, 16,
+				 &rfseq_tx2rx_lpf_h_hpc_rev7);
 
-		if (pdetrange == 0) {
-			chan_freq_range =
-				wlc_phy_get_chan_freq_range_nphy(pi, 0);
-			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
-				aux_adc_vmid_rev7_core0[3] = 0x70;
-				aux_adc_vmid_rev7_core1[3] = 0x70;
-				aux_adc_gain_rev7[3] = 2;
-			} else {
-				aux_adc_vmid_rev7_core0[3] = 0x80;
-				aux_adc_vmid_rev7_core1[3] = 0x80;
-				aux_adc_gain_rev7[3] = 3;
-			}
-		} else if (pdetrange == 1) {
-			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
-				aux_adc_vmid_rev7_core0[3] = 0x7c;
-				aux_adc_vmid_rev7_core1[3] = 0x7c;
-				aux_adc_gain_rev7[3] = 2;
-			} else {
-				aux_adc_vmid_rev7_core0[3] = 0x8c;
-				aux_adc_vmid_rev7_core1[3] = 0x8c;
-				aux_adc_gain_rev7[3] = 1;
-			}
-		} else if (pdetrange == 2) {
-			if (pi->pubpi.radioid == BCM2057_ID) {
-				if ((pi->pubpi.radiorev == 5)
-				    || (pi->pubpi.radiorev == 7)
-				    || (pi->pubpi.radiorev == 8)) {
-					if (chan_freq_range ==
-					    WL_CHAN_FREQ_RANGE_2G) {
-						aux_adc_vmid_rev7_core0[3] =
-							0x8c;
-						aux_adc_vmid_rev7_core1[3] =
-							0x8c;
-						aux_adc_gain_rev7[3] = 0;
-					} else {
-						aux_adc_vmid_rev7_core0[3] =
-							0x96;
-						aux_adc_vmid_rev7_core1[3] =
-							0x96;
-						aux_adc_gain_rev7[3] = 0;
-					}
+	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x12A, 16,
+				 &rfseq_rx2tx_lpf_h_hpc_rev7);
+
+	if (CHSPEC_IS40(pi->radio_chanspec) == 0) {
+		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
+					 32, &min_nvar_val);
+		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
+					 127, 32, &min_nvar_val);
+	} else {
+		min_nvar_val = noise_var_tbl_rev7[3];
+		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
+					 32, &min_nvar_val);
+
+		min_nvar_val = noise_var_tbl_rev7[127];
+		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
+					 127, 32, &min_nvar_val);
+	}
+
+	wlc_phy_workarounds_nphy_gainctrl(pi);
+
+	pdetrange = (CHSPEC_IS5G(pi->radio_chanspec)) ?
+		    pi->srom_fem5g.pdetrange : pi->srom_fem2g.pdetrange;
+
+	if (pdetrange == 0) {
+		chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0);
+		if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
+			aux_adc_vmid_rev7_core0[3] = 0x70;
+			aux_adc_vmid_rev7_core1[3] = 0x70;
+			aux_adc_gain_rev7[3] = 2;
+		} else {
+			aux_adc_vmid_rev7_core0[3] = 0x80;
+			aux_adc_vmid_rev7_core1[3] = 0x80;
+			aux_adc_gain_rev7[3] = 3;
+		}
+	} else if (pdetrange == 1) {
+		if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
+			aux_adc_vmid_rev7_core0[3] = 0x7c;
+			aux_adc_vmid_rev7_core1[3] = 0x7c;
+			aux_adc_gain_rev7[3] = 2;
+		} else {
+			aux_adc_vmid_rev7_core0[3] = 0x8c;
+			aux_adc_vmid_rev7_core1[3] = 0x8c;
+			aux_adc_gain_rev7[3] = 1;
+		}
+	} else if (pdetrange == 2) {
+		if (pi->pubpi.radioid == BCM2057_ID) {
+			if ((pi->pubpi.radiorev == 5)
+			    || (pi->pubpi.radiorev == 7)
+			    || (pi->pubpi.radiorev == 8)) {
+				if (chan_freq_range ==
+				    WL_CHAN_FREQ_RANGE_2G) {
+					aux_adc_vmid_rev7_core0[3] = 0x8c;
+					aux_adc_vmid_rev7_core1[3] = 0x8c;
+					aux_adc_gain_rev7[3] = 0;
+				} else {
+					aux_adc_vmid_rev7_core0[3] = 0x96;
+					aux_adc_vmid_rev7_core1[3] = 0x96;
+					aux_adc_gain_rev7[3] = 0;
 				}
 			}
+		}
 
-		} else if (pdetrange == 3) {
-			if (chan_freq_range == WL_CHAN_FREQ_RANGE_2G) {
-				aux_adc_vmid_rev7_core0[3] = 0x89;
-				aux_adc_vmid_rev7_core1[3] = 0x89;
-				aux_adc_gain_rev7[3] = 0;
-			}
+	} else if (pdetrange == 3) {
+		if (chan_freq_range == WL_CHAN_FREQ_RANGE_2G) {
+			aux_adc_vmid_rev7_core0[3] = 0x89;
+			aux_adc_vmid_rev7_core1[3] = 0x89;
+			aux_adc_gain_rev7[3] = 0;
+		}
 
-		} else if (pdetrange == 5) {
+	} else if (pdetrange == 5) {
 
-			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
-				aux_adc_vmid_rev7_core0[3] = 0x80;
-				aux_adc_vmid_rev7_core1[3] = 0x80;
-				aux_adc_gain_rev7[3] = 3;
-			} else {
-				aux_adc_vmid_rev7_core0[3] = 0x70;
-				aux_adc_vmid_rev7_core1[3] = 0x70;
-				aux_adc_gain_rev7[3] = 2;
-			}
+		if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
+			aux_adc_vmid_rev7_core0[3] = 0x80;
+			aux_adc_vmid_rev7_core1[3] = 0x80;
+			aux_adc_gain_rev7[3] = 3;
+		} else {
+			aux_adc_vmid_rev7_core0[3] = 0x70;
+			aux_adc_vmid_rev7_core1[3] = 0x70;
+			aux_adc_gain_rev7[3] = 2;
 		}
+	}
 
-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x08, 16,
-					 &aux_adc_vmid_rev7_core0);
-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x18, 16,
-					 &aux_adc_vmid_rev7_core1);
-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x0c, 16,
-					 &aux_adc_gain_rev7);
-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x1c, 16,
-					 &aux_adc_gain_rev7);
+	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x08, 16,
+				 &aux_adc_vmid_rev7_core0);
+	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x18, 16,
+				 &aux_adc_vmid_rev7_core1);
+	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x0c, 16,
+				 &aux_adc_gain_rev7);
+	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x1c, 16,
+				 &aux_adc_gain_rev7);
 }
 
 static void wlc_phy_workarounds_nphy_rev3(struct brcms_phy *pi)
@@ -16672,7 +16599,8 @@ static void wlc_phy_workarounds_nphy_rev3(struct brcms_phy *pi)
 		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
 		NPHY_REV3_RFSEQ_CMD_END
 	};
-	static const u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
+	static const u8 rfseq_rx2tx_dlys_rev3_ipa[] =
+	    { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
 	s16 alpha0, alpha1, alpha2;
 	s16 beta0, beta1, beta2;
 	u32 leg_data_weights, ht_data_weights, nss1_data_weights,
@@ -16691,330 +16619,290 @@ static void wlc_phy_workarounds_nphy_rev3(struct brcms_phy *pi)
 	u8 pdetrange;
 	u8 triso;
 
-		write_phy_reg(pi, 0x23f, 0x1f8);
-		write_phy_reg(pi, 0x240, 0x1f8);
-
-		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
-					1, 0, 32, &leg_data_weights);
-		leg_data_weights = leg_data_weights & 0xffffff;
-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
-					 1, 0, 32, &leg_data_weights);
-
-		alpha0 = 293;
-		alpha1 = 435;
-		alpha2 = 261;
-		beta0 = 366;
-		beta1 = 205;
-		beta2 = 32;
-		write_phy_reg(pi, 0x145, alpha0);
-		write_phy_reg(pi, 0x146, alpha1);
-		write_phy_reg(pi, 0x147, alpha2);
-		write_phy_reg(pi, 0x148, beta0);
-		write_phy_reg(pi, 0x149, beta1);
-		write_phy_reg(pi, 0x14a, beta2);
-
-		write_phy_reg(pi, 0x38, 0xC);
-		write_phy_reg(pi, 0x2ae, 0xC);
-
-		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX,
-				       rfseq_tx2rx_events_rev3,
-				       rfseq_tx2rx_dlys_rev3,
-				       ARRAY_SIZE(rfseq_tx2rx_events_rev3));
-
-		if (PHY_IPA(pi))
-			wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
-					       rfseq_rx2tx_events_rev3_ipa,
-					       rfseq_rx2tx_dlys_rev3_ipa,
-					       ARRAY_SIZE(rfseq_rx2tx_events_rev3_ipa));
-
-		if ((pi->sh->hw_phyrxchain != 0x3) &&
-		    (pi->sh->hw_phyrxchain != pi->sh->hw_phytxchain)) {
-
-			if (PHY_IPA(pi)) {
-				rfseq_rx2tx_dlys_rev3[5] = 59;
-				rfseq_rx2tx_dlys_rev3[6] = 1;
-				rfseq_rx2tx_events_rev3[7] =
-					NPHY_REV3_RFSEQ_CMD_END;
-			}
-
-			wlc_phy_set_rfseq_nphy(
-				pi, NPHY_RFSEQ_RX2TX,
-				rfseq_rx2tx_events_rev3,
-				rfseq_rx2tx_dlys_rev3,
-				ARRAY_SIZE(rfseq_rx2tx_events_rev3));
-		}
+	write_phy_reg(pi, 0x23f, 0x1f8);
+	write_phy_reg(pi, 0x240, 0x1f8);
+
+	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
+				1, 0, 32, &leg_data_weights);
+	leg_data_weights = leg_data_weights & 0xffffff;
+	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
+				 1, 0, 32, &leg_data_weights);
+
+	alpha0 = 293;
+	alpha1 = 435;
+	alpha2 = 261;
+	beta0 = 366;
+	beta1 = 205;
+	beta2 = 32;
+	write_phy_reg(pi, 0x145, alpha0);
+	write_phy_reg(pi, 0x146, alpha1);
+	write_phy_reg(pi, 0x147, alpha2);
+	write_phy_reg(pi, 0x148, beta0);
+	write_phy_reg(pi, 0x149, beta1);
+	write_phy_reg(pi, 0x14a, beta2);
+
+	write_phy_reg(pi, 0x38, 0xC);
+	write_phy_reg(pi, 0x2ae, 0xC);
+
+	wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX,
+			       rfseq_tx2rx_events_rev3,
+			       rfseq_tx2rx_dlys_rev3,
+			       ARRAY_SIZE(rfseq_tx2rx_events_rev3));
 
-		if (CHSPEC_IS2G(pi->radio_chanspec))
-			write_phy_reg(pi, 0x6a, 0x2);
-		else
-			write_phy_reg(pi, 0x6a, 0x9c40);
-
-		mod_phy_reg(pi, 0x294, (0xf << 8), (7 << 8));
+	if (PHY_IPA(pi))
+		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
+				       rfseq_rx2tx_events_rev3_ipa,
+				       rfseq_rx2tx_dlys_rev3_ipa,
+				       ARRAY_SIZE (rfseq_rx2tx_events_rev3_ipa));
 
-		if (CHSPEC_IS40(pi->radio_chanspec) == 0) {
-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
-						 32, &min_nvar_val);
-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
-						 127, 32, &min_nvar_val);
-		} else {
-			min_nvar_val = noise_var_tbl_rev3[3];
-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
-						 32, &min_nvar_val);
+	if ((pi->sh->hw_phyrxchain != 0x3) &&
+	    (pi->sh->hw_phyrxchain != pi->sh->hw_phytxchain)) {
 
-			min_nvar_val = noise_var_tbl_rev3[127];
-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
-						 127, 32, &min_nvar_val);
+		if (PHY_IPA(pi)) {
+			rfseq_rx2tx_dlys_rev3[5] = 59;
+			rfseq_rx2tx_dlys_rev3[6] = 1;
+			rfseq_rx2tx_events_rev3[7] = NPHY_REV3_RFSEQ_CMD_END;
 		}
 
-		wlc_phy_workarounds_nphy_gainctrl(pi);
+		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
+				       rfseq_rx2tx_events_rev3,
+				       rfseq_rx2tx_dlys_rev3,
+				       ARRAY_SIZE (rfseq_rx2tx_events_rev3));
+	}
 
-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16,
-					 &dac_control);
-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x10, 16,
-					 &dac_control);
+	if (CHSPEC_IS2G(pi->radio_chanspec))
+		write_phy_reg(pi, 0x6a, 0x2);
+	else
+		write_phy_reg(pi, 0x6a, 0x9c40);
 
-		pdetrange =
-			(CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
-			pdetrange : pi->srom_fem2g.pdetrange;
+	mod_phy_reg(pi, 0x294, (0xf << 8), (7 << 8));
 
-		if (pdetrange == 0) {
-			if (NREV_GE(pi->pubpi.phy_rev, 4)) {
-				aux_adc_vmid = aux_adc_vmid_rev4;
-				aux_adc_gain = aux_adc_gain_rev4;
-			} else {
-				aux_adc_vmid = aux_adc_vmid_rev3;
-				aux_adc_gain = aux_adc_gain_rev3;
-			}
-			chan_freq_range =
-				wlc_phy_get_chan_freq_range_nphy(pi, 0);
-			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
-				switch (chan_freq_range) {
-				case WL_CHAN_FREQ_RANGE_5GL:
-					aux_adc_vmid[3] = 0x89;
-					aux_adc_gain[3] = 0;
-					break;
-				case WL_CHAN_FREQ_RANGE_5GM:
-					aux_adc_vmid[3] = 0x89;
-					aux_adc_gain[3] = 0;
-					break;
-				case WL_CHAN_FREQ_RANGE_5GH:
-					aux_adc_vmid[3] = 0x89;
-					aux_adc_gain[3] = 0;
-					break;
-				default:
-					break;
-				}
-			}
-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
-						 0x08, 16, aux_adc_vmid);
-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
-						 0x18, 16, aux_adc_vmid);
-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
-						 0x0c, 16, aux_adc_gain);
-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
-						 0x1c, 16, aux_adc_gain);
-		} else if (pdetrange == 1) {
-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
-						 0x08, 16, sk_adc_vmid);
-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
-						 0x18, 16, sk_adc_vmid);
-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
-						 0x0c, 16, sk_adc_gain);
-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
-						 0x1c, 16, sk_adc_gain);
-		} else if (pdetrange == 2) {
+	if (CHSPEC_IS40(pi->radio_chanspec) == 0) {
+		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
+					 32, &min_nvar_val);
+		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
+					 127, 32, &min_nvar_val);
+	} else {
+		min_nvar_val = noise_var_tbl_rev3[3];
+		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
+					 32, &min_nvar_val);
 
-			u16 bcm_adc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x74 };
-			u16 bcm_adc_gain[] = { 0x02, 0x02, 0x02, 0x04 };
+		min_nvar_val = noise_var_tbl_rev3[127];
+		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
+					 127, 32, &min_nvar_val);
+	}
 
-			if (NREV_GE(pi->pubpi.phy_rev, 6)) {
-				chan_freq_range =
-					wlc_phy_get_chan_freq_range_nphy(pi, 0);
-				if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
-					bcm_adc_vmid[3] = 0x8e;
-					bcm_adc_gain[3] = 0x03;
-				} else {
-					bcm_adc_vmid[3] = 0x94;
-					bcm_adc_gain[3] = 0x03;
-				}
-			} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
-				bcm_adc_vmid[3] = 0x84;
-				bcm_adc_gain[3] = 0x02;
-			}
+	wlc_phy_workarounds_nphy_gainctrl(pi);
 
-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
-						 0x08, 16, bcm_adc_vmid);
-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
-						 0x18, 16, bcm_adc_vmid);
-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
-						 0x0c, 16, bcm_adc_gain);
-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
-						 0x1c, 16, bcm_adc_gain);
-		} else if (pdetrange == 3) {
-			chan_freq_range =
-				wlc_phy_get_chan_freq_range_nphy(pi, 0);
-			if ((NREV_GE(pi->pubpi.phy_rev, 4))
-			    && (chan_freq_range == WL_CHAN_FREQ_RANGE_2G)) {
+	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16,
+				 &dac_control);
+	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x10, 16,
+				 &dac_control);
 
-				u16 auxadc_vmid[] = {
-					0xa2, 0xb4, 0xb4, 0x270
-				};
-				u16 auxadc_gain[] = {
-					0x02, 0x02, 0x02, 0x00
-				};
+	pdetrange = (CHSPEC_IS5G(pi->radio_chanspec)) ?
+			pi->srom_fem5g.pdetrange : pi->srom_fem2g.pdetrange;
 
-				wlc_phy_table_write_nphy(pi,
-							 NPHY_TBL_ID_AFECTRL, 4,
-							 0x08, 16, auxadc_vmid);
-				wlc_phy_table_write_nphy(pi,
-							 NPHY_TBL_ID_AFECTRL, 4,
-							 0x18, 16, auxadc_vmid);
-				wlc_phy_table_write_nphy(pi,
-							 NPHY_TBL_ID_AFECTRL, 4,
-							 0x0c, 16, auxadc_gain);
-				wlc_phy_table_write_nphy(pi,
-							 NPHY_TBL_ID_AFECTRL, 4,
-							 0x1c, 16, auxadc_gain);
+	if (pdetrange == 0) {
+		if (NREV_GE(pi->pubpi.phy_rev, 4)) {
+			aux_adc_vmid = aux_adc_vmid_rev4;
+			aux_adc_gain = aux_adc_gain_rev4;
+		} else {
+			aux_adc_vmid = aux_adc_vmid_rev3;
+			aux_adc_gain = aux_adc_gain_rev3;
+		}
+		chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0);
+		if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
+			switch (chan_freq_range) {
+			case WL_CHAN_FREQ_RANGE_5GL:
+				aux_adc_vmid[3] = 0x89;
+				aux_adc_gain[3] = 0;
+				break;
+			case WL_CHAN_FREQ_RANGE_5GM:
+				aux_adc_vmid[3] = 0x89;
+				aux_adc_gain[3] = 0;
+				break;
+			case WL_CHAN_FREQ_RANGE_5GH:
+				aux_adc_vmid[3] = 0x89;
+				aux_adc_gain[3] = 0;
+				break;
+			default:
+				break;
 			}
-		} else if ((pdetrange == 4) || (pdetrange == 5)) {
-			u16 bcm_adc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x0 };
-			u16 bcm_adc_gain[] = { 0x02, 0x02, 0x02, 0x0 };
-			u16 Vmid[2], Av[2];
+		}
+		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+					 0x08, 16, aux_adc_vmid);
+		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+					 0x18, 16, aux_adc_vmid);
+		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+					 0x0c, 16, aux_adc_gain);
+		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+					 0x1c, 16, aux_adc_gain);
+	} else if (pdetrange == 1) {
+		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+					 0x08, 16, sk_adc_vmid);
+		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+					 0x18, 16, sk_adc_vmid);
+		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+					 0x0c, 16, sk_adc_gain);
+		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+					 0x1c, 16, sk_adc_gain);
+	} else if (pdetrange == 2) {
+
+		u16 bcm_adc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x74 };
+		u16 bcm_adc_gain[] = { 0x02, 0x02, 0x02, 0x04 };
 
+		if (NREV_GE(pi->pubpi.phy_rev, 6)) {
 			chan_freq_range =
-				wlc_phy_get_chan_freq_range_nphy(pi, 0);
+			    wlc_phy_get_chan_freq_range_nphy(pi, 0);
 			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
-				Vmid[0] = (pdetrange == 4) ? 0x8e : 0x89;
-				Vmid[1] = (pdetrange == 4) ? 0x96 : 0x89;
-				Av[0] = (pdetrange == 4) ? 2 : 0;
-				Av[1] = (pdetrange == 4) ? 2 : 0;
+				bcm_adc_vmid[3] = 0x8e;
+				bcm_adc_gain[3] = 0x03;
 			} else {
-				Vmid[0] = (pdetrange == 4) ? 0x89 : 0x74;
-				Vmid[1] = (pdetrange == 4) ? 0x8b : 0x70;
-				Av[0] = (pdetrange == 4) ? 2 : 0;
-				Av[1] = (pdetrange == 4) ? 2 : 0;
+				bcm_adc_vmid[3] = 0x94;
+				bcm_adc_gain[3] = 0x03;
 			}
+		} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
+			bcm_adc_vmid[3] = 0x84;
+			bcm_adc_gain[3] = 0x02;
+		}
+
+		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+					 0x08, 16, bcm_adc_vmid);
+		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+					 0x18, 16, bcm_adc_vmid);
+		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+					 0x0c, 16, bcm_adc_gain);
+		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+					 0x1c, 16, bcm_adc_gain);
+	} else if (pdetrange == 3) {
+		chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0);
+		if ((NREV_GE(pi->pubpi.phy_rev, 4)) &&
+		    (chan_freq_range == WL_CHAN_FREQ_RANGE_2G)) {
+			u16 auxadc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x270 };
+			u16 auxadc_gain[] = { 0x02, 0x02, 0x02, 0x00 };
 
-			bcm_adc_vmid[3] = Vmid[0];
-			bcm_adc_gain[3] = Av[0];
 			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
-						 0x08, 16, bcm_adc_vmid);
+						 0x08, 16, auxadc_vmid);
 			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
-						 0x0c, 16, bcm_adc_gain);
-
-			bcm_adc_vmid[3] = Vmid[1];
-			bcm_adc_gain[3] = Av[1];
+						 0x18, 16, auxadc_vmid);
 			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
-						 0x18, 16, bcm_adc_vmid);
+						 0x0c, 16, auxadc_gain);
 			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
-						 0x1c, 16, bcm_adc_gain);
+						 0x1c, 16, auxadc_gain);
 		}
+	} else if ((pdetrange == 4) || (pdetrange == 5)) {
+		u16 bcm_adc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x0 };
+		u16 bcm_adc_gain[] = { 0x02, 0x02, 0x02, 0x0 };
+		u16 Vmid[2], Av[2];
 
-		write_radio_reg(pi,
-				(RADIO_2056_RX_MIXA_MAST_BIAS | RADIO_2056_RX0),
-				0x0);
-		write_radio_reg(pi,
-				(RADIO_2056_RX_MIXA_MAST_BIAS | RADIO_2056_RX1),
-				0x0);
+		chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0);
+		if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
+			Vmid[0] = (pdetrange == 4) ? 0x8e : 0x89;
+			Vmid[1] = (pdetrange == 4) ? 0x96 : 0x89;
+			Av[0] = (pdetrange == 4) ? 2 : 0;
+			Av[1] = (pdetrange == 4) ? 2 : 0;
+		} else {
+			Vmid[0] = (pdetrange == 4) ? 0x89 : 0x74;
+			Vmid[1] = (pdetrange == 4) ? 0x8b : 0x70;
+			Av[0] = (pdetrange == 4) ? 2 : 0;
+			Av[1] = (pdetrange == 4) ? 2 : 0;
+		}
 
-		write_radio_reg(pi,
-				(RADIO_2056_RX_MIXA_BIAS_MAIN | RADIO_2056_RX0),
-				0x6);
-		write_radio_reg(pi,
-				(RADIO_2056_RX_MIXA_BIAS_MAIN | RADIO_2056_RX1),
-				0x6);
+		bcm_adc_vmid[3] = Vmid[0];
+		bcm_adc_gain[3] = Av[0];
+		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+					 0x08, 16, bcm_adc_vmid);
+		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+					 0x0c, 16, bcm_adc_gain);
+
+		bcm_adc_vmid[3] = Vmid[1];
+		bcm_adc_gain[3] = Av[1];
+		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+					 0x18, 16, bcm_adc_vmid);
+		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+					 0x1c, 16, bcm_adc_gain);
+	}
 
-		write_radio_reg(pi,
-				(RADIO_2056_RX_MIXA_BIAS_AUX | RADIO_2056_RX0),
-				0x7);
-		write_radio_reg(pi,
-				(RADIO_2056_RX_MIXA_BIAS_AUX | RADIO_2056_RX1),
-				0x7);
+	write_radio_reg(pi, (RADIO_2056_RX_MIXA_MAST_BIAS | RADIO_2056_RX0), 0x0);
+	write_radio_reg(pi, (RADIO_2056_RX_MIXA_MAST_BIAS | RADIO_2056_RX1), 0x0);
 
-		write_radio_reg(pi,
-				(RADIO_2056_RX_MIXA_LOB_BIAS | RADIO_2056_RX0),
-				0x88);
-		write_radio_reg(pi,
-				(RADIO_2056_RX_MIXA_LOB_BIAS | RADIO_2056_RX1),
-				0x88);
+	write_radio_reg(pi, (RADIO_2056_RX_MIXA_BIAS_MAIN | RADIO_2056_RX0), 0x6);
+	write_radio_reg(pi, (RADIO_2056_RX_MIXA_BIAS_MAIN | RADIO_2056_RX1), 0x6);
 
-		write_radio_reg(pi,
-				(RADIO_2056_RX_MIXA_CMFB_IDAC | RADIO_2056_RX0),
-				0x0);
-		write_radio_reg(pi,
-				(RADIO_2056_RX_MIXA_CMFB_IDAC | RADIO_2056_RX1),
-				0x0);
+	write_radio_reg(pi, (RADIO_2056_RX_MIXA_BIAS_AUX | RADIO_2056_RX0), 0x7);
+	write_radio_reg(pi, (RADIO_2056_RX_MIXA_BIAS_AUX | RADIO_2056_RX1), 0x7);
 
-		write_radio_reg(pi,
-				(RADIO_2056_RX_MIXG_CMFB_IDAC | RADIO_2056_RX0),
-				0x0);
-		write_radio_reg(pi,
-				(RADIO_2056_RX_MIXG_CMFB_IDAC | RADIO_2056_RX1),
-				0x0);
+	write_radio_reg(pi, (RADIO_2056_RX_MIXA_LOB_BIAS | RADIO_2056_RX0), 0x88);
+	write_radio_reg(pi, (RADIO_2056_RX_MIXA_LOB_BIAS | RADIO_2056_RX1), 0x88);
 
-		triso =
-			(CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
-			triso : pi->srom_fem2g.triso;
-		if (triso == 7) {
-			wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_0);
-			wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_1);
-		}
+	write_radio_reg(pi, (RADIO_2056_RX_MIXA_CMFB_IDAC | RADIO_2056_RX0), 0x0);
+	write_radio_reg(pi, (RADIO_2056_RX_MIXA_CMFB_IDAC | RADIO_2056_RX1), 0x0);
 
-		wlc_phy_war_txchain_upd_nphy(pi, pi->sh->hw_phytxchain);
+	write_radio_reg(pi, (RADIO_2056_RX_MIXG_CMFB_IDAC | RADIO_2056_RX0), 0x0);
+	write_radio_reg(pi, (RADIO_2056_RX_MIXG_CMFB_IDAC | RADIO_2056_RX1), 0x0);
 
-		if (((pi->sh->boardflags2 & BFL2_APLL_WAR) &&
-		     (CHSPEC_IS5G(pi->radio_chanspec))) ||
-		    (((pi->sh->boardflags2 & BFL2_GPLL_WAR) ||
-		      (pi->sh->boardflags2 & BFL2_GPLL_WAR2)) &&
-		     (CHSPEC_IS2G(pi->radio_chanspec)))) {
-			nss1_data_weights = 0x00088888;
-			ht_data_weights = 0x00088888;
-			stbc_data_weights = 0x00088888;
-		} else {
-			nss1_data_weights = 0x88888888;
-			ht_data_weights = 0x88888888;
-			stbc_data_weights = 0x88888888;
-		}
-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
-					 1, 1, 32, &nss1_data_weights);
-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
-					 1, 2, 32, &ht_data_weights);
-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
-					 1, 3, 32, &stbc_data_weights);
-
-		if (NREV_IS(pi->pubpi.phy_rev, 4)) {
-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
-				write_radio_reg(pi,
-						RADIO_2056_TX_GMBB_IDAC |
-						RADIO_2056_TX0, 0x70);
-				write_radio_reg(pi,
-						RADIO_2056_TX_GMBB_IDAC |
-						RADIO_2056_TX1, 0x70);
-			}
-		}
+	triso = (CHSPEC_IS5G(pi->radio_chanspec)) ?
+		 pi->srom_fem5g.triso : pi->srom_fem2g.triso;
+	if (triso == 7) {
+		wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_0);
+		wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_1);
+	}
 
-		if (!pi->edcrs_threshold_lock) {
-			write_phy_reg(pi, 0x224, 0x3eb);
-			write_phy_reg(pi, 0x225, 0x3eb);
-			write_phy_reg(pi, 0x226, 0x341);
-			write_phy_reg(pi, 0x227, 0x341);
-			write_phy_reg(pi, 0x228, 0x42b);
-			write_phy_reg(pi, 0x229, 0x42b);
-			write_phy_reg(pi, 0x22a, 0x381);
-			write_phy_reg(pi, 0x22b, 0x381);
-			write_phy_reg(pi, 0x22c, 0x42b);
-			write_phy_reg(pi, 0x22d, 0x42b);
-			write_phy_reg(pi, 0x22e, 0x381);
-			write_phy_reg(pi, 0x22f, 0x381);
+	wlc_phy_war_txchain_upd_nphy(pi, pi->sh->hw_phytxchain);
+
+	if (((pi->sh->boardflags2 & BFL2_APLL_WAR) &&
+	     (CHSPEC_IS5G(pi->radio_chanspec))) ||
+	    (((pi->sh->boardflags2 & BFL2_GPLL_WAR) ||
+	      (pi->sh->boardflags2 & BFL2_GPLL_WAR2)) &&
+	     (CHSPEC_IS2G(pi->radio_chanspec)))) {
+		nss1_data_weights = 0x00088888;
+		ht_data_weights = 0x00088888;
+		stbc_data_weights = 0x00088888;
+	} else {
+		nss1_data_weights = 0x88888888;
+		ht_data_weights = 0x88888888;
+		stbc_data_weights = 0x88888888;
+	}
+	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
+				 1, 1, 32, &nss1_data_weights);
+	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
+				 1, 2, 32, &ht_data_weights);
+	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
+				 1, 3, 32, &stbc_data_weights);
+
+	if (NREV_IS(pi->pubpi.phy_rev, 4)) {
+		if (CHSPEC_IS5G(pi->radio_chanspec)) {
+			write_radio_reg(pi,
+					RADIO_2056_TX_GMBB_IDAC |
+					RADIO_2056_TX0, 0x70);
+			write_radio_reg(pi,
+					RADIO_2056_TX_GMBB_IDAC |
+					RADIO_2056_TX1, 0x70);
 		}
+	}
 
-		if (NREV_GE(pi->pubpi.phy_rev, 6)) {
+	if (!pi->edcrs_threshold_lock) {
+		write_phy_reg(pi, 0x224, 0x3eb);
+		write_phy_reg(pi, 0x225, 0x3eb);
+		write_phy_reg(pi, 0x226, 0x341);
+		write_phy_reg(pi, 0x227, 0x341);
+		write_phy_reg(pi, 0x228, 0x42b);
+		write_phy_reg(pi, 0x229, 0x42b);
+		write_phy_reg(pi, 0x22a, 0x381);
+		write_phy_reg(pi, 0x22b, 0x381);
+		write_phy_reg(pi, 0x22c, 0x42b);
+		write_phy_reg(pi, 0x22d, 0x42b);
+		write_phy_reg(pi, 0x22e, 0x381);
+		write_phy_reg(pi, 0x22f, 0x381);
+	}
 
-			if (pi->sh->boardflags2 & BFL2_SINGLEANT_CCK)
-				wlapi_bmac_mhf(pi->sh->physhim, MHF4,
-					      MHF4_BPHY_TXCORE0,
-					      MHF4_BPHY_TXCORE0, BRCM_BAND_ALL);
-		}
+	if (NREV_GE(pi->pubpi.phy_rev, 6)) {
+
+		if (pi->sh->boardflags2 & BFL2_SINGLEANT_CCK)
+			wlapi_bmac_mhf(pi->sh->physhim, MHF4,
+				       MHF4_BPHY_TXCORE0,
+				       MHF4_BPHY_TXCORE0, BRCM_BAND_ALL);
+	}
 }
 
 void wlc_phy_workarounds_nphy_rev1(struct brcms_phy *pi)
@@ -17043,102 +16931,101 @@ void wlc_phy_workarounds_nphy_rev1(struct brcms_phy *pi)
 	s16 beta0, beta1, beta2;
 	u16 regval;
 
-		if (pi->sh->boardflags2 & BFL2_SKWRKFEM_BRD ||
-		    (pi->sh->boardtype == 0x8b)) {
-			uint i;
-			u8 war_dlys[] = { 1, 6, 6, 2, 4, 20, 1 };
-			for (i = 0; i < ARRAY_SIZE(rfseq_rx2tx_dlys); i++)
-				rfseq_rx2tx_dlys[i] = war_dlys[i];
-		}
+	if (pi->sh->boardflags2 & BFL2_SKWRKFEM_BRD ||
+	    (pi->sh->boardtype == 0x8b)) {
+		uint i;
+		u8 war_dlys[] = { 1, 6, 6, 2, 4, 20, 1 };
+		for (i = 0; i < ARRAY_SIZE(rfseq_rx2tx_dlys); i++)
+			rfseq_rx2tx_dlys[i] = war_dlys[i];
+	}
 
-		if (CHSPEC_IS5G(pi->radio_chanspec) && pi->phy_5g_pwrgain) {
-			and_radio_reg(pi, RADIO_2055_CORE1_TX_RF_SPARE, 0xf7);
-			and_radio_reg(pi, RADIO_2055_CORE2_TX_RF_SPARE, 0xf7);
-		} else {
-			or_radio_reg(pi, RADIO_2055_CORE1_TX_RF_SPARE, 0x8);
-			or_radio_reg(pi, RADIO_2055_CORE2_TX_RF_SPARE, 0x8);
-		}
+	if (CHSPEC_IS5G(pi->radio_chanspec) && pi->phy_5g_pwrgain) {
+		and_radio_reg(pi, RADIO_2055_CORE1_TX_RF_SPARE, 0xf7);
+		and_radio_reg(pi, RADIO_2055_CORE2_TX_RF_SPARE, 0xf7);
+	} else {
+		or_radio_reg(pi, RADIO_2055_CORE1_TX_RF_SPARE, 0x8);
+		or_radio_reg(pi, RADIO_2055_CORE2_TX_RF_SPARE, 0x8);
+	}
 
-		regval = 0x000a;
-		wlc_phy_table_write_nphy(pi, 8, 1, 0, 16, &regval);
-		wlc_phy_table_write_nphy(pi, 8, 1, 0x10, 16, &regval);
+	regval = 0x000a;
+	wlc_phy_table_write_nphy(pi, 8, 1, 0, 16, &regval);
+	wlc_phy_table_write_nphy(pi, 8, 1, 0x10, 16, &regval);
 
-		if (NREV_LT(pi->pubpi.phy_rev, 3)) {
-			regval = 0xcdaa;
-			wlc_phy_table_write_nphy(pi, 8, 1, 0x02, 16, &regval);
-			wlc_phy_table_write_nphy(pi, 8, 1, 0x12, 16, &regval);
-		}
+	if (NREV_LT(pi->pubpi.phy_rev, 3)) {
+		regval = 0xcdaa;
+		wlc_phy_table_write_nphy(pi, 8, 1, 0x02, 16, &regval);
+		wlc_phy_table_write_nphy(pi, 8, 1, 0x12, 16, &regval);
+	}
 
-		if (NREV_LT(pi->pubpi.phy_rev, 2)) {
-			regval = 0x0000;
-			wlc_phy_table_write_nphy(pi, 8, 1, 0x08, 16, &regval);
-			wlc_phy_table_write_nphy(pi, 8, 1, 0x18, 16, &regval);
+	if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+		regval = 0x0000;
+		wlc_phy_table_write_nphy(pi, 8, 1, 0x08, 16, &regval);
+		wlc_phy_table_write_nphy(pi, 8, 1, 0x18, 16, &regval);
 
-			regval = 0x7aab;
-			wlc_phy_table_write_nphy(pi, 8, 1, 0x07, 16, &regval);
-			wlc_phy_table_write_nphy(pi, 8, 1, 0x17, 16, &regval);
+		regval = 0x7aab;
+		wlc_phy_table_write_nphy(pi, 8, 1, 0x07, 16, &regval);
+		wlc_phy_table_write_nphy(pi, 8, 1, 0x17, 16, &regval);
 
-			regval = 0x0800;
-			wlc_phy_table_write_nphy(pi, 8, 1, 0x06, 16, &regval);
-			wlc_phy_table_write_nphy(pi, 8, 1, 0x16, 16, &regval);
-		}
+		regval = 0x0800;
+		wlc_phy_table_write_nphy(pi, 8, 1, 0x06, 16, &regval);
+		wlc_phy_table_write_nphy(pi, 8, 1, 0x16, 16, &regval);
+	}
 
-		write_phy_reg(pi, 0xf8, 0x02d8);
-		write_phy_reg(pi, 0xf9, 0x0301);
-		write_phy_reg(pi, 0xfa, 0x02d8);
-		write_phy_reg(pi, 0xfb, 0x0301);
+	write_phy_reg(pi, 0xf8, 0x02d8);
+	write_phy_reg(pi, 0xf9, 0x0301);
+	write_phy_reg(pi, 0xfa, 0x02d8);
+	write_phy_reg(pi, 0xfb, 0x0301);
 
-		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX, rfseq_rx2tx_events,
-				       rfseq_rx2tx_dlys,
-				       ARRAY_SIZE(rfseq_rx2tx_events));
+	wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX, rfseq_rx2tx_events,
+			       rfseq_rx2tx_dlys,
+			       ARRAY_SIZE(rfseq_rx2tx_events));
 
-		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX, rfseq_tx2rx_events,
-				       rfseq_tx2rx_dlys,
-				       ARRAY_SIZE(rfseq_tx2rx_events));
+	wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX, rfseq_tx2rx_events,
+			       rfseq_tx2rx_dlys,
+			       ARRAY_SIZE(rfseq_tx2rx_events));
 
-		wlc_phy_workarounds_nphy_gainctrl(pi);
+	wlc_phy_workarounds_nphy_gainctrl(pi);
 
-		if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+	if (NREV_LT(pi->pubpi.phy_rev, 2)) {
 
-			if (read_phy_reg(pi, 0xa0) & NPHY_MLenable)
-				wlapi_bmac_mhf(pi->sh->physhim, MHF3,
-					       MHF3_NPHY_MLADV_WAR,
-					       MHF3_NPHY_MLADV_WAR,
-					       BRCM_BAND_ALL);
+		if (read_phy_reg(pi, 0xa0) & NPHY_MLenable)
+			wlapi_bmac_mhf(pi->sh->physhim, MHF3,
+				       MHF3_NPHY_MLADV_WAR,
+				       MHF3_NPHY_MLADV_WAR, BRCM_BAND_ALL);
 
-		} else if (NREV_IS(pi->pubpi.phy_rev, 2)) {
-			write_phy_reg(pi, 0x1e3, 0x0);
-			write_phy_reg(pi, 0x1e4, 0x0);
-		}
+	} else if (NREV_IS(pi->pubpi.phy_rev, 2)) {
+		write_phy_reg(pi, 0x1e3, 0x0);
+		write_phy_reg(pi, 0x1e4, 0x0);
+	}
 
-		if (NREV_LT(pi->pubpi.phy_rev, 2))
-			mod_phy_reg(pi, 0x90, (0x1 << 7), 0);
-
-		alpha0 = 293;
-		alpha1 = 435;
-		alpha2 = 261;
-		beta0 = 366;
-		beta1 = 205;
-		beta2 = 32;
-		write_phy_reg(pi, 0x145, alpha0);
-		write_phy_reg(pi, 0x146, alpha1);
-		write_phy_reg(pi, 0x147, alpha2);
-		write_phy_reg(pi, 0x148, beta0);
-		write_phy_reg(pi, 0x149, beta1);
-		write_phy_reg(pi, 0x14a, beta2);
-
-		if (NREV_LT(pi->pubpi.phy_rev, 3)) {
-			mod_phy_reg(pi, 0x142, (0xf << 12), 0);
-
-			write_phy_reg(pi, 0x192, 0xb5);
-			write_phy_reg(pi, 0x193, 0xa4);
-			write_phy_reg(pi, 0x194, 0x0);
-		}
+	if (NREV_LT(pi->pubpi.phy_rev, 2))
+		mod_phy_reg(pi, 0x90, (0x1 << 7), 0);
+
+	alpha0 = 293;
+	alpha1 = 435;
+	alpha2 = 261;
+	beta0 = 366;
+	beta1 = 205;
+	beta2 = 32;
+	write_phy_reg(pi, 0x145, alpha0);
+	write_phy_reg(pi, 0x146, alpha1);
+	write_phy_reg(pi, 0x147, alpha2);
+	write_phy_reg(pi, 0x148, beta0);
+	write_phy_reg(pi, 0x149, beta1);
+	write_phy_reg(pi, 0x14a, beta2);
+
+	if (NREV_LT(pi->pubpi.phy_rev, 3)) {
+		mod_phy_reg(pi, 0x142, (0xf << 12), 0);
+
+		write_phy_reg(pi, 0x192, 0xb5);
+		write_phy_reg(pi, 0x193, 0xa4);
+		write_phy_reg(pi, 0x194, 0x0);
+	}
 
-		if (NREV_IS(pi->pubpi.phy_rev, 2))
-			mod_phy_reg(pi, 0x221,
-				    NPHY_FORCESIG_DECODEGATEDCLKS,
-				    NPHY_FORCESIG_DECODEGATEDCLKS);
+	if (NREV_IS(pi->pubpi.phy_rev, 2))
+		mod_phy_reg(pi, 0x221,
+			    NPHY_FORCESIG_DECODEGATEDCLKS,
+			    NPHY_FORCESIG_DECODEGATEDCLKS);
 }
 
 static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 11/26] rtlwifi: reduce stack usage for KASAN
  2017-03-02 16:38 [PATCH 00/26] bring back stack frame warning with KASAN Arnd Bergmann
                   ` (9 preceding siblings ...)
  2017-03-02 16:38 ` [PATCH 10/26] brcmsmac: reindent split functions Arnd Bergmann
@ 2017-03-02 16:38 ` Arnd Bergmann
  2017-03-02 16:38 ` [PATCH 12/26] wl3501_cs: reduce stack size " Arnd Bergmann
                   ` (15 subsequent siblings)
  26 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann

When CONFIG_KASAN is set, we use a large amount of stack in the btcoexist code,
presumably due to lots of inlining of functions that each add to the kernel
stack.

net/wireless/realtek/rtlwifi/btcoexist/halbtc8192e2ant.c:3762:1: error: the frame size of 4032 bytes is larger than 3072 bytes
net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.c:3076:1: error: the frame size of 4104 bytes is larger than 3072 bytes
net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a2ant.c:3740:1: error: the frame size of 3408 bytes is larger than 3072 bytes

I went through these recursively and marked functions as noinline_for_kasan
until no function used more than a kilobyte. While I saw the warning only for
three of the five files, I'm changing all five the same way for consistency.
This should help in case gcc later makes different inlining decisions.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 .../realtek/rtlwifi/btcoexist/halbtc8192e2ant.c    | 41 +++++++++++-----------
 .../realtek/rtlwifi/btcoexist/halbtc8723b1ant.c    | 26 +++++++-------
 .../realtek/rtlwifi/btcoexist/halbtc8723b2ant.c    | 34 +++++++++---------
 .../realtek/rtlwifi/btcoexist/halbtc8821a1ant.c    | 36 +++++++++----------
 .../realtek/rtlwifi/btcoexist/halbtc8821a2ant.c    | 38 ++++++++++----------
 5 files changed, 88 insertions(+), 87 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8192e2ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8192e2ant.c
index ffa1f438424d..8433c406a3c0 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8192e2ant.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8192e2ant.c
@@ -455,7 +455,7 @@ static void halbtc8192e2ant_querybt_info(struct btc_coexist *btcoexist)
 	btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter);
 }
 
-static void halbtc8192e2ant_update_btlink_info(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8192e2ant_update_btlink_info(struct btc_coexist *btcoexist)
 {
 	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
 	bool bt_hson = false;
@@ -751,7 +751,7 @@ static void halbtc8192e2ant_set_fwdec_btpwr(struct btc_coexist *btcoexist,
 	btcoexist->btc_fill_h2c(btcoexist, 0x62, 1, h2c_parameter);
 }
 
-static void halbtc8192e2ant_dec_btpwr(struct btc_coexist *btcoexist,
+static noinline_for_kasan void halbtc8192e2ant_dec_btpwr(struct btc_coexist *btcoexist,
 				      bool force_exec, u8 dec_btpwr_lvl)
 {
 	struct rtl_priv *rtlpriv = btcoexist->adapter;
@@ -817,7 +817,7 @@ static void halbtc8192e2ant_bt_autoreport(struct btc_coexist *btcoexist,
 	coex_dm->pre_bt_auto_report = coex_dm->cur_bt_auto_report;
 }
 
-static void halbtc8192e2ant_fw_dac_swinglvl(struct btc_coexist *btcoexist,
+static noinline_for_kasan void halbtc8192e2ant_fw_dac_swinglvl(struct btc_coexist *btcoexist,
 					    bool force_exec, u8 fw_dac_swinglvl)
 {
 	struct rtl_priv *rtlpriv = btcoexist->adapter;
@@ -1145,8 +1145,9 @@ static void halbtc8192e2ant_IgnoreWlanAct(struct btc_coexist *btcoexist,
 	coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act;
 }
 
-static void halbtc8192e2ant_SetFwPstdma(struct btc_coexist *btcoexist, u8 byte1,
-					u8 byte2, u8 byte3, u8 byte4, u8 byte5)
+static noinline_for_kasan void
+halbtc8192e2ant_SetFwPstdma(struct btc_coexist *btcoexist, u8 byte1,
+			    u8 byte2, u8 byte3, u8 byte4, u8 byte5)
 {
 	struct rtl_priv *rtlpriv = btcoexist->adapter;
 
@@ -1328,7 +1329,7 @@ static void halbtc8192e2ant_ps_tdma(struct btc_coexist *btcoexist,
 	coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma;
 }
 
-static void halbtc8192e2ant_set_switch_sstype(struct btc_coexist *btcoexist,
+static noinline_for_kasan void halbtc8192e2ant_set_switch_sstype(struct btc_coexist *btcoexist,
 					      u8 sstype)
 {
 	struct rtl_priv *rtlpriv = btcoexist->adapter;
@@ -1365,7 +1366,7 @@ static void halbtc8192e2ant_set_switch_sstype(struct btc_coexist *btcoexist,
 	btcoexist->btc_set(btcoexist, BTC_SET_ACT_SEND_MIMO_PS, &mimops);
 }
 
-static void halbtc8192e2ant_switch_sstype(struct btc_coexist *btcoexist,
+static noinline_for_kasan void halbtc8192e2ant_switch_sstype(struct btc_coexist *btcoexist,
 					  bool force_exec, u8 new_sstype)
 {
 	struct rtl_priv *rtlpriv = btcoexist->adapter;
@@ -1432,7 +1433,7 @@ static void halbtc8192e2ant_action_bt_inquiry(struct btc_coexist *btcoexist)
 	btc8192e2ant_sw_mec2(btcoexist, false, false, false, 0x18);
 }
 
-static bool halbtc8192e2ant_is_common_action(struct btc_coexist *btcoexist)
+static noinline_for_kasan bool halbtc8192e2ant_is_common_action(struct btc_coexist *btcoexist)
 {
 	struct rtl_priv *rtlpriv = btcoexist->adapter;
 	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
@@ -2358,7 +2359,7 @@ static void halbtc8192e2ant_tdma_duration_adjust(struct btc_coexist *btcoexist,
 }
 
 /* SCO only or SCO+PAN(HS) */
-static void halbtc8192e2ant_action_sco(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8192e2ant_action_sco(struct btc_coexist *btcoexist)
 {
 	u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_STAY_LOW;
 	u32 wifi_bw;
@@ -2420,7 +2421,7 @@ static void halbtc8192e2ant_action_sco(struct btc_coexist *btcoexist)
 	}
 }
 
-static void halbtc8192e2ant_action_sco_pan(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8192e2ant_action_sco_pan(struct btc_coexist *btcoexist)
 {
 	u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_STAY_LOW;
 	u32 wifi_bw;
@@ -2482,7 +2483,7 @@ static void halbtc8192e2ant_action_sco_pan(struct btc_coexist *btcoexist)
 	}
 }
 
-static void halbtc8192e2ant_action_hid(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8192e2ant_action_hid(struct btc_coexist *btcoexist)
 {
 	u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
 	u32 wifi_bw;
@@ -2544,7 +2545,7 @@ static void halbtc8192e2ant_action_hid(struct btc_coexist *btcoexist)
 }
 
 /* A2DP only / PAN(EDR) only/ A2DP+PAN(HS) */
-static void halbtc8192e2ant_action_a2dp(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8192e2ant_action_a2dp(struct btc_coexist *btcoexist)
 {
 	struct rtl_priv *rtlpriv = btcoexist->adapter;
 	u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
@@ -2633,7 +2634,7 @@ static void halbtc8192e2ant_action_a2dp(struct btc_coexist *btcoexist)
 	}
 }
 
-static void halbtc8192e2ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8192e2ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist)
 {
 	u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
 	u32 wifi_bw;
@@ -2694,7 +2695,7 @@ static void halbtc8192e2ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist)
 	}
 }
 
-static void halbtc8192e2ant_action_pan_edr(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8192e2ant_action_pan_edr(struct btc_coexist *btcoexist)
 {
 	u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
 	u32 wifi_bw;
@@ -2755,7 +2756,7 @@ static void halbtc8192e2ant_action_pan_edr(struct btc_coexist *btcoexist)
 }
 
 /* PAN(HS) only */
-static void halbtc8192e2ant_action_pan_hs(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8192e2ant_action_pan_hs(struct btc_coexist *btcoexist)
 {
 	u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
 	u32 wifi_bw;
@@ -2813,7 +2814,7 @@ static void halbtc8192e2ant_action_pan_hs(struct btc_coexist *btcoexist)
 }
 
 /* PAN(EDR)+A2DP */
-static void halbtc8192e2ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8192e2ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
 {
 	u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
 	u32 wifi_bw;
@@ -2876,7 +2877,7 @@ static void halbtc8192e2ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
 	}
 }
 
-static void halbtc8192e2ant_action_pan_edr_hid(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8192e2ant_action_pan_edr_hid(struct btc_coexist *btcoexist)
 {
 	u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
 	u32 wifi_bw;
@@ -2940,7 +2941,7 @@ static void halbtc8192e2ant_action_pan_edr_hid(struct btc_coexist *btcoexist)
 }
 
 /* HID+A2DP+PAN(EDR) */
-static void btc8192e2ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist)
+static noinline_for_kasan void btc8192e2ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist)
 {
 	u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
 	u32 wifi_bw;
@@ -3001,7 +3002,7 @@ static void btc8192e2ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist)
 	}
 }
 
-static void halbtc8192e2ant_action_hid_a2dp(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8192e2ant_action_hid_a2dp(struct btc_coexist *btcoexist)
 {
 	u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
 	u32 wifi_bw;
@@ -3060,7 +3061,7 @@ static void halbtc8192e2ant_action_hid_a2dp(struct btc_coexist *btcoexist)
 	}
 }
 
-static void halbtc8192e2ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8192e2ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
 {
 	struct rtl_priv *rtlpriv = btcoexist->adapter;
 	u8 algorithm = 0;
diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c
index d67bbfb6ad8e..583933f10af2 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c
@@ -862,7 +862,7 @@ static void halbtc8723b1ant_SetFwIgnoreWlanAct(struct btc_coexist *btcoexist,
 	btcoexist->btc_fill_h2c(btcoexist, 0x63, 1, h2c_parameter);
 }
 
-static void halbtc8723b1ant_ignore_wlan_act(struct btc_coexist *btcoexist,
+static noinline_for_kasan void halbtc8723b1ant_ignore_wlan_act(struct btc_coexist *btcoexist,
 					    bool force_exec, bool enable)
 {
 	struct rtl_priv *rtlpriv = btcoexist->adapter;
@@ -1407,7 +1407,7 @@ static void halbtc8723b1ant_ps_tdma(struct btc_coexist *btcoexist,
 	coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma;
 }
 
-static bool halbtc8723b1ant_is_common_action(struct btc_coexist *btcoexist)
+static noinline_for_kasan bool halbtc8723b1ant_is_common_action(struct btc_coexist *btcoexist)
 {
 	struct rtl_priv *rtlpriv = btcoexist->adapter;
 	bool commom = false, wifi_connected = false;
@@ -1706,56 +1706,56 @@ static void halbtc8723b1ant_power_save_state(struct btc_coexist *btcoexist,
  *
  ***************************************************/
 /* SCO only or SCO+PAN(HS) */
-static void halbtc8723b1ant_action_sco(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8723b1ant_action_sco(struct btc_coexist *btcoexist)
 {
 	halbtc8723b1ant_sw_mechanism(btcoexist, true);
 }
 
-static void halbtc8723b1ant_action_hid(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8723b1ant_action_hid(struct btc_coexist *btcoexist)
 {
 	halbtc8723b1ant_sw_mechanism(btcoexist, true);
 }
 
 /*A2DP only / PAN(EDR) only/ A2DP+PAN(HS) */
-static void halbtc8723b1ant_action_a2dp(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8723b1ant_action_a2dp(struct btc_coexist *btcoexist)
 {
 	halbtc8723b1ant_sw_mechanism(btcoexist, false);
 }
 
-static void halbtc8723b1ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist)
+static noinline_for_kasan noinline_for_kasan void halbtc8723b1ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist)
 {
 	halbtc8723b1ant_sw_mechanism(btcoexist, false);
 }
 
-static void halbtc8723b1ant_action_pan_edr(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8723b1ant_action_pan_edr(struct btc_coexist *btcoexist)
 {
 	halbtc8723b1ant_sw_mechanism(btcoexist, false);
 }
 
 /* PAN(HS) only */
-static void halbtc8723b1ant_action_pan_hs(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8723b1ant_action_pan_hs(struct btc_coexist *btcoexist)
 {
 	halbtc8723b1ant_sw_mechanism(btcoexist, false);
 }
 
 /*PAN(EDR)+A2DP */
-static void halbtc8723b1ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
+static noinline_for_kasan noinline_for_kasan void halbtc8723b1ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
 {
 	halbtc8723b1ant_sw_mechanism(btcoexist, false);
 }
 
-static void halbtc8723b1ant_action_pan_edr_hid(struct btc_coexist *btcoexist)
+static noinline_for_kasan noinline_for_kasan void halbtc8723b1ant_action_pan_edr_hid(struct btc_coexist *btcoexist)
 {
 	halbtc8723b1ant_sw_mechanism(btcoexist, true);
 }
 
 /* HID+A2DP+PAN(EDR) */
-static void btc8723b1ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist)
+static noinline_for_kasan void btc8723b1ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist)
 {
 	halbtc8723b1ant_sw_mechanism(btcoexist, true);
 }
 
-static void halbtc8723b1ant_action_hid_a2dp(struct btc_coexist *btcoexist)
+static noinline_for_kasan noinline_for_kasan void halbtc8723b1ant_action_hid_a2dp(struct btc_coexist *btcoexist)
 {
 	halbtc8723b1ant_sw_mechanism(btcoexist, true);
 }
@@ -2178,7 +2178,7 @@ static void btc8723b1ant_run_sw_coex_mech(struct btc_coexist *btcoexist)
 	}
 }
 
-static void halbtc8723b1ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8723b1ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
 {
 	struct rtl_priv *rtlpriv = btcoexist->adapter;
 	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.c
index 12125966a911..8459add3576f 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.c
@@ -659,7 +659,7 @@ static void btc8723b2ant_set_fw_dec_bt_pwr(struct btc_coexist *btcoexist,
 	btcoexist->btc_fill_h2c(btcoexist, 0x62, 1, h2c_parameter);
 }
 
-static void btc8723b2ant_dec_bt_pwr(struct btc_coexist *btcoexist,
+static noinline_for_kasan void btc8723b2ant_dec_bt_pwr(struct btc_coexist *btcoexist,
 				    bool force_exec, bool dec_bt_pwr)
 {
 	struct rtl_priv *rtlpriv = btcoexist->adapter;
@@ -1087,7 +1087,7 @@ static void btc8723b_coex_tbl_type(struct btc_coexist *btcoexist,
 	}
 }
 
-static void btc8723b2ant_set_fw_ignore_wlan_act(struct btc_coexist *btcoexist,
+static noinline_for_kasan void btc8723b2ant_set_fw_ignore_wlan_act(struct btc_coexist *btcoexist,
 						bool enable)
 {
 	struct rtl_priv *rtlpriv = btcoexist->adapter;
@@ -1103,7 +1103,7 @@ static void btc8723b2ant_set_fw_ignore_wlan_act(struct btc_coexist *btcoexist,
 	btcoexist->btc_fill_h2c(btcoexist, 0x63, 1, h2c_parameter);
 }
 
-static void btc8723b2ant_ignore_wlan_act(struct btc_coexist *btcoexist,
+static noinline_for_kasan void btc8723b2ant_ignore_wlan_act(struct btc_coexist *btcoexist,
 					 bool force_exec, bool enable)
 {
 	struct rtl_priv *rtlpriv = btcoexist->adapter;
@@ -1128,7 +1128,7 @@ static void btc8723b2ant_ignore_wlan_act(struct btc_coexist *btcoexist,
 	coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act;
 }
 
-static void btc8723b2ant_set_fw_ps_tdma(struct btc_coexist *btcoexist, u8 byte1,
+static noinline_for_kasan void btc8723b2ant_set_fw_ps_tdma(struct btc_coexist *btcoexist, u8 byte1,
 					u8 byte2, u8 byte3, u8 byte4, u8 byte5)
 {
 	struct rtl_priv *rtlpriv = btcoexist->adapter;
@@ -1398,7 +1398,7 @@ static void btc8723b2ant_ps_tdma(struct btc_coexist *btcoexist, bool force_exec,
 	coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma;
 }
 
-static void btc8723b2ant_coex_alloff(struct btc_coexist *btcoexist)
+static noinline_for_kasan void btc8723b2ant_coex_alloff(struct btc_coexist *btcoexist)
 {
 	/* fw all off */
 	btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
@@ -1456,7 +1456,7 @@ static void btc8723b2ant_action_bt_inquiry(struct btc_coexist *btcoexist)
 				  false, false);
 }
 
-static bool btc8723b2ant_is_common_action(struct btc_coexist *btcoexist)
+static noinline_for_kasan bool btc8723b2ant_is_common_action(struct btc_coexist *btcoexist)
 {
 	struct rtl_priv *rtlpriv = btcoexist->adapter;
 	bool common = false, wifi_connected = false;
@@ -2333,7 +2333,7 @@ static void btc8723b2ant_tdma_duration_adjust(struct btc_coexist *btcoexist,
 }
 
 /* SCO only or SCO+PAN(HS) */
-static void btc8723b2ant_action_sco(struct btc_coexist *btcoexist)
+static noinline_for_kasan void btc8723b2ant_action_sco(struct btc_coexist *btcoexist)
 {
 	u8 wifi_rssi_state;
 	u32 wifi_bw;
@@ -2391,7 +2391,7 @@ static void btc8723b2ant_action_sco(struct btc_coexist *btcoexist)
 	}
 }
 
-static void btc8723b2ant_action_hid(struct btc_coexist *btcoexist)
+static noinline_for_kasan void btc8723b2ant_action_hid(struct btc_coexist *btcoexist)
 {
 	u8 wifi_rssi_state, bt_rssi_state;
 	u32 wifi_bw;
@@ -2453,7 +2453,7 @@ static void btc8723b2ant_action_hid(struct btc_coexist *btcoexist)
 }
 
 /*A2DP only / PAN(EDR) only/ A2DP+PAN(HS)*/
-static void btc8723b2ant_action_a2dp(struct btc_coexist *btcoexist)
+static noinline_for_kasan void btc8723b2ant_action_a2dp(struct btc_coexist *btcoexist)
 {
 	u8 wifi_rssi_state, wifi_rssi_state1, bt_rssi_state;
 	u32 wifi_bw;
@@ -2542,7 +2542,7 @@ static void btc8723b2ant_action_a2dp(struct btc_coexist *btcoexist)
 	}
 }
 
-static void btc8723b2ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist)
+static noinline_for_kasan void btc8723b2ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist)
 {
 	u8 wifi_rssi_state;
 	u32 wifi_bw;
@@ -2595,7 +2595,7 @@ static void btc8723b2ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist)
 	}
 }
 
-static void btc8723b2ant_action_pan_edr(struct btc_coexist *btcoexist)
+static noinline_for_kasan void btc8723b2ant_action_pan_edr(struct btc_coexist *btcoexist)
 {
 	u8 wifi_rssi_state, bt_rssi_state;
 	u32 wifi_bw;
@@ -2653,7 +2653,7 @@ static void btc8723b2ant_action_pan_edr(struct btc_coexist *btcoexist)
 }
 
 /*PAN(HS) only*/
-static void btc8723b2ant_action_pan_hs(struct btc_coexist *btcoexist)
+static noinline_for_kasan void btc8723b2ant_action_pan_hs(struct btc_coexist *btcoexist)
 {
 	u8 wifi_rssi_state;
 	u32 wifi_bw;
@@ -2706,7 +2706,7 @@ static void btc8723b2ant_action_pan_hs(struct btc_coexist *btcoexist)
 }
 
 /*PAN(EDR)+A2DP*/
-static void btc8723b2ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
+static noinline_for_kasan void btc8723b2ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
 {
 	u8 wifi_rssi_state, bt_rssi_state;
 	u32 wifi_bw;
@@ -2770,7 +2770,7 @@ static void btc8723b2ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
 	}
 }
 
-static void btc8723b2ant_action_pan_edr_hid(struct btc_coexist *btcoexist)
+static noinline_for_kasan void btc8723b2ant_action_pan_edr_hid(struct btc_coexist *btcoexist)
 {
 	u8 wifi_rssi_state, bt_rssi_state;
 	u32 wifi_bw;
@@ -2840,7 +2840,7 @@ static void btc8723b2ant_action_pan_edr_hid(struct btc_coexist *btcoexist)
 }
 
 /* HID+A2DP+PAN(EDR) */
-static void btc8723b2ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist)
+static noinline_for_kasan void btc8723b2ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist)
 {
 	u8 wifi_rssi_state, bt_rssi_state;
 	u32 wifi_bw;
@@ -2904,7 +2904,7 @@ static void btc8723b2ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist)
 	}
 }
 
-static void btc8723b2ant_action_hid_a2dp(struct btc_coexist *btcoexist)
+static noinline_for_kasan void btc8723b2ant_action_hid_a2dp(struct btc_coexist *btcoexist)
 {
 	u8 wifi_rssi_state, bt_rssi_state;
 	u32 wifi_bw;
@@ -2962,7 +2962,7 @@ static void btc8723b2ant_action_hid_a2dp(struct btc_coexist *btcoexist)
 	}
 }
 
-static void btc8723b2ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
+static noinline_for_kasan void btc8723b2ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
 {
 	struct rtl_priv *rtlpriv = btcoexist->adapter;
 	u8 algorithm = 0;
diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c
index 8b689ed9a629..b3f24226f165 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c
@@ -670,7 +670,7 @@ static u8 halbtc8821a1ant_action_algorithm(struct btc_coexist *btcoexist)
 	return algorithm;
 }
 
-static void halbtc8821a1ant_set_bt_auto_report(struct btc_coexist *btcoexist,
+static noinline_for_kasan void halbtc8821a1ant_set_bt_auto_report(struct btc_coexist *btcoexist,
 					       bool enable_auto_report)
 {
 	struct rtl_priv *rtlpriv = btcoexist->adapter;
@@ -689,7 +689,7 @@ static void halbtc8821a1ant_set_bt_auto_report(struct btc_coexist *btcoexist,
 	btcoexist->btc_fill_h2c(btcoexist, 0x68, 1, h2c_parameter);
 }
 
-static void halbtc8821a1ant_bt_auto_report(struct btc_coexist *btcoexist,
+static noinline_for_kasan void halbtc8821a1ant_bt_auto_report(struct btc_coexist *btcoexist,
 					   bool force_exec,
 					   bool enable_auto_report)
 {
@@ -849,7 +849,7 @@ static void halbtc8821a1ant_coex_table_with_type(struct btc_coexist *btcoexist,
 	}
 }
 
-static void btc8821a1ant_set_fw_ignore_wlan_act(struct btc_coexist *btcoexist,
+static noinline_for_kasan void btc8821a1ant_set_fw_ignore_wlan_act(struct btc_coexist *btcoexist,
 						bool enable)
 {
 	struct rtl_priv *rtlpriv = btcoexist->adapter;
@@ -865,7 +865,7 @@ static void btc8821a1ant_set_fw_ignore_wlan_act(struct btc_coexist *btcoexist,
 	btcoexist->btc_fill_h2c(btcoexist, 0x63, 1, h2c_parameter);
 }
 
-static void halbtc8821a1ant_ignore_wlan_act(struct btc_coexist *btcoexist,
+static noinline_for_kasan void halbtc8821a1ant_ignore_wlan_act(struct btc_coexist *btcoexist,
 					    bool force_exec, bool enable)
 {
 	struct rtl_priv *rtlpriv = btcoexist->adapter;
@@ -890,7 +890,7 @@ static void halbtc8821a1ant_ignore_wlan_act(struct btc_coexist *btcoexist,
 	coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act;
 }
 
-static void halbtc8821a1ant_set_fw_pstdma(struct btc_coexist *btcoexist,
+static noinline_for_kasan void halbtc8821a1ant_set_fw_pstdma(struct btc_coexist *btcoexist,
 					  u8 byte1, u8 byte2, u8 byte3,
 					  u8 byte4, u8 byte5)
 {
@@ -1269,7 +1269,7 @@ static void halbtc8821a1ant_ps_tdma(struct btc_coexist *btcoexist,
 	coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma;
 }
 
-static bool halbtc8821a1ant_is_common_action(struct btc_coexist *btcoexist)
+static noinline_for_kasan bool halbtc8821a1ant_is_common_action(struct btc_coexist *btcoexist)
 {
 	struct rtl_priv *rtlpriv = btcoexist->adapter;
 	bool	common = false, wifi_connected = false, wifi_busy = false;
@@ -1669,56 +1669,56 @@ static void btc8821a1ant_mon_bt_en_dis(struct btc_coexist *btcoexist)
 /*=============================================*/
 
 /* SCO only or SCO+PAN(HS)*/
-static void halbtc8821a1ant_action_sco(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8821a1ant_action_sco(struct btc_coexist *btcoexist)
 {
 	halbtc8821a1ant_sw_mechanism(btcoexist, true);
 }
 
-static void halbtc8821a1ant_action_hid(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8821a1ant_action_hid(struct btc_coexist *btcoexist)
 {
 	halbtc8821a1ant_sw_mechanism(btcoexist, true);
 }
 
 /*A2DP only / PAN(EDR) only/ A2DP+PAN(HS)*/
-static void halbtc8821a1ant_action_a2dp(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8821a1ant_action_a2dp(struct btc_coexist *btcoexist)
 {
 	halbtc8821a1ant_sw_mechanism(btcoexist, false);
 }
 
-static void halbtc8821a1ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist)
+static noinline_for_kasan noinline_for_kasan void halbtc8821a1ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist)
 {
 	halbtc8821a1ant_sw_mechanism(btcoexist, false);
 }
 
-static void halbtc8821a1ant_action_pan_edr(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8821a1ant_action_pan_edr(struct btc_coexist *btcoexist)
 {
 	halbtc8821a1ant_sw_mechanism(btcoexist, false);
 }
 
 /*PAN(HS) only*/
-static void halbtc8821a1ant_action_pan_hs(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8821a1ant_action_pan_hs(struct btc_coexist *btcoexist)
 {
 	halbtc8821a1ant_sw_mechanism(btcoexist, false);
 }
 
 /*PAN(EDR)+A2DP*/
-static void halbtc8821a1ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
+static noinline_for_kasan noinline_for_kasan void halbtc8821a1ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
 {
 	halbtc8821a1ant_sw_mechanism(btcoexist, false);
 }
 
-static void halbtc8821a1ant_action_pan_edr_hid(struct btc_coexist *btcoexist)
+static noinline_for_kasan noinline_for_kasan void halbtc8821a1ant_action_pan_edr_hid(struct btc_coexist *btcoexist)
 {
 	halbtc8821a1ant_sw_mechanism(btcoexist, true);
 }
 
 /* HID+A2DP+PAN(EDR)*/
-static void btc8821a1ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist)
+static noinline_for_kasan void btc8821a1ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist)
 {
 	halbtc8821a1ant_sw_mechanism(btcoexist, true);
 }
 
-static void halbtc8821a1ant_action_hid_a2dp(struct btc_coexist *btcoexist)
+static noinline_for_kasan noinline_for_kasan void halbtc8821a1ant_action_hid_a2dp(struct btc_coexist *btcoexist)
 {
 	halbtc8821a1ant_sw_mechanism(btcoexist, true);
 }
@@ -1991,7 +1991,7 @@ static void halbtc8821a1ant_action_wifi_connected(struct btc_coexist *btcoexist)
 	}
 }
 
-static void btc8821a1ant_run_sw_coex_mech(struct btc_coexist *btcoexist)
+static noinline_for_kasan void btc8821a1ant_run_sw_coex_mech(struct btc_coexist *btcoexist)
 {
 	struct rtl_priv *rtlpriv = btcoexist->adapter;
 	u8	algorithm = 0;
@@ -2061,7 +2061,7 @@ static void btc8821a1ant_run_sw_coex_mech(struct btc_coexist *btcoexist)
 	}
 }
 
-static void halbtc8821a1ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8821a1ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
 {
 	struct rtl_priv *rtlpriv = btcoexist->adapter;
 	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a2ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a2ant.c
index 1717e9ce96ca..9da9f5df7690 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a2ant.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a2ant.c
@@ -610,7 +610,7 @@ static void halbtc8821a2ant_set_fw_dec_bt_pwr(struct btc_coexist *btcoexist,
 	btcoexist->btc_fill_h2c(btcoexist, 0x62, 1, h2c_parameter);
 }
 
-static void halbtc8821a2ant_dec_bt_pwr(struct btc_coexist *btcoexist,
+static noinline_for_kasan void halbtc8821a2ant_dec_bt_pwr(struct btc_coexist *btcoexist,
 				       bool force_exec, bool dec_bt_pwr)
 {
 	struct rtl_priv *rtlpriv = btcoexist->adapter;
@@ -722,7 +722,7 @@ static void halbtc8821a2ant_set_bt_psd_mode(struct btc_coexist *btcoexist,
 	coex_dm->pre_bt_psd_mode = coex_dm->cur_bt_psd_mode;
 }
 
-static void halbtc8821a2ant_set_bt_auto_report(struct btc_coexist *btcoexist,
+static noinline_for_kasan void halbtc8821a2ant_set_bt_auto_report(struct btc_coexist *btcoexist,
 					       bool enable_auto_report)
 {
 	struct rtl_priv *rtlpriv = btcoexist->adapter;
@@ -741,7 +741,7 @@ static void halbtc8821a2ant_set_bt_auto_report(struct btc_coexist *btcoexist,
 	btcoexist->btc_fill_h2c(btcoexist, 0x68, 1, h2c_parameter);
 }
 
-static void halbtc8821a2ant_bt_auto_report(struct btc_coexist *btcoexist,
+static noinline_for_kasan void halbtc8821a2ant_bt_auto_report(struct btc_coexist *btcoexist,
 					   bool force_exec,
 					   bool enable_auto_report)
 {
@@ -1066,7 +1066,7 @@ static void halbtc8821a2ant_coex_table(struct btc_coexist *btcoexist,
 	coex_dm->pre_val0x6cc = coex_dm->cur_val0x6cc;
 }
 
-static void halbtc8821a2ant_set_fw_ignore_wlan_act(struct btc_coexist *btcoex,
+static noinline_for_kasan void halbtc8821a2ant_set_fw_ignore_wlan_act(struct btc_coexist *btcoex,
 						   bool enable)
 {
 	struct rtl_priv *rtlpriv = btcoex->adapter;
@@ -1082,7 +1082,7 @@ static void halbtc8821a2ant_set_fw_ignore_wlan_act(struct btc_coexist *btcoex,
 	btcoex->btc_fill_h2c(btcoex, 0x63, 1, h2c_parameter);
 }
 
-static void halbtc8821a2ant_ignore_wlan_act(struct btc_coexist *btcoexist,
+static noinline_for_kasan void halbtc8821a2ant_ignore_wlan_act(struct btc_coexist *btcoexist,
 					    bool force_exec, bool enable)
 {
 	struct rtl_priv *rtlpriv = btcoexist->adapter;
@@ -1107,7 +1107,7 @@ static void halbtc8821a2ant_ignore_wlan_act(struct btc_coexist *btcoexist,
 	coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act;
 }
 
-static void halbtc8821a2ant_set_fw_pstdma(struct btc_coexist *btcoexist,
+static noinline_for_kasan void halbtc8821a2ant_set_fw_pstdma(struct btc_coexist *btcoexist,
 					  u8 byte1, u8 byte2, u8 byte3,
 					  u8 byte4, u8 byte5)
 {
@@ -1362,7 +1362,7 @@ static void halbtc8821a2ant_ps_tdma(struct btc_coexist *btcoexist,
 	coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma;
 }
 
-static void halbtc8821a2ant_coex_all_off(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8821a2ant_coex_all_off(struct btc_coexist *btcoexist)
 {
 	/* fw all off */
 	halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
@@ -1409,7 +1409,7 @@ static void halbtc8821a2ant_bt_inquiry_page(struct btc_coexist *btcoexist)
 	halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3);
 }
 
-static bool halbtc8821a2ant_is_common_action(struct btc_coexist *btcoexist)
+static noinline_for_kasan bool halbtc8821a2ant_is_common_action(struct btc_coexist *btcoexist)
 {
 	struct rtl_priv *rtlpriv = btcoexist->adapter;
 	bool common = false, wifi_connected = false, wifi_busy = false;
@@ -2355,7 +2355,7 @@ static void btc8821a2ant_tdma_dur_adj(struct btc_coexist *btcoexist,
 }
 
 /* SCO only or SCO+PAN(HS)*/
-static void halbtc8821a2ant_action_sco(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8821a2ant_action_sco(struct btc_coexist *btcoexist)
 {
 	u8	wifi_rssi_state, bt_rssi_state;
 	u32 wifi_bw;
@@ -2433,7 +2433,7 @@ static void halbtc8821a2ant_action_sco(struct btc_coexist *btcoexist)
 	}
 }
 
-static void halbtc8821a2ant_action_hid(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8821a2ant_action_hid(struct btc_coexist *btcoexist)
 {
 	u8	wifi_rssi_state, bt_rssi_state;
 	u32	wifi_bw;
@@ -2513,7 +2513,7 @@ static void halbtc8821a2ant_action_hid(struct btc_coexist *btcoexist)
 }
 
 /* A2DP only / PAN(EDR) only/ A2DP+PAN(HS) */
-static void halbtc8821a2ant_action_a2dp(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8821a2ant_action_a2dp(struct btc_coexist *btcoexist)
 {
 	u8		wifi_rssi_state, bt_rssi_state;
 	u32		wifi_bw;
@@ -2580,7 +2580,7 @@ static void halbtc8821a2ant_action_a2dp(struct btc_coexist *btcoexist)
 	}
 }
 
-static void halbtc8821a2ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8821a2ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist)
 {
 	u8		wifi_rssi_state, bt_rssi_state, bt_info_ext;
 	u32		wifi_bw;
@@ -2650,7 +2650,7 @@ static void halbtc8821a2ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist)
 	}
 }
 
-static void halbtc8821a2ant_action_pan_edr(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8821a2ant_action_pan_edr(struct btc_coexist *btcoexist)
 {
 	u8		wifi_rssi_state, bt_rssi_state;
 	u32		wifi_bw;
@@ -2730,7 +2730,7 @@ static void halbtc8821a2ant_action_pan_edr(struct btc_coexist *btcoexist)
 }
 
 /* PAN(HS) only */
-static void halbtc8821a2ant_action_pan_hs(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8821a2ant_action_pan_hs(struct btc_coexist *btcoexist)
 {
 	u8		wifi_rssi_state, bt_rssi_state;
 	u32		wifi_bw;
@@ -2798,7 +2798,7 @@ static void halbtc8821a2ant_action_pan_hs(struct btc_coexist *btcoexist)
 }
 
 /* PAN(EDR)+A2DP */
-static void halbtc8821a2ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8821a2ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
 {
 	u8	wifi_rssi_state, bt_rssi_state, bt_info_ext;
 	u32	wifi_bw;
@@ -2867,7 +2867,7 @@ static void halbtc8821a2ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
 	}
 }
 
-static void halbtc8821a2ant_action_pan_edr_hid(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8821a2ant_action_pan_edr_hid(struct btc_coexist *btcoexist)
 {
 	u8	wifi_rssi_state, bt_rssi_state;
 	u32	wifi_bw;
@@ -2942,7 +2942,7 @@ static void halbtc8821a2ant_action_pan_edr_hid(struct btc_coexist *btcoexist)
 }
 
 /* HID+A2DP+PAN(EDR) */
-static void btc8821a2ant_act_hid_a2dp_pan_edr(struct btc_coexist *btcoexist)
+static noinline_for_kasan void btc8821a2ant_act_hid_a2dp_pan_edr(struct btc_coexist *btcoexist)
 {
 	u8	wifi_rssi_state, bt_rssi_state, bt_info_ext;
 	u32	wifi_bw;
@@ -3022,7 +3022,7 @@ static void btc8821a2ant_act_hid_a2dp_pan_edr(struct btc_coexist *btcoexist)
 	}
 }
 
-static void halbtc8821a2ant_action_hid_a2dp(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8821a2ant_action_hid_a2dp(struct btc_coexist *btcoexist)
 {
 	u8	wifi_rssi_state, bt_rssi_state, bt_info_ext;
 	u32	wifi_bw;
@@ -3079,7 +3079,7 @@ static void halbtc8821a2ant_action_hid_a2dp(struct btc_coexist *btcoexist)
 	}
 }
 
-static void halbtc8821a2ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
+static noinline_for_kasan void halbtc8821a2ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
 {
 	struct rtl_priv *rtlpriv = btcoexist->adapter;
 	bool	wifi_under_5g = false;
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 12/26] wl3501_cs: reduce stack size for KASAN
  2017-03-02 16:38 [PATCH 00/26] bring back stack frame warning with KASAN Arnd Bergmann
                   ` (10 preceding siblings ...)
  2017-03-02 16:38 ` [PATCH 11/26] rtlwifi: reduce stack usage for KASAN Arnd Bergmann
@ 2017-03-02 16:38 ` Arnd Bergmann
  2017-03-02 16:38 ` [PATCH 13/26] rtl8180: " Arnd Bergmann
                   ` (14 subsequent siblings)
  26 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann

Inlining functions with local variables can lead to excessive stack usage
with KASAN:

drivers/net/wireless/wl3501_cs.c: In function 'wl3501_rx_interrupt':
drivers/net/wireless/wl3501_cs.c:1103:1: error: the frame size of 2232 bytes is larger than 1536 bytes [-Werror=frame-larger-than=]

Marking a few functions as noinline_for_kasan avoids the problem

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/net/wireless/wl3501_cs.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index acec0d9ec422..15dd8e31d373 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -242,8 +242,8 @@ static int wl3501_get_flash_mac_addr(struct wl3501_card *this)
  *
  * Move 'size' bytes from PC to card. (Shouldn't be interrupted)
  */
-static void wl3501_set_to_wla(struct wl3501_card *this, u16 dest, void *src,
-			      int size)
+static noinline_for_kasan void wl3501_set_to_wla(struct wl3501_card *this,
+						 u16 dest, void *src, int size)
 {
 	/* switch to SRAM Page 0 */
 	wl3501_switch_page(this, (dest & 0x8000) ? WL3501_BSS_SPAGE1 :
@@ -264,8 +264,8 @@ static void wl3501_set_to_wla(struct wl3501_card *this, u16 dest, void *src,
  *
  * Move 'size' bytes from card to PC. (Shouldn't be interrupted)
  */
-static void wl3501_get_from_wla(struct wl3501_card *this, u16 src, void *dest,
-				int size)
+static noinline_for_kasan void wl3501_get_from_wla(struct wl3501_card *this,
+						u16 src, void *dest, int size)
 {
 	/* switch to SRAM Page 0 */
 	wl3501_switch_page(this, (src & 0x8000) ? WL3501_BSS_SPAGE1 :
@@ -1037,7 +1037,7 @@ static inline void wl3501_auth_confirm_interrupt(struct wl3501_card *this,
 		wl3501_mgmt_resync(this);
 }
 
-static inline void wl3501_rx_interrupt(struct net_device *dev)
+static noinline_for_kasan void wl3501_rx_interrupt(struct net_device *dev)
 {
 	int morepkts;
 	u16 addr;
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 13/26] rtl8180: reduce stack size for KASAN
  2017-03-02 16:38 [PATCH 00/26] bring back stack frame warning with KASAN Arnd Bergmann
                   ` (11 preceding siblings ...)
  2017-03-02 16:38 ` [PATCH 12/26] wl3501_cs: reduce stack size " Arnd Bergmann
@ 2017-03-02 16:38 ` Arnd Bergmann
  2017-03-02 16:38 ` [PATCH 14/26] [media] dvb-frontends: reduce stack size in i2c access Arnd Bergmann
                   ` (13 subsequent siblings)
  26 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann

When CONFIG_KASAN is set, we see overly large stack frames from inlining
functions with local variables:

drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225se.c: In function 'rtl8225se_rf_init':
drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225se.c:431:1: warning: the frame size of 4384 bytes is larger than 3072 bytes [-Wframe-larger-than=]

This marks them noinline_for_kasan.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225se.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225se.c b/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225se.c
index fde89866fa8d..1efa098a2e32 100644
--- a/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225se.c
+++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225se.c
@@ -174,14 +174,14 @@ static void rtl8187se_three_wire_io(struct ieee80211_hw *dev, u8 *data,
 	} while (0);
 }
 
-static u32 rtl8187se_rf_readreg(struct ieee80211_hw *dev, u8 addr)
+static noinline_for_kasan u32 rtl8187se_rf_readreg(struct ieee80211_hw *dev, u8 addr)
 {
 	u32 dataread = addr & 0x0F;
 	rtl8187se_three_wire_io(dev, (u8 *)&dataread, 16, 0);
 	return dataread;
 }
 
-static void rtl8187se_rf_writereg(struct ieee80211_hw *dev, u8 addr, u32 data)
+static noinline_for_kasan void rtl8187se_rf_writereg(struct ieee80211_hw *dev, u8 addr, u32 data)
 {
 	u32 outdata = (data << 4) | (u32)(addr & 0x0F);
 	rtl8187se_three_wire_io(dev, (u8 *)&outdata, 16, 1);
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 14/26] [media] dvb-frontends: reduce stack size in i2c access
  2017-03-02 16:38 [PATCH 00/26] bring back stack frame warning with KASAN Arnd Bergmann
                   ` (12 preceding siblings ...)
  2017-03-02 16:38 ` [PATCH 13/26] rtl8180: " Arnd Bergmann
@ 2017-03-02 16:38 ` Arnd Bergmann
  2017-03-02 16:38 ` [PATCH 15/26] [media] tuners: i2c: reduce stack usage for tuner_i2c_xfer_* Arnd Bergmann
                   ` (12 subsequent siblings)
  26 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann

A typical code fragment was copied across many dvb-frontend
drivers and causes large stack frames when built with
-fsanitize-address-use-after-scope, e.g.

drivers/media/dvb-frontends/cxd2841er.c:3225:1: error: the frame size of 3992 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
drivers/media/dvb-frontends/cxd2841er.c:3404:1: error: the frame size of 3136 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
drivers/media/dvb-frontends/stv0367.c:3143:1: error: the frame size of 4016 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
drivers/media/dvb-frontends/stv090x.c:3430:1: error: the frame size of 5312 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
drivers/media/dvb-frontends/stv090x.c:4248:1: error: the frame size of 4872 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]

By marking the register access functions as noinline_for_kasan,
we can completely avoid this problem.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/media/dvb-frontends/ascot2e.c       |  3 ++-
 drivers/media/dvb-frontends/cxd2841er.c     |  4 ++--
 drivers/media/dvb-frontends/drx39xyj/drxj.c | 14 +++++++-------
 drivers/media/dvb-frontends/helene.c        |  4 ++--
 drivers/media/dvb-frontends/horus3a.c       |  2 +-
 drivers/media/dvb-frontends/itd1000.c       |  2 +-
 drivers/media/dvb-frontends/mt312.c         |  2 +-
 drivers/media/dvb-frontends/si2165.c        | 14 +++++++-------
 drivers/media/dvb-frontends/stb0899_drv.c   |  2 +-
 drivers/media/dvb-frontends/stb6100.c       |  2 +-
 drivers/media/dvb-frontends/stv0367.c       |  2 +-
 drivers/media/dvb-frontends/stv090x.c       |  2 +-
 drivers/media/dvb-frontends/stv6110.c       |  2 +-
 drivers/media/dvb-frontends/stv6110x.c      |  2 +-
 drivers/media/dvb-frontends/tda8083.c       |  2 +-
 drivers/media/dvb-frontends/zl10039.c       |  2 +-
 16 files changed, 31 insertions(+), 30 deletions(-)

diff --git a/drivers/media/dvb-frontends/ascot2e.c b/drivers/media/dvb-frontends/ascot2e.c
index 0ee0df53b91b..435eb4d3f3ef 100644
--- a/drivers/media/dvb-frontends/ascot2e.c
+++ b/drivers/media/dvb-frontends/ascot2e.c
@@ -153,7 +153,8 @@ static int ascot2e_write_regs(struct ascot2e_priv *priv,
 	return 0;
 }
 
-static int ascot2e_write_reg(struct ascot2e_priv *priv, u8 reg, u8 val)
+static noinline_for_kasan int ascot2e_write_reg(struct ascot2e_priv *priv,
+						u8 reg, u8 val)
 {
 	return ascot2e_write_regs(priv, reg, &val, 1);
 }
diff --git a/drivers/media/dvb-frontends/cxd2841er.c b/drivers/media/dvb-frontends/cxd2841er.c
index 614bfb3740f1..01f7ec4d42c1 100644
--- a/drivers/media/dvb-frontends/cxd2841er.c
+++ b/drivers/media/dvb-frontends/cxd2841er.c
@@ -258,7 +258,7 @@ static int cxd2841er_write_regs(struct cxd2841er_priv *priv,
 	return 0;
 }
 
-static int cxd2841er_write_reg(struct cxd2841er_priv *priv,
+static noinline_for_kasan int cxd2841er_write_reg(struct cxd2841er_priv *priv,
 			       u8 addr, u8 reg, u8 val)
 {
 	return cxd2841er_write_regs(priv, addr, reg, &val, 1);
@@ -306,7 +306,7 @@ static int cxd2841er_read_regs(struct cxd2841er_priv *priv,
 	return 0;
 }
 
-static int cxd2841er_read_reg(struct cxd2841er_priv *priv,
+static noinline_for_kasan int cxd2841er_read_reg(struct cxd2841er_priv *priv,
 			      u8 addr, u8 reg, u8 *val)
 {
 	return cxd2841er_read_regs(priv, addr, reg, val, 1);
diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.c b/drivers/media/dvb-frontends/drx39xyj/drxj.c
index daeaf965dd56..0e6540709e09 100644
--- a/drivers/media/dvb-frontends/drx39xyj/drxj.c
+++ b/drivers/media/dvb-frontends/drx39xyj/drxj.c
@@ -1516,7 +1516,7 @@ static int drxdap_fasi_read_block(struct i2c_device_addr *dev_addr,
 *
 ******************************/
 
-static int drxdap_fasi_read_reg16(struct i2c_device_addr *dev_addr,
+static noinline_for_kasan int drxdap_fasi_read_reg16(struct i2c_device_addr *dev_addr,
 					 u32 addr,
 					 u16 *data, u32 flags)
 {
@@ -1549,7 +1549,7 @@ static int drxdap_fasi_read_reg16(struct i2c_device_addr *dev_addr,
 *
 ******************************/
 
-static int drxdap_fasi_read_reg32(struct i2c_device_addr *dev_addr,
+static noinline_for_kasan int drxdap_fasi_read_reg32(struct i2c_device_addr *dev_addr,
 					 u32 addr,
 					 u32 *data, u32 flags)
 {
@@ -1722,7 +1722,7 @@ static int drxdap_fasi_write_block(struct i2c_device_addr *dev_addr,
 *
 ******************************/
 
-static int drxdap_fasi_write_reg16(struct i2c_device_addr *dev_addr,
+static noinline_for_kasan int drxdap_fasi_write_reg16(struct i2c_device_addr *dev_addr,
 					  u32 addr,
 					  u16 data, u32 flags)
 {
@@ -1795,7 +1795,7 @@ static int drxdap_fasi_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
 *
 ******************************/
 
-static int drxdap_fasi_write_reg32(struct i2c_device_addr *dev_addr,
+static noinline_for_kasan int drxdap_fasi_write_reg32(struct i2c_device_addr *dev_addr,
 					  u32 addr,
 					  u32 data, u32 flags)
 {
@@ -2172,7 +2172,7 @@ int drxj_dap_atomic_read_write_block(struct i2c_device_addr *dev_addr,
 * \fn int drxj_dap_atomic_read_reg32()
 * \brief Atomic read of 32 bits words
 */
-static
+static noinline_for_kasan
 int drxj_dap_atomic_read_reg32(struct i2c_device_addr *dev_addr,
 				     u32 addr,
 				     u32 *data, u32 flags)
@@ -4191,7 +4191,7 @@ int drxj_dap_scu_atomic_read_write_block(struct i2c_device_addr *dev_addr, u32 a
 * \fn int DRXJ_DAP_AtomicReadReg16()
 * \brief Atomic read of 16 bits words
 */
-static
+static noinline_for_kasan
 int drxj_dap_scu_atomic_read_reg16(struct i2c_device_addr *dev_addr,
 					 u32 addr,
 					 u16 *data, u32 flags)
@@ -4219,7 +4219,7 @@ int drxj_dap_scu_atomic_read_reg16(struct i2c_device_addr *dev_addr,
 * \fn int drxj_dap_scu_atomic_write_reg16()
 * \brief Atomic read of 16 bits words
 */
-static
+static noinline_for_kasan
 int drxj_dap_scu_atomic_write_reg16(struct i2c_device_addr *dev_addr,
 					  u32 addr,
 					  u16 data, u32 flags)
diff --git a/drivers/media/dvb-frontends/helene.c b/drivers/media/dvb-frontends/helene.c
index 4bf5a551ba40..d984dfc392f0 100644
--- a/drivers/media/dvb-frontends/helene.c
+++ b/drivers/media/dvb-frontends/helene.c
@@ -329,7 +329,7 @@ static int helene_write_regs(struct helene_priv *priv,
 	return 0;
 }
 
-static int helene_write_reg(struct helene_priv *priv, u8 reg, u8 val)
+static noinline_for_kasan int helene_write_reg(struct helene_priv *priv, u8 reg, u8 val)
 {
 	return helene_write_regs(priv, reg, &val, 1);
 }
@@ -374,7 +374,7 @@ static int helene_read_regs(struct helene_priv *priv,
 	return 0;
 }
 
-static int helene_read_reg(struct helene_priv *priv, u8 reg, u8 *val)
+static noinline_for_kasan int helene_read_reg(struct helene_priv *priv, u8 reg, u8 *val)
 {
 	return helene_read_regs(priv, reg, val, 1);
 }
diff --git a/drivers/media/dvb-frontends/horus3a.c b/drivers/media/dvb-frontends/horus3a.c
index 94bb4f7a2298..9dc6662073a7 100644
--- a/drivers/media/dvb-frontends/horus3a.c
+++ b/drivers/media/dvb-frontends/horus3a.c
@@ -87,7 +87,7 @@ static int horus3a_write_regs(struct horus3a_priv *priv,
 	return 0;
 }
 
-static int horus3a_write_reg(struct horus3a_priv *priv, u8 reg, u8 val)
+static noinline_for_kasan int horus3a_write_reg(struct horus3a_priv *priv, u8 reg, u8 val)
 {
 	return horus3a_write_regs(priv, reg, &val, 1);
 }
diff --git a/drivers/media/dvb-frontends/itd1000.c b/drivers/media/dvb-frontends/itd1000.c
index 5bb1e73a10b4..ae0b19c65b9f 100644
--- a/drivers/media/dvb-frontends/itd1000.c
+++ b/drivers/media/dvb-frontends/itd1000.c
@@ -93,7 +93,7 @@ static int itd1000_read_reg(struct itd1000_state *state, u8 reg)
 	return val;
 }
 
-static inline int itd1000_write_reg(struct itd1000_state *state, u8 r, u8 v)
+static noinline_for_kasan int itd1000_write_reg(struct itd1000_state *state, u8 r, u8 v)
 {
 	int ret = itd1000_write_regs(state, r, &v, 1);
 	state->shadow[r] = v;
diff --git a/drivers/media/dvb-frontends/mt312.c b/drivers/media/dvb-frontends/mt312.c
index 961b9a2508e0..a41d2c719aac 100644
--- a/drivers/media/dvb-frontends/mt312.c
+++ b/drivers/media/dvb-frontends/mt312.c
@@ -139,7 +139,7 @@ static inline int mt312_readreg(struct mt312_state *state,
 	return mt312_read(state, reg, val, 1);
 }
 
-static inline int mt312_writereg(struct mt312_state *state,
+static noinline_for_kasan int mt312_writereg(struct mt312_state *state,
 				 const enum mt312_reg_addr reg, const u8 val)
 {
 	return mt312_write(state, reg, &val, 1);
diff --git a/drivers/media/dvb-frontends/si2165.c b/drivers/media/dvb-frontends/si2165.c
index 528b82a5dd46..1a0997e1db4a 100644
--- a/drivers/media/dvb-frontends/si2165.c
+++ b/drivers/media/dvb-frontends/si2165.c
@@ -140,7 +140,7 @@ static int si2165_read(struct si2165_state *state,
 	return 0;
 }
 
-static int si2165_readreg8(struct si2165_state *state,
+static noinline_for_kasan int si2165_readreg8(struct si2165_state *state,
 		       const u16 reg, u8 *val)
 {
 	unsigned int val_tmp;
@@ -150,7 +150,7 @@ static int si2165_readreg8(struct si2165_state *state,
 	return ret;
 }
 
-static int si2165_readreg16(struct si2165_state *state,
+static noinline_for_kasan int si2165_readreg16(struct si2165_state *state,
 		       const u16 reg, u16 *val)
 {
 	u8 buf[2];
@@ -161,26 +161,26 @@ static int si2165_readreg16(struct si2165_state *state,
 	return ret;
 }
 
-static int si2165_writereg8(struct si2165_state *state, const u16 reg, u8 val)
+static noinline_for_kasan int si2165_writereg8(struct si2165_state *state, const u16 reg, u8 val)
 {
 	return regmap_write(state->regmap, reg, val);
 }
 
-static int si2165_writereg16(struct si2165_state *state, const u16 reg, u16 val)
+static noinline_for_kasan int si2165_writereg16(struct si2165_state *state, const u16 reg, u16 val)
 {
 	u8 buf[2] = { val & 0xff, (val >> 8) & 0xff };
 
 	return si2165_write(state, reg, buf, 2);
 }
 
-static int si2165_writereg24(struct si2165_state *state, const u16 reg, u32 val)
+static noinline_for_kasan int si2165_writereg24(struct si2165_state *state, const u16 reg, u32 val)
 {
 	u8 buf[3] = { val & 0xff, (val >> 8) & 0xff, (val >> 16) & 0xff };
 
 	return si2165_write(state, reg, buf, 3);
 }
 
-static int si2165_writereg32(struct si2165_state *state, const u16 reg, u32 val)
+static noinline_for_kasan int si2165_writereg32(struct si2165_state *state, const u16 reg, u32 val)
 {
 	u8 buf[4] = {
 		val & 0xff,
@@ -191,7 +191,7 @@ static int si2165_writereg32(struct si2165_state *state, const u16 reg, u32 val)
 	return si2165_write(state, reg, buf, 4);
 }
 
-static int si2165_writereg_mask8(struct si2165_state *state, const u16 reg,
+static noinline_for_kasan int si2165_writereg_mask8(struct si2165_state *state, const u16 reg,
 				 u8 val, u8 mask)
 {
 	if (mask != 0xff) {
diff --git a/drivers/media/dvb-frontends/stb0899_drv.c b/drivers/media/dvb-frontends/stb0899_drv.c
index 02347598277a..f638950f1478 100644
--- a/drivers/media/dvb-frontends/stb0899_drv.c
+++ b/drivers/media/dvb-frontends/stb0899_drv.c
@@ -537,7 +537,7 @@ int stb0899_write_regs(struct stb0899_state *state, unsigned int reg, u8 *data,
 	return 0;
 }
 
-int stb0899_write_reg(struct stb0899_state *state, unsigned int reg, u8 data)
+noinline_for_kasan int stb0899_write_reg(struct stb0899_state *state, unsigned int reg, u8 data)
 {
 	return stb0899_write_regs(state, reg, &data, 1);
 }
diff --git a/drivers/media/dvb-frontends/stb6100.c b/drivers/media/dvb-frontends/stb6100.c
index 17a955d0031b..2fd6378ebd9a 100644
--- a/drivers/media/dvb-frontends/stb6100.c
+++ b/drivers/media/dvb-frontends/stb6100.c
@@ -224,7 +224,7 @@ static int stb6100_write_reg_range(struct stb6100_state *state, u8 buf[], int st
 	return 0;
 }
 
-static int stb6100_write_reg(struct stb6100_state *state, u8 reg, u8 data)
+static noinline_for_kasan int stb6100_write_reg(struct stb6100_state *state, u8 reg, u8 data)
 {
 	if (unlikely(reg >= STB6100_NUMREGS)) {
 		dprintk(verbose, FE_ERROR, 1, "Invalid register offset 0x%x", reg);
diff --git a/drivers/media/dvb-frontends/stv0367.c b/drivers/media/dvb-frontends/stv0367.c
index fd49c436a36d..dc7c1e596d29 100644
--- a/drivers/media/dvb-frontends/stv0367.c
+++ b/drivers/media/dvb-frontends/stv0367.c
@@ -798,7 +798,7 @@ int stv0367_writeregs(struct stv0367_state *state, u16 reg, u8 *data, int len)
 	return (ret != 1) ? -EREMOTEIO : 0;
 }
 
-static int stv0367_writereg(struct stv0367_state *state, u16 reg, u8 data)
+static noinline_for_kasan int stv0367_writereg(struct stv0367_state *state, u16 reg, u8 data)
 {
 	return stv0367_writeregs(state, reg, &data, 1);
 }
diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c
index 7ef469c0c866..236325ae2580 100644
--- a/drivers/media/dvb-frontends/stv090x.c
+++ b/drivers/media/dvb-frontends/stv090x.c
@@ -753,7 +753,7 @@ static int stv090x_write_regs(struct stv090x_state *state, unsigned int reg, u8
 	return 0;
 }
 
-static int stv090x_write_reg(struct stv090x_state *state, unsigned int reg, u8 data)
+static noinline_for_kasan int stv090x_write_reg(struct stv090x_state *state, unsigned int reg, u8 data)
 {
 	return stv090x_write_regs(state, reg, &data, 1);
 }
diff --git a/drivers/media/dvb-frontends/stv6110.c b/drivers/media/dvb-frontends/stv6110.c
index e4fd9c1b0560..34677f7327d5 100644
--- a/drivers/media/dvb-frontends/stv6110.c
+++ b/drivers/media/dvb-frontends/stv6110.c
@@ -137,7 +137,7 @@ static int stv6110_read_regs(struct dvb_frontend *fe, u8 regs[],
 	return 0;
 }
 
-static int stv6110_read_reg(struct dvb_frontend *fe, int start)
+static noinline_for_kasan int stv6110_read_reg(struct dvb_frontend *fe, int start)
 {
 	u8 buf[] = { 0 };
 	stv6110_read_regs(fe, buf, start, 1);
diff --git a/drivers/media/dvb-frontends/stv6110x.c b/drivers/media/dvb-frontends/stv6110x.c
index 66eba38f1014..b8e3c5ac06e2 100644
--- a/drivers/media/dvb-frontends/stv6110x.c
+++ b/drivers/media/dvb-frontends/stv6110x.c
@@ -95,7 +95,7 @@ static int stv6110x_write_regs(struct stv6110x_state *stv6110x, int start, u8 da
 	return 0;
 }
 
-static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data)
+static noinline_for_kasan int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data)
 {
 	return stv6110x_write_regs(stv6110x, reg, &data, 1);
 }
diff --git a/drivers/media/dvb-frontends/tda8083.c b/drivers/media/dvb-frontends/tda8083.c
index aa3200d3c352..26732db739a5 100644
--- a/drivers/media/dvb-frontends/tda8083.c
+++ b/drivers/media/dvb-frontends/tda8083.c
@@ -88,7 +88,7 @@ static int tda8083_readregs (struct tda8083_state* state, u8 reg1, u8 *b, u8 len
 	return ret == 2 ? 0 : -1;
 }
 
-static inline u8 tda8083_readreg (struct tda8083_state* state, u8 reg)
+static noinline_for_kasan u8 tda8083_readreg (struct tda8083_state* state, u8 reg)
 {
 	u8 val;
 
diff --git a/drivers/media/dvb-frontends/zl10039.c b/drivers/media/dvb-frontends/zl10039.c
index 623355fc2666..713da9e02700 100644
--- a/drivers/media/dvb-frontends/zl10039.c
+++ b/drivers/media/dvb-frontends/zl10039.c
@@ -130,7 +130,7 @@ static inline int zl10039_readreg(struct zl10039_state *state,
 	return zl10039_read(state, reg, val, 1);
 }
 
-static inline int zl10039_writereg(struct zl10039_state *state,
+static noinline_for_kasan int zl10039_writereg(struct zl10039_state *state,
 				const enum zl10039_reg_addr reg,
 				const u8 val)
 {
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 15/26] [media] tuners: i2c: reduce stack usage for tuner_i2c_xfer_*
  2017-03-02 16:38 [PATCH 00/26] bring back stack frame warning with KASAN Arnd Bergmann
                   ` (13 preceding siblings ...)
  2017-03-02 16:38 ` [PATCH 14/26] [media] dvb-frontends: reduce stack size in i2c access Arnd Bergmann
@ 2017-03-02 16:38 ` Arnd Bergmann
  2017-03-02 16:38 ` [PATCH 16/26] [media] i2c: adv7604: mark register access as noinline_for_kasan Arnd Bergmann
                   ` (11 subsequent siblings)
  26 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann

When CONFIG_KASAN is enabled, we see very large stack usage in some
functions, e.g.:

drivers/media/tuners/tda8290.c: In function 'tda8290_set_params':
drivers/media/tuners/tda8290.c:310:1: warning: the frame size of 3184 bytes is larger than 1024 bytes [-Wframe-larger-than=]
drivers/media/tuners/tda8290.c: In function 'tda829x_probe':
drivers/media/tuners/tda8290.c:878:1: warning: the frame size of 1088 bytes is larger than 1024 bytes [-Wframe-larger-than=]

By annotating the helpers as noinline_for_kasan, we can easily avoid this.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/media/tuners/tuner-i2c.h | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/media/tuners/tuner-i2c.h b/drivers/media/tuners/tuner-i2c.h
index bda67a5a76f2..c8970299799c 100644
--- a/drivers/media/tuners/tuner-i2c.h
+++ b/drivers/media/tuners/tuner-i2c.h
@@ -33,8 +33,8 @@ struct tuner_i2c_props {
 	char *name;
 };
 
-static inline int tuner_i2c_xfer_send(struct tuner_i2c_props *props,
-				      unsigned char *buf, int len)
+static noinline_for_kasan int
+tuner_i2c_xfer_send(struct tuner_i2c_props *props, unsigned char *buf, int len)
 {
 	struct i2c_msg msg = { .addr = props->addr, .flags = 0,
 			       .buf = buf, .len = len };
@@ -43,8 +43,8 @@ static inline int tuner_i2c_xfer_send(struct tuner_i2c_props *props,
 	return (ret == 1) ? len : ret;
 }
 
-static inline int tuner_i2c_xfer_recv(struct tuner_i2c_props *props,
-				      unsigned char *buf, int len)
+static noinline_for_kasan int
+tuner_i2c_xfer_recv(struct tuner_i2c_props *props, unsigned char *buf, int len)
 {
 	struct i2c_msg msg = { .addr = props->addr, .flags = I2C_M_RD,
 			       .buf = buf, .len = len };
@@ -53,9 +53,10 @@ static inline int tuner_i2c_xfer_recv(struct tuner_i2c_props *props,
 	return (ret == 1) ? len : ret;
 }
 
-static inline int tuner_i2c_xfer_send_recv(struct tuner_i2c_props *props,
-					   unsigned char *obuf, int olen,
-					   unsigned char *ibuf, int ilen)
+static noinline_for_kasan int
+tuner_i2c_xfer_send_recv(struct tuner_i2c_props *props,
+			 unsigned char *obuf, int olen,
+			 unsigned char *ibuf, int ilen)
 {
 	struct i2c_msg msg[2] = { { .addr = props->addr, .flags = 0,
 				    .buf = obuf, .len = olen },
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 16/26] [media] i2c: adv7604: mark register access as noinline_for_kasan
  2017-03-02 16:38 [PATCH 00/26] bring back stack frame warning with KASAN Arnd Bergmann
                   ` (14 preceding siblings ...)
  2017-03-02 16:38 ` [PATCH 15/26] [media] tuners: i2c: reduce stack usage for tuner_i2c_xfer_* Arnd Bergmann
@ 2017-03-02 16:38 ` Arnd Bergmann
  2017-03-02 16:38 ` [PATCH 17/26] [media] i2c: ks0127: reduce stack frame size for KASAN Arnd Bergmann
                   ` (10 subsequent siblings)
  26 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann

When building with KASAN, we get a stack frame size warning about a function
that could potentially cause a stack overflow:

drivers/media/i2c/adv7604.c: In function 'adv76xx_log_status':
drivers/media/i2c/adv7604.c:2615:1: error: the frame size of 3248 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]

This is caused by adv76xx_read_check() being inlined repeatedly, and
marking this function as noinline_for_kasan solves the problem
completely.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/media/i2c/adv7604.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index d8bf435db86d..176f46ac85fd 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -339,8 +339,8 @@ static inline unsigned vtotal(const struct v4l2_bt_timings *t)
 
 /* ----------------------------------------------------------------------- */
 
-static int adv76xx_read_check(struct adv76xx_state *state,
-			     int client_page, u8 reg)
+static noinline_for_kasan int adv76xx_read_check(struct adv76xx_state *state,
+						 int client_page, u8 reg)
 {
 	struct i2c_client *client = state->i2c_clients[client_page];
 	int err;
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 17/26] [media] i2c: ks0127: reduce stack frame size for KASAN
  2017-03-02 16:38 [PATCH 00/26] bring back stack frame warning with KASAN Arnd Bergmann
                   ` (15 preceding siblings ...)
  2017-03-02 16:38 ` [PATCH 16/26] [media] i2c: adv7604: mark register access as noinline_for_kasan Arnd Bergmann
@ 2017-03-02 16:38 ` Arnd Bergmann
  2017-03-02 16:38 ` [PATCH 18/26] [media] i2c: cx25840: avoid stack overflow with KASAN Arnd Bergmann
                   ` (9 subsequent siblings)
  26 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann

When CONFIG_KASAN is set, inlining of functions with local variables
causes excessive stack usage:

drivers/media/i2c/ks0127.c: In function 'ks0127_s_routing':
drivers/media/i2c/ks0127.c:541:1: error: the frame size of 3136 bytes is larger than 2048 bytes [-Werror=frame-larger-than=]

Marking one functions as noinline_for_kasan solves the problem in this
driver.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/media/i2c/ks0127.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/i2c/ks0127.c b/drivers/media/i2c/ks0127.c
index ab536c4a7115..eb2fccdc0602 100644
--- a/drivers/media/i2c/ks0127.c
+++ b/drivers/media/i2c/ks0127.c
@@ -349,7 +349,7 @@ static void ks0127_write(struct v4l2_subdev *sd, u8 reg, u8 val)
 
 
 /* generic bit-twiddling */
-static void ks0127_and_or(struct v4l2_subdev *sd, u8 reg, u8 and_v, u8 or_v)
+static noinline_for_kasan void ks0127_and_or(struct v4l2_subdev *sd, u8 reg, u8 and_v, u8 or_v)
 {
 	struct ks0127 *ks = to_ks0127(sd);
 
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 18/26] [media] i2c: cx25840: avoid stack overflow with KASAN
  2017-03-02 16:38 [PATCH 00/26] bring back stack frame warning with KASAN Arnd Bergmann
                   ` (16 preceding siblings ...)
  2017-03-02 16:38 ` [PATCH 17/26] [media] i2c: ks0127: reduce stack frame size for KASAN Arnd Bergmann
@ 2017-03-02 16:38 ` Arnd Bergmann
  2017-03-02 16:38 ` [PATCH 19/26] [media] r820t: mark register functions as noinline_for_kasan Arnd Bergmann
                   ` (8 subsequent siblings)
  26 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann

With CONFIG_KASAN, this driver has shown a ridiculously large stack frame
in one configuration:

drivers/media/i2c/cx25840/cx25840-core.c:4960:1: error: the frame size of 94000 bytes is larger than 2048 bytes [-Werror=frame-larger-than=]

In most builds, it's only about 3300 bytes, but that's still large anough to
risk a kernel stack overflow.

Marking the two register access functions as noinline_for_kasan avoids
the problem and brings the largest stack frame size down to 232 bytes.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/media/i2c/cx25840/cx25840-core.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c
index b8d3c070bfc1..fd72e5a11cb9 100644
--- a/drivers/media/i2c/cx25840/cx25840-core.c
+++ b/drivers/media/i2c/cx25840/cx25840-core.c
@@ -81,7 +81,7 @@ MODULE_PARM_DESC(debug, "Debugging messages [0=Off (default) 1=On]");
 /* ----------------------------------------------------------------------- */
 static void cx23888_std_setup(struct i2c_client *client);
 
-int cx25840_write(struct i2c_client *client, u16 addr, u8 value)
+noinline_for_kasan int cx25840_write(struct i2c_client *client, u16 addr, u8 value)
 {
 	u8 buffer[3];
 	buffer[0] = addr >> 8;
@@ -90,7 +90,7 @@ int cx25840_write(struct i2c_client *client, u16 addr, u8 value)
 	return i2c_master_send(client, buffer, 3);
 }
 
-int cx25840_write4(struct i2c_client *client, u16 addr, u32 value)
+noinline_for_kasan int cx25840_write4(struct i2c_client *client, u16 addr, u32 value)
 {
 	u8 buffer[6];
 	buffer[0] = addr >> 8;
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 19/26] [media] r820t: mark register functions as noinline_for_kasan
  2017-03-02 16:38 [PATCH 00/26] bring back stack frame warning with KASAN Arnd Bergmann
                   ` (17 preceding siblings ...)
  2017-03-02 16:38 ` [PATCH 18/26] [media] i2c: cx25840: avoid stack overflow with KASAN Arnd Bergmann
@ 2017-03-02 16:38 ` Arnd Bergmann
  2017-03-02 16:38 ` [PATCH 20/26] [media] em28xx: split up em28xx_dvb_init to reduce stack size Arnd Bergmann
                   ` (7 subsequent siblings)
  26 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann

With KASAN, we get an overly long stack frame due to inlining
the register access function:

drivers/media/tuners/r820t.c: In function 'generic_set_freq.isra.7':
drivers/media/tuners/r820t.c:1334:1: error: the frame size of 2880 bytes is larger than 2048 bytes [-Werror=frame-larger-than=]

An earlier patch I tried used an open-coded r820t_write_reg()
implementation that may have been more efficent, while this
version simply adds the annotation, which has a lower risk for
regressions.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/media/tuners/r820t.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/tuners/r820t.c b/drivers/media/tuners/r820t.c
index ba80376a3b86..0fbfa6416e38 100644
--- a/drivers/media/tuners/r820t.c
+++ b/drivers/media/tuners/r820t.c
@@ -396,7 +396,7 @@ static int r820t_write(struct r820t_priv *priv, u8 reg, const u8 *val,
 	return 0;
 }
 
-static int r820t_write_reg(struct r820t_priv *priv, u8 reg, u8 val)
+static noinline_for_kasan int r820t_write_reg(struct r820t_priv *priv, u8 reg, u8 val)
 {
 	return r820t_write(priv, reg, &val, 1);
 }
@@ -411,7 +411,7 @@ static int r820t_read_cache_reg(struct r820t_priv *priv, int reg)
 		return -EINVAL;
 }
 
-static int r820t_write_reg_mask(struct r820t_priv *priv, u8 reg, u8 val,
+static noinline_for_kasan int r820t_write_reg_mask(struct r820t_priv *priv, u8 reg, u8 val,
 				u8 bit_mask)
 {
 	int rc = r820t_read_cache_reg(priv, reg);
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 20/26] [media] em28xx: split up em28xx_dvb_init to reduce stack size
  2017-03-02 16:38 [PATCH 00/26] bring back stack frame warning with KASAN Arnd Bergmann
                   ` (18 preceding siblings ...)
  2017-03-02 16:38 ` [PATCH 19/26] [media] r820t: mark register functions as noinline_for_kasan Arnd Bergmann
@ 2017-03-02 16:38 ` Arnd Bergmann
  2017-03-02 16:38 ` [PATCH 21/26] drm/bridge: ps8622: reduce stack size for KASAN Arnd Bergmann
                   ` (6 subsequent siblings)
  26 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann

With CONFIG_KASAN, the init function uses a large amount of kernel stack:

drivers/media/usb/em28xx/em28xx-dvb.c: In function 'em28xx_dvb_init':
drivers/media/usb/em28xx/em28xx-dvb.c:2069:1: error: the frame size of 4280 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]

By splitting out each part of the switch/case statement that has its own local
variables into a separate function, no single one of them uses more than 500 bytes,
and with a noinline_for_kasan annotation we can ensure that they are not merged
back together.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/media/usb/em28xx/em28xx-dvb.c | 947 ++++++++++++++++++----------------
 1 file changed, 508 insertions(+), 439 deletions(-)

diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c
index 82edd37f0d73..83125a05918a 100644
--- a/drivers/media/usb/em28xx/em28xx-dvb.c
+++ b/drivers/media/usb/em28xx/em28xx-dvb.c
@@ -934,7 +934,7 @@ static struct lgdt3306a_config hauppauge_01595_lgdt3306a_config = {
 
 /* ------------------------------------------------------------------ */
 
-static int em28xx_attach_xc3028(u8 addr, struct em28xx *dev)
+static noinline_for_kasan int em28xx_attach_xc3028(u8 addr, struct em28xx *dev)
 {
 	struct dvb_frontend *fe;
 	struct xc2028_config cfg;
@@ -1126,6 +1126,492 @@ static void em28xx_unregister_dvb(struct em28xx_dvb *dvb)
 	dvb_unregister_adapter(&dvb->adapter);
 }
 
+static noinline_for_kasan int em28174_dvb_init_pctv_460e(struct em28xx *dev)
+{
+	struct em28xx_dvb *dvb = dev->dvb;
+	struct i2c_client *client;
+	struct i2c_board_info board_info;
+	struct tda10071_platform_data tda10071_pdata = {};
+	struct a8293_platform_data a8293_pdata = {};
+	int result;
+
+	/* attach demod + tuner combo */
+	tda10071_pdata.clk = 40444000, /* 40.444 MHz */
+	tda10071_pdata.i2c_wr_max = 64,
+	tda10071_pdata.ts_mode = TDA10071_TS_SERIAL,
+	tda10071_pdata.pll_multiplier = 20,
+	tda10071_pdata.tuner_i2c_addr = 0x14,
+	memset(&board_info, 0, sizeof(board_info));
+	strlcpy(board_info.type, "tda10071_cx24118", I2C_NAME_SIZE);
+	board_info.addr = 0x55;
+	board_info.platform_data = &tda10071_pdata;
+	request_module("tda10071");
+	client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info);
+	if (client == NULL || client->dev.driver == NULL) {
+		result = -ENODEV;
+		goto out_free;
+	}
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		result = -ENODEV;
+		goto out_free;
+	}
+	dvb->fe[0] = tda10071_pdata.get_dvb_frontend(client);
+	dvb->i2c_client_demod = client;
+
+	/* attach SEC */
+	a8293_pdata.dvb_frontend = dvb->fe[0];
+	memset(&board_info, 0, sizeof(board_info));
+	strlcpy(board_info.type, "a8293", I2C_NAME_SIZE);
+	board_info.addr = 0x08;
+	board_info.platform_data = &a8293_pdata;
+	request_module("a8293");
+	client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info);
+	if (client == NULL || client->dev.driver == NULL) {
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+	dvb->i2c_client_sec = client;
+	result = 0;
+out_free:
+	return result;
+}
+
+static noinline_for_kasan int em28178_dvb_init_pctv_461e(struct em28xx *dev)
+{
+	struct em28xx_dvb *dvb = dev->dvb;
+	struct i2c_client *client;
+	struct i2c_adapter *i2c_adapter;
+	struct i2c_board_info board_info;
+	struct m88ds3103_platform_data m88ds3103_pdata = {};
+	struct ts2020_config ts2020_config = {};
+	struct a8293_platform_data a8293_pdata = {};
+	int result;
+
+	/* attach demod */
+	m88ds3103_pdata.clk = 27000000;
+	m88ds3103_pdata.i2c_wr_max = 33;
+	m88ds3103_pdata.ts_mode = M88DS3103_TS_PARALLEL;
+	m88ds3103_pdata.ts_clk = 16000;
+	m88ds3103_pdata.ts_clk_pol = 1;
+	m88ds3103_pdata.agc = 0x99;
+	memset(&board_info, 0, sizeof(board_info));
+	strlcpy(board_info.type, "m88ds3103", I2C_NAME_SIZE);
+	board_info.addr = 0x68;
+	board_info.platform_data = &m88ds3103_pdata;
+	request_module("m88ds3103");
+	client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info);
+	if (client == NULL || client->dev.driver == NULL) {
+		result = -ENODEV;
+		goto out_free;
+	}
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		result = -ENODEV;
+		goto out_free;
+	}
+	dvb->fe[0] = m88ds3103_pdata.get_dvb_frontend(client);
+	i2c_adapter = m88ds3103_pdata.get_i2c_adapter(client);
+	dvb->i2c_client_demod = client;
+
+	/* attach tuner */
+	ts2020_config.fe = dvb->fe[0];
+	memset(&board_info, 0, sizeof(board_info));
+	strlcpy(board_info.type, "ts2022", I2C_NAME_SIZE);
+	board_info.addr = 0x60;
+	board_info.platform_data = &ts2020_config;
+	request_module("ts2020");
+	client = i2c_new_device(i2c_adapter, &board_info);
+	if (client == NULL || client->dev.driver == NULL) {
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+	dvb->i2c_client_tuner = client;
+	/* delegate signal strength measurement to tuner */
+	dvb->fe[0]->ops.read_signal_strength =
+			dvb->fe[0]->ops.tuner_ops.get_rf_strength;
+
+	/* attach SEC */
+	a8293_pdata.dvb_frontend = dvb->fe[0];
+	memset(&board_info, 0, sizeof(board_info));
+	strlcpy(board_info.type, "a8293", I2C_NAME_SIZE);
+	board_info.addr = 0x08;
+	board_info.platform_data = &a8293_pdata;
+	request_module("a8293");
+	client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info);
+	if (client == NULL || client->dev.driver == NULL) {
+		module_put(dvb->i2c_client_tuner->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_tuner);
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		module_put(dvb->i2c_client_tuner->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_tuner);
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+	dvb->i2c_client_sec = client;
+	result = 0;
+out_free:
+	return result;
+}
+
+static noinline_for_kasan int em28178_dvb_init_pctv_292e(struct em28xx *dev)
+{
+	struct em28xx_dvb *dvb = dev->dvb;
+	struct i2c_adapter *adapter;
+	struct i2c_client *client;
+	struct i2c_board_info info;
+	struct si2168_config si2168_config;
+	struct si2157_config si2157_config;
+	int result;
+
+	/* attach demod */
+	memset(&si2168_config, 0, sizeof(si2168_config));
+	si2168_config.i2c_adapter = &adapter;
+	si2168_config.fe = &dvb->fe[0];
+	si2168_config.ts_mode = SI2168_TS_PARALLEL;
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "si2168", I2C_NAME_SIZE);
+	info.addr = 0x64;
+	info.platform_data = &si2168_config;
+	request_module(info.type);
+	client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info);
+	if (client == NULL || client->dev.driver == NULL) {
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	dvb->i2c_client_demod = client;
+
+	/* attach tuner */
+	memset(&si2157_config, 0, sizeof(si2157_config));
+	si2157_config.fe = dvb->fe[0];
+	si2157_config.if_port = 1;
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+	si2157_config.mdev = dev->media_dev;
+#endif
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "si2157", I2C_NAME_SIZE);
+	info.addr = 0x60;
+	info.platform_data = &si2157_config;
+	request_module(info.type);
+	client = i2c_new_device(adapter, &info);
+	if (client == NULL || client->dev.driver == NULL) {
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	dvb->i2c_client_tuner = client;
+	dvb->fe[0]->ops.set_lna = em28xx_pctv_292e_set_lna;
+	result = 0;
+out_free:
+	return result;
+}
+
+static noinline_for_kasan int em28178_dvb_init_terratec_t2_stick_hd(struct em28xx *dev)
+{
+	struct em28xx_dvb *dvb = dev->dvb;
+	struct i2c_adapter *adapter;
+	struct i2c_client *client;
+	struct i2c_board_info info;
+	struct si2168_config si2168_config;
+	struct si2157_config si2157_config;
+	int result;
+
+	/* attach demod */
+	memset(&si2168_config, 0, sizeof(si2168_config));
+	si2168_config.i2c_adapter = &adapter;
+	si2168_config.fe = &dvb->fe[0];
+	si2168_config.ts_mode = SI2168_TS_PARALLEL;
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "si2168", I2C_NAME_SIZE);
+	info.addr = 0x64;
+	info.platform_data = &si2168_config;
+	request_module(info.type);
+	client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info);
+	if (client == NULL || client->dev.driver == NULL) {
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	dvb->i2c_client_demod = client;
+
+	/* attach tuner */
+	memset(&si2157_config, 0, sizeof(si2157_config));
+	si2157_config.fe = dvb->fe[0];
+	si2157_config.if_port = 0;
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+	si2157_config.mdev = dev->media_dev;
+#endif
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "si2146", I2C_NAME_SIZE);
+	info.addr = 0x60;
+	info.platform_data = &si2157_config;
+	request_module("si2157");
+	client = i2c_new_device(adapter, &info);
+	if (client == NULL || client->dev.driver == NULL) {
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	dvb->i2c_client_tuner = client;
+	result = 0;
+out_free:
+	return result;
+}
+
+static noinline_for_kasan int em28178_dvb_init_plex_px_bcud(struct em28xx *dev)
+{
+	struct em28xx_dvb *dvb = dev->dvb;
+	struct i2c_client *client;
+	struct i2c_board_info info;
+	struct tc90522_config tc90522_config;
+	struct qm1d1c0042_config qm1d1c0042_config;
+	int result;
+
+	/* attach demod */
+	memset(&tc90522_config, 0, sizeof(tc90522_config));
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "tc90522sat", I2C_NAME_SIZE);
+	info.addr = 0x15;
+	info.platform_data = &tc90522_config;
+	request_module("tc90522");
+	client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info);
+	if (client == NULL || client->dev.driver == NULL) {
+		result = -ENODEV;
+		goto out_free;
+	}
+	dvb->i2c_client_demod = client;
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	/* attach tuner */
+	memset(&qm1d1c0042_config, 0,
+	       sizeof(qm1d1c0042_config));
+	qm1d1c0042_config.fe = tc90522_config.fe;
+	qm1d1c0042_config.lpf = 1;
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "qm1d1c0042", I2C_NAME_SIZE);
+	info.addr = 0x61;
+	info.platform_data = &qm1d1c0042_config;
+	request_module(info.type);
+	client = i2c_new_device(tc90522_config.tuner_i2c,
+				&info);
+	if (client == NULL || client->dev.driver == NULL) {
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+	dvb->i2c_client_tuner = client;
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+	dvb->fe[0] = tc90522_config.fe;
+	px_bcud_init(dev);
+	result = 0;
+out_free:
+	return result;
+}
+
+static noinline_for_kasan int em28174_dvb_init_hauppauge_wintv_dualhd_dvb(struct em28xx *dev)
+{
+	struct em28xx_dvb *dvb = dev->dvb;
+	struct i2c_adapter *adapter;
+	struct i2c_client *client;
+	struct i2c_board_info info;
+	struct si2168_config si2168_config;
+	struct si2157_config si2157_config;
+	int result;
+
+	/* attach demod */
+	memset(&si2168_config, 0, sizeof(si2168_config));
+	si2168_config.i2c_adapter = &adapter;
+	si2168_config.fe = &dvb->fe[0];
+	si2168_config.ts_mode = SI2168_TS_SERIAL;
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "si2168", I2C_NAME_SIZE);
+	info.addr = 0x64;
+	info.platform_data = &si2168_config;
+	request_module(info.type);
+	client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info);
+	if (client == NULL || client->dev.driver == NULL) {
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	dvb->i2c_client_demod = client;
+
+	/* attach tuner */
+	memset(&si2157_config, 0, sizeof(si2157_config));
+	si2157_config.fe = dvb->fe[0];
+	si2157_config.if_port = 1;
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+	si2157_config.mdev = dev->media_dev;
+#endif
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "si2157", I2C_NAME_SIZE);
+	info.addr = 0x60;
+	info.platform_data = &si2157_config;
+	request_module(info.type);
+	client = i2c_new_device(adapter, &info);
+	if (client == NULL || client->dev.driver == NULL) {
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	dvb->i2c_client_tuner = client;
+	result = 0;
+out_free:
+	return result;
+}
+
+static int em28174_dvb_init_hauppauge_wintv_dualhd_01595(struct em28xx *dev)
+{
+	struct em28xx_dvb *dvb = dev->dvb;
+	struct i2c_adapter *adapter;
+	struct i2c_client *client;
+	struct i2c_board_info info = {};
+	struct lgdt3306a_config lgdt3306a_config;
+	struct si2157_config si2157_config = {};
+	int result;
+
+	/* attach demod */
+	lgdt3306a_config = hauppauge_01595_lgdt3306a_config;
+	lgdt3306a_config.fe = &dvb->fe[0];
+	lgdt3306a_config.i2c_adapter = &adapter;
+	strlcpy(info.type, "lgdt3306a", sizeof(info.type));
+	info.addr = 0x59;
+	info.platform_data = &lgdt3306a_config;
+	request_module(info.type);
+	client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus],
+			&info);
+	if (client == NULL || client->dev.driver == NULL) {
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	dvb->i2c_client_demod = client;
+
+	/* attach tuner */
+	si2157_config.fe = dvb->fe[0];
+	si2157_config.if_port = 1;
+	si2157_config.inversion = 1;
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+	si2157_config.mdev = dev->media_dev;
+#endif
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "si2157", sizeof(info.type));
+	info.addr = 0x60;
+	info.platform_data = &si2157_config;
+	request_module(info.type);
+
+	client = i2c_new_device(adapter, &info);
+	if (client == NULL || client->dev.driver == NULL) {
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	dvb->i2c_client_tuner = client;
+	result = 0;
+out_free:
+	return result;
+}
 static int em28xx_dvb_init(struct em28xx *dev)
 {
 	int result = 0;
@@ -1427,60 +1913,11 @@ static int em28xx_dvb_init(struct em28xx *dev)
 				   &dev->i2c_adap[dev->def_i2c_bus],
 				   &c3tech_duo_tda18271_config);
 		break;
-	case EM28174_BOARD_PCTV_460E: {
-		struct i2c_client *client;
-		struct i2c_board_info board_info;
-		struct tda10071_platform_data tda10071_pdata = {};
-		struct a8293_platform_data a8293_pdata = {};
-
-		/* attach demod + tuner combo */
-		tda10071_pdata.clk = 40444000, /* 40.444 MHz */
-		tda10071_pdata.i2c_wr_max = 64,
-		tda10071_pdata.ts_mode = TDA10071_TS_SERIAL,
-		tda10071_pdata.pll_multiplier = 20,
-		tda10071_pdata.tuner_i2c_addr = 0x14,
-		memset(&board_info, 0, sizeof(board_info));
-		strlcpy(board_info.type, "tda10071_cx24118", I2C_NAME_SIZE);
-		board_info.addr = 0x55;
-		board_info.platform_data = &tda10071_pdata;
-		request_module("tda10071");
-		client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info);
-		if (client == NULL || client->dev.driver == NULL) {
-			result = -ENODEV;
-			goto out_free;
-		}
-		if (!try_module_get(client->dev.driver->owner)) {
-			i2c_unregister_device(client);
-			result = -ENODEV;
-			goto out_free;
-		}
-		dvb->fe[0] = tda10071_pdata.get_dvb_frontend(client);
-		dvb->i2c_client_demod = client;
-
-		/* attach SEC */
-		a8293_pdata.dvb_frontend = dvb->fe[0];
-		memset(&board_info, 0, sizeof(board_info));
-		strlcpy(board_info.type, "a8293", I2C_NAME_SIZE);
-		board_info.addr = 0x08;
-		board_info.platform_data = &a8293_pdata;
-		request_module("a8293");
-		client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info);
-		if (client == NULL || client->dev.driver == NULL) {
-			module_put(dvb->i2c_client_demod->dev.driver->owner);
-			i2c_unregister_device(dvb->i2c_client_demod);
-			result = -ENODEV;
+	case EM28174_BOARD_PCTV_460E:
+		result = em28174_dvb_init_pctv_460e(dev);
+		if (result)
 			goto out_free;
-		}
-		if (!try_module_get(client->dev.driver->owner)) {
-			i2c_unregister_device(client);
-			module_put(dvb->i2c_client_demod->dev.driver->owner);
-			i2c_unregister_device(dvb->i2c_client_demod);
-			result = -ENODEV;
-			goto out_free;
-		}
-		dvb->i2c_client_sec = client;
 		break;
-	}
 	case EM2874_BOARD_DELOCK_61959:
 	case EM2874_BOARD_MAXMEDIA_UB425_TC:
 		/* attach demodulator */
@@ -1626,403 +2063,35 @@ static int em28xx_dvb_init(struct em28xx *dev)
 			}
 		}
 		break;
-	case EM28178_BOARD_PCTV_461E: {
-		struct i2c_client *client;
-		struct i2c_adapter *i2c_adapter;
-		struct i2c_board_info board_info;
-		struct m88ds3103_platform_data m88ds3103_pdata = {};
-		struct ts2020_config ts2020_config = {};
-		struct a8293_platform_data a8293_pdata = {};
-
-		/* attach demod */
-		m88ds3103_pdata.clk = 27000000;
-		m88ds3103_pdata.i2c_wr_max = 33;
-		m88ds3103_pdata.ts_mode = M88DS3103_TS_PARALLEL;
-		m88ds3103_pdata.ts_clk = 16000;
-		m88ds3103_pdata.ts_clk_pol = 1;
-		m88ds3103_pdata.agc = 0x99;
-		memset(&board_info, 0, sizeof(board_info));
-		strlcpy(board_info.type, "m88ds3103", I2C_NAME_SIZE);
-		board_info.addr = 0x68;
-		board_info.platform_data = &m88ds3103_pdata;
-		request_module("m88ds3103");
-		client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info);
-		if (client == NULL || client->dev.driver == NULL) {
-			result = -ENODEV;
+	case EM28178_BOARD_PCTV_461E: 
+		result = em28178_dvb_init_pctv_461e(dev);
+		if (result)
 			goto out_free;
-		}
-		if (!try_module_get(client->dev.driver->owner)) {
-			i2c_unregister_device(client);
-			result = -ENODEV;
-			goto out_free;
-		}
-		dvb->fe[0] = m88ds3103_pdata.get_dvb_frontend(client);
-		i2c_adapter = m88ds3103_pdata.get_i2c_adapter(client);
-		dvb->i2c_client_demod = client;
-
-		/* attach tuner */
-		ts2020_config.fe = dvb->fe[0];
-		memset(&board_info, 0, sizeof(board_info));
-		strlcpy(board_info.type, "ts2022", I2C_NAME_SIZE);
-		board_info.addr = 0x60;
-		board_info.platform_data = &ts2020_config;
-		request_module("ts2020");
-		client = i2c_new_device(i2c_adapter, &board_info);
-		if (client == NULL || client->dev.driver == NULL) {
-			module_put(dvb->i2c_client_demod->dev.driver->owner);
-			i2c_unregister_device(dvb->i2c_client_demod);
-			result = -ENODEV;
-			goto out_free;
-		}
-		if (!try_module_get(client->dev.driver->owner)) {
-			i2c_unregister_device(client);
-			module_put(dvb->i2c_client_demod->dev.driver->owner);
-			i2c_unregister_device(dvb->i2c_client_demod);
-			result = -ENODEV;
-			goto out_free;
-		}
-		dvb->i2c_client_tuner = client;
-		/* delegate signal strength measurement to tuner */
-		dvb->fe[0]->ops.read_signal_strength =
-				dvb->fe[0]->ops.tuner_ops.get_rf_strength;
-
-		/* attach SEC */
-		a8293_pdata.dvb_frontend = dvb->fe[0];
-		memset(&board_info, 0, sizeof(board_info));
-		strlcpy(board_info.type, "a8293", I2C_NAME_SIZE);
-		board_info.addr = 0x08;
-		board_info.platform_data = &a8293_pdata;
-		request_module("a8293");
-		client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info);
-		if (client == NULL || client->dev.driver == NULL) {
-			module_put(dvb->i2c_client_tuner->dev.driver->owner);
-			i2c_unregister_device(dvb->i2c_client_tuner);
-			module_put(dvb->i2c_client_demod->dev.driver->owner);
-			i2c_unregister_device(dvb->i2c_client_demod);
-			result = -ENODEV;
-			goto out_free;
-		}
-		if (!try_module_get(client->dev.driver->owner)) {
-			i2c_unregister_device(client);
-			module_put(dvb->i2c_client_tuner->dev.driver->owner);
-			i2c_unregister_device(dvb->i2c_client_tuner);
-			module_put(dvb->i2c_client_demod->dev.driver->owner);
-			i2c_unregister_device(dvb->i2c_client_demod);
-			result = -ENODEV;
-			goto out_free;
-		}
-		dvb->i2c_client_sec = client;
 		break;
-	}
 	case EM28178_BOARD_PCTV_292E:
-		{
-			struct i2c_adapter *adapter;
-			struct i2c_client *client;
-			struct i2c_board_info info;
-			struct si2168_config si2168_config;
-			struct si2157_config si2157_config;
-
-			/* attach demod */
-			memset(&si2168_config, 0, sizeof(si2168_config));
-			si2168_config.i2c_adapter = &adapter;
-			si2168_config.fe = &dvb->fe[0];
-			si2168_config.ts_mode = SI2168_TS_PARALLEL;
-			memset(&info, 0, sizeof(struct i2c_board_info));
-			strlcpy(info.type, "si2168", I2C_NAME_SIZE);
-			info.addr = 0x64;
-			info.platform_data = &si2168_config;
-			request_module(info.type);
-			client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info);
-			if (client == NULL || client->dev.driver == NULL) {
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			if (!try_module_get(client->dev.driver->owner)) {
-				i2c_unregister_device(client);
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			dvb->i2c_client_demod = client;
-
-			/* attach tuner */
-			memset(&si2157_config, 0, sizeof(si2157_config));
-			si2157_config.fe = dvb->fe[0];
-			si2157_config.if_port = 1;
-#ifdef CONFIG_MEDIA_CONTROLLER_DVB
-			si2157_config.mdev = dev->media_dev;
-#endif
-			memset(&info, 0, sizeof(struct i2c_board_info));
-			strlcpy(info.type, "si2157", I2C_NAME_SIZE);
-			info.addr = 0x60;
-			info.platform_data = &si2157_config;
-			request_module(info.type);
-			client = i2c_new_device(adapter, &info);
-			if (client == NULL || client->dev.driver == NULL) {
-				module_put(dvb->i2c_client_demod->dev.driver->owner);
-				i2c_unregister_device(dvb->i2c_client_demod);
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			if (!try_module_get(client->dev.driver->owner)) {
-				i2c_unregister_device(client);
-				module_put(dvb->i2c_client_demod->dev.driver->owner);
-				i2c_unregister_device(dvb->i2c_client_demod);
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			dvb->i2c_client_tuner = client;
-			dvb->fe[0]->ops.set_lna = em28xx_pctv_292e_set_lna;
-		}
+		result = em28178_dvb_init_pctv_292e(dev);
+		if (result)
+			goto out_free;
 		break;
 	case EM28178_BOARD_TERRATEC_T2_STICK_HD:
-		{
-			struct i2c_adapter *adapter;
-			struct i2c_client *client;
-			struct i2c_board_info info;
-			struct si2168_config si2168_config;
-			struct si2157_config si2157_config;
-
-			/* attach demod */
-			memset(&si2168_config, 0, sizeof(si2168_config));
-			si2168_config.i2c_adapter = &adapter;
-			si2168_config.fe = &dvb->fe[0];
-			si2168_config.ts_mode = SI2168_TS_PARALLEL;
-			memset(&info, 0, sizeof(struct i2c_board_info));
-			strlcpy(info.type, "si2168", I2C_NAME_SIZE);
-			info.addr = 0x64;
-			info.platform_data = &si2168_config;
-			request_module(info.type);
-			client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info);
-			if (client == NULL || client->dev.driver == NULL) {
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			if (!try_module_get(client->dev.driver->owner)) {
-				i2c_unregister_device(client);
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			dvb->i2c_client_demod = client;
-
-			/* attach tuner */
-			memset(&si2157_config, 0, sizeof(si2157_config));
-			si2157_config.fe = dvb->fe[0];
-			si2157_config.if_port = 0;
-#ifdef CONFIG_MEDIA_CONTROLLER_DVB
-			si2157_config.mdev = dev->media_dev;
-#endif
-			memset(&info, 0, sizeof(struct i2c_board_info));
-			strlcpy(info.type, "si2146", I2C_NAME_SIZE);
-			info.addr = 0x60;
-			info.platform_data = &si2157_config;
-			request_module("si2157");
-			client = i2c_new_device(adapter, &info);
-			if (client == NULL || client->dev.driver == NULL) {
-				module_put(dvb->i2c_client_demod->dev.driver->owner);
-				i2c_unregister_device(dvb->i2c_client_demod);
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			if (!try_module_get(client->dev.driver->owner)) {
-				i2c_unregister_device(client);
-				module_put(dvb->i2c_client_demod->dev.driver->owner);
-				i2c_unregister_device(dvb->i2c_client_demod);
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			dvb->i2c_client_tuner = client;
-		}
+		result = em28178_dvb_init_terratec_t2_stick_hd(dev);
+		if (result)
+			goto out_free;
 		break;
-
 	case EM28178_BOARD_PLEX_PX_BCUD:
-		{
-			struct i2c_client *client;
-			struct i2c_board_info info;
-			struct tc90522_config tc90522_config;
-			struct qm1d1c0042_config qm1d1c0042_config;
-
-			/* attach demod */
-			memset(&tc90522_config, 0, sizeof(tc90522_config));
-			memset(&info, 0, sizeof(struct i2c_board_info));
-			strlcpy(info.type, "tc90522sat", I2C_NAME_SIZE);
-			info.addr = 0x15;
-			info.platform_data = &tc90522_config;
-			request_module("tc90522");
-			client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info);
-			if (client == NULL || client->dev.driver == NULL) {
-				result = -ENODEV;
-				goto out_free;
-			}
-			dvb->i2c_client_demod = client;
-			if (!try_module_get(client->dev.driver->owner)) {
-				i2c_unregister_device(client);
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			/* attach tuner */
-			memset(&qm1d1c0042_config, 0,
-			       sizeof(qm1d1c0042_config));
-			qm1d1c0042_config.fe = tc90522_config.fe;
-			qm1d1c0042_config.lpf = 1;
-			memset(&info, 0, sizeof(struct i2c_board_info));
-			strlcpy(info.type, "qm1d1c0042", I2C_NAME_SIZE);
-			info.addr = 0x61;
-			info.platform_data = &qm1d1c0042_config;
-			request_module(info.type);
-			client = i2c_new_device(tc90522_config.tuner_i2c,
-						&info);
-			if (client == NULL || client->dev.driver == NULL) {
-				module_put(dvb->i2c_client_demod->dev.driver->owner);
-				i2c_unregister_device(dvb->i2c_client_demod);
-				result = -ENODEV;
-				goto out_free;
-			}
-			dvb->i2c_client_tuner = client;
-			if (!try_module_get(client->dev.driver->owner)) {
-				i2c_unregister_device(client);
-				module_put(dvb->i2c_client_demod->dev.driver->owner);
-				i2c_unregister_device(dvb->i2c_client_demod);
-				result = -ENODEV;
-				goto out_free;
-			}
-			dvb->fe[0] = tc90522_config.fe;
-			px_bcud_init(dev);
-		}
+		result = em28178_dvb_init_plex_px_bcud(dev);
+		if (result)
+			goto out_free;
 		break;
 	case EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB:
-		{
-			struct i2c_adapter *adapter;
-			struct i2c_client *client;
-			struct i2c_board_info info;
-			struct si2168_config si2168_config;
-			struct si2157_config si2157_config;
-
-			/* attach demod */
-			memset(&si2168_config, 0, sizeof(si2168_config));
-			si2168_config.i2c_adapter = &adapter;
-			si2168_config.fe = &dvb->fe[0];
-			si2168_config.ts_mode = SI2168_TS_SERIAL;
-			memset(&info, 0, sizeof(struct i2c_board_info));
-			strlcpy(info.type, "si2168", I2C_NAME_SIZE);
-			info.addr = 0x64;
-			info.platform_data = &si2168_config;
-			request_module(info.type);
-			client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info);
-			if (client == NULL || client->dev.driver == NULL) {
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			if (!try_module_get(client->dev.driver->owner)) {
-				i2c_unregister_device(client);
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			dvb->i2c_client_demod = client;
-
-			/* attach tuner */
-			memset(&si2157_config, 0, sizeof(si2157_config));
-			si2157_config.fe = dvb->fe[0];
-			si2157_config.if_port = 1;
-#ifdef CONFIG_MEDIA_CONTROLLER_DVB
-			si2157_config.mdev = dev->media_dev;
-#endif
-			memset(&info, 0, sizeof(struct i2c_board_info));
-			strlcpy(info.type, "si2157", I2C_NAME_SIZE);
-			info.addr = 0x60;
-			info.platform_data = &si2157_config;
-			request_module(info.type);
-			client = i2c_new_device(adapter, &info);
-			if (client == NULL || client->dev.driver == NULL) {
-				module_put(dvb->i2c_client_demod->dev.driver->owner);
-				i2c_unregister_device(dvb->i2c_client_demod);
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			if (!try_module_get(client->dev.driver->owner)) {
-				i2c_unregister_device(client);
-				module_put(dvb->i2c_client_demod->dev.driver->owner);
-				i2c_unregister_device(dvb->i2c_client_demod);
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			dvb->i2c_client_tuner = client;
-
-		}
+		result = em28174_dvb_init_hauppauge_wintv_dualhd_dvb(dev);
+		if (result)
+			goto out_free;
 		break;
 	case EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595:
-		{
-			struct i2c_adapter *adapter;
-			struct i2c_client *client;
-			struct i2c_board_info info = {};
-			struct lgdt3306a_config lgdt3306a_config;
-			struct si2157_config si2157_config = {};
-
-			/* attach demod */
-			lgdt3306a_config = hauppauge_01595_lgdt3306a_config;
-			lgdt3306a_config.fe = &dvb->fe[0];
-			lgdt3306a_config.i2c_adapter = &adapter;
-			strlcpy(info.type, "lgdt3306a", sizeof(info.type));
-			info.addr = 0x59;
-			info.platform_data = &lgdt3306a_config;
-			request_module(info.type);
-			client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus],
-					&info);
-			if (client == NULL || client->dev.driver == NULL) {
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			if (!try_module_get(client->dev.driver->owner)) {
-				i2c_unregister_device(client);
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			dvb->i2c_client_demod = client;
-
-			/* attach tuner */
-			si2157_config.fe = dvb->fe[0];
-			si2157_config.if_port = 1;
-			si2157_config.inversion = 1;
-#ifdef CONFIG_MEDIA_CONTROLLER_DVB
-			si2157_config.mdev = dev->media_dev;
-#endif
-			memset(&info, 0, sizeof(struct i2c_board_info));
-			strlcpy(info.type, "si2157", sizeof(info.type));
-			info.addr = 0x60;
-			info.platform_data = &si2157_config;
-			request_module(info.type);
-
-			client = i2c_new_device(adapter, &info);
-			if (client == NULL || client->dev.driver == NULL) {
-				module_put(dvb->i2c_client_demod->dev.driver->owner);
-				i2c_unregister_device(dvb->i2c_client_demod);
-				result = -ENODEV;
-				goto out_free;
-			}
-			if (!try_module_get(client->dev.driver->owner)) {
-				i2c_unregister_device(client);
-				module_put(dvb->i2c_client_demod->dev.driver->owner);
-				i2c_unregister_device(dvb->i2c_client_demod);
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			dvb->i2c_client_tuner = client;
-		}
+		result = em28174_dvb_init_hauppauge_wintv_dualhd_01595(dev);
+		if (result)
+			goto out_free;
 		break;
 	default:
 		dev_err(&dev->intf->dev,
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 21/26] drm/bridge: ps8622: reduce stack size for KASAN
  2017-03-02 16:38 [PATCH 00/26] bring back stack frame warning with KASAN Arnd Bergmann
                   ` (19 preceding siblings ...)
  2017-03-02 16:38 ` [PATCH 20/26] [media] em28xx: split up em28xx_dvb_init to reduce stack size Arnd Bergmann
@ 2017-03-02 16:38 ` Arnd Bergmann
  2017-03-02 16:38 ` [PATCH 22/26] drm/i915/gvt: don't overflow the kernel stack with KASAN Arnd Bergmann
                   ` (5 subsequent siblings)
  26 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann

When CONFIG_KASAN is set, each call to ps8622_set() adds an object to the
stack frame, leading to a warning about possible stack overflow:

drivers/gpu/drm/bridge/parade-ps8622.c: In function 'ps8622_send_config':
drivers/gpu/drm/bridge/parade-ps8622.c:338:1: error: the frame size of 5872 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]

Marking this as noinline_for_kasan completely avoids the problem.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/gpu/drm/bridge/parade-ps8622.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/parade-ps8622.c b/drivers/gpu/drm/bridge/parade-ps8622.c
index ac8cc5b50d9f..6b995edd2a46 100644
--- a/drivers/gpu/drm/bridge/parade-ps8622.c
+++ b/drivers/gpu/drm/bridge/parade-ps8622.c
@@ -79,7 +79,7 @@ static inline struct ps8622_bridge *
 	return container_of(connector, struct ps8622_bridge, connector);
 }
 
-static int ps8622_set(struct i2c_client *client, u8 page, u8 reg, u8 val)
+static noinline_for_kasan int ps8622_set(struct i2c_client *client, u8 page, u8 reg, u8 val)
 {
 	int ret;
 	struct i2c_adapter *adap = client->adapter;
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 22/26] drm/i915/gvt: don't overflow the kernel stack with KASAN
  2017-03-02 16:38 [PATCH 00/26] bring back stack frame warning with KASAN Arnd Bergmann
                   ` (20 preceding siblings ...)
  2017-03-02 16:38 ` [PATCH 21/26] drm/bridge: ps8622: reduce stack size for KASAN Arnd Bergmann
@ 2017-03-02 16:38 ` Arnd Bergmann
  2017-03-02 16:38 ` [PATCH 23/26] mtd: cfi: reduce stack size " Arnd Bergmann
                   ` (4 subsequent siblings)
  26 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann

Enabling CONFIG_KASAN can lead to an instant stack overflow:

drivers/gpu/drm/i915/gvt/handlers.c: In function 'init_generic_mmio_info':
drivers/gpu/drm/i915/gvt/handlers.c:2200:1: error: the frame size of 30464 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
drivers/gpu/drm/i915/gvt/handlers.c: In function 'init_broadwell_mmio_info':
drivers/gpu/drm/i915/gvt/handlers.c:2402:1: error: the frame size of 5376 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
drivers/gpu/drm/i915/gvt/handlers.c: In function 'init_skl_mmio_info':
drivers/gpu/drm/i915/gvt/handlers.c:2628:1: error: the frame size of 5296 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]

The reason is the INTEL_GVT_MMIO_OFFSET() hack that attempts to convert any type
(including i915_reg_t) into a u32 by reading the first four bytes, in combination
with the stack sanitizer that adds a redzone around each instance.

Originally, i915_reg_t was introduced to add a little extra type safety by
disallowing simple type casts, and INTEL_GVT_MMIO_OFFSET() goes the opposite
way by allowing any type as input, including those that are not safe in this
context.

I'm replacing it with an implementation that specifically allows the three
types that are actually used as input: 'i915_reg_t' (from _MMIO constants),
'int' (from other constants), and 'unsigned int' (from function arguments),
and any other type should now provoke a build error. This also solves the
stack overflow as we no longer use a local variable for each instance.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/gpu/drm/i915/gvt/mmio.h | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/mmio.h b/drivers/gpu/drm/i915/gvt/mmio.h
index 3bc620f56f35..bf40100fc626 100644
--- a/drivers/gpu/drm/i915/gvt/mmio.h
+++ b/drivers/gpu/drm/i915/gvt/mmio.h
@@ -78,13 +78,20 @@ bool intel_gvt_match_device(struct intel_gvt *gvt, unsigned long device);
 int intel_gvt_setup_mmio_info(struct intel_gvt *gvt);
 void intel_gvt_clean_mmio_info(struct intel_gvt *gvt);
 
+static inline u32 intel_gvt_mmio_offset(unsigned int offset)
+{
+	return offset;
+}
+
 struct intel_gvt_mmio_info *intel_gvt_find_mmio_info(struct intel_gvt *gvt,
 						     unsigned int offset);
-#define INTEL_GVT_MMIO_OFFSET(reg) ({ \
-	typeof(reg) __reg = reg; \
-	u32 *offset = (u32 *)&__reg; \
-	*offset; \
-})
+#define INTEL_GVT_MMIO_OFFSET(reg) \
+__builtin_choose_expr(__builtin_types_compatible_p(typeof(reg), int), intel_gvt_mmio_offset, \
+__builtin_choose_expr(__builtin_types_compatible_p(typeof(reg), unsigned int), intel_gvt_mmio_offset, \
+__builtin_choose_expr(__builtin_types_compatible_p(typeof(reg), i915_reg_t), i915_mmio_reg_offset, \
+	(void)(0) \
+)))(reg)
+
 
 int intel_vgpu_init_mmio(struct intel_vgpu *vgpu);
 void intel_vgpu_reset_mmio(struct intel_vgpu *vgpu);
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 23/26] mtd: cfi: reduce stack size with KASAN
  2017-03-02 16:38 [PATCH 00/26] bring back stack frame warning with KASAN Arnd Bergmann
                   ` (21 preceding siblings ...)
  2017-03-02 16:38 ` [PATCH 22/26] drm/i915/gvt: don't overflow the kernel stack with KASAN Arnd Bergmann
@ 2017-03-02 16:38 ` Arnd Bergmann
  2017-03-02 16:38 ` [PATCH 24/26] ocfs2: " Arnd Bergmann
                   ` (3 subsequent siblings)
  26 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann

When CONFIG_KASAN is used, we consume a lot of extra stack space:

drivers/mtd/chips/cfi_cmdset_0020.c: In function 'do_write_buffer':
drivers/mtd/chips/cfi_cmdset_0020.c:603:1: error: the frame size of 2080 bytes is larger than 1536 bytes [-Werror=frame-larger-than=]
drivers/mtd/chips/cfi_cmdset_0020.c: In function 'cfi_staa_erase_varsize':
drivers/mtd/chips/cfi_cmdset_0020.c:972:1: error: the frame size of 1936 bytes is larger than 1536 bytes [-Werror=frame-larger-than=]
drivers/mtd/chips/cfi_cmdset_0001.c: In function 'do_write_buffer':
drivers/mtd/chips/cfi_cmdset_0001.c:1841:1: error: the frame size of 1776 bytes is larger than 1536 bytes [-Werror=frame-larger-than=]

This marks some functions as noinline_for_kasan to keep reduce the
overall stack size.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/mtd/chips/cfi_cmdset_0020.c | 8 ++++----
 include/linux/mtd/map.h             | 8 ++++----
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c
index 94d3eb42c4d5..8a21e030829c 100644
--- a/drivers/mtd/chips/cfi_cmdset_0020.c
+++ b/drivers/mtd/chips/cfi_cmdset_0020.c
@@ -244,7 +244,7 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map)
 }
 
 
-static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
+static noinline_for_kasan int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
 {
 	map_word status, status_OK;
 	unsigned long timeo;
@@ -728,7 +728,7 @@ cfi_staa_writev(struct mtd_info *mtd, const struct kvec *vecs,
 }
 
 
-static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
+static noinline_for_kasan int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
 {
 	struct cfi_private *cfi = map->fldrv_priv;
 	map_word status, status_OK;
@@ -1029,7 +1029,7 @@ static void cfi_staa_sync (struct mtd_info *mtd)
 	}
 }
 
-static inline int do_lock_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
+static noinline_for_kasan int do_lock_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
 {
 	struct cfi_private *cfi = map->fldrv_priv;
 	map_word status, status_OK;
@@ -1175,7 +1175,7 @@ static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 	}
 	return 0;
 }
-static inline int do_unlock_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
+static noinline_for_kasan int do_unlock_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
 {
 	struct cfi_private *cfi = map->fldrv_priv;
 	map_word status, status_OK;
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h
index 3aa56e3104bb..8c2e241f45c7 100644
--- a/include/linux/mtd/map.h
+++ b/include/linux/mtd/map.h
@@ -316,7 +316,7 @@ static inline map_word map_word_or(struct map_info *map, map_word val1, map_word
 	return r;
 }
 
-static inline int map_word_andequal(struct map_info *map, map_word val1, map_word val2, map_word val3)
+static noinline_for_kasan int map_word_andequal(struct map_info *map, map_word val1, map_word val2, map_word val3)
 {
 	int i;
 
@@ -328,7 +328,7 @@ static inline int map_word_andequal(struct map_info *map, map_word val1, map_wor
 	return 1;
 }
 
-static inline int map_word_bitsset(struct map_info *map, map_word val1, map_word val2)
+static noinline_for_kasan int map_word_bitsset(struct map_info *map, map_word val1, map_word val2)
 {
 	int i;
 
@@ -362,7 +362,7 @@ static inline map_word map_word_load(struct map_info *map, const void *ptr)
 	return r;
 }
 
-static inline map_word map_word_load_partial(struct map_info *map, map_word orig, const unsigned char *buf, int start, int len)
+static noinline_for_kasan map_word map_word_load_partial(struct map_info *map, map_word orig, const unsigned char *buf, int start, int len)
 {
 	int i;
 
@@ -392,7 +392,7 @@ static inline map_word map_word_load_partial(struct map_info *map, map_word orig
 #define MAP_FF_LIMIT 8
 #endif
 
-static inline map_word map_word_ff(struct map_info *map)
+static noinline_for_kasan map_word map_word_ff(struct map_info *map)
 {
 	map_word r;
 	int i;
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 24/26] ocfs2: reduce stack size with KASAN
  2017-03-02 16:38 [PATCH 00/26] bring back stack frame warning with KASAN Arnd Bergmann
                   ` (22 preceding siblings ...)
  2017-03-02 16:38 ` [PATCH 23/26] mtd: cfi: reduce stack size " Arnd Bergmann
@ 2017-03-02 16:38 ` Arnd Bergmann
  2017-03-02 17:46   ` Joe Perches
  2017-03-02 16:38 ` [PATCH 25/26] isdn: eicon: mark divascapi incompatible with kasan Arnd Bergmann
                   ` (2 subsequent siblings)
  26 siblings, 1 reply; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann, Joe Perches

The internal logging infrastructure in ocfs2 causes special warning code to be
used with KASAN, which produces rather large stack frames:

fs/ocfs2/super.c: In function 'ocfs2_fill_super':
fs/ocfs2/super.c:1219:1: error: the frame size of 3264 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]

By simply passing the mask by value instead of reference, we can avoid the
problem completely. On 64-bit architectures, this is also more efficient,
while on the less common (at least among ocfs2 users) 32-bit architectures,
I'm guessing that the resulting code is comparable to what it was before.

The current version was introduced by Joe Perches as an optimization, maybe
he can see if my change regresses compared to his.

Cc: Joe Perches <joe@perches.com>
Fixes: 7c2bd2f930ae ("ocfs2: reduce object size of mlog uses")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 fs/ocfs2/cluster/masklog.c | 10 +++++-----
 fs/ocfs2/cluster/masklog.h |  4 ++--
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/fs/ocfs2/cluster/masklog.c b/fs/ocfs2/cluster/masklog.c
index d331c2386b94..9720c5443e4d 100644
--- a/fs/ocfs2/cluster/masklog.c
+++ b/fs/ocfs2/cluster/masklog.c
@@ -64,7 +64,7 @@ static ssize_t mlog_mask_store(u64 mask, const char *buf, size_t count)
 	return count;
 }
 
-void __mlog_printk(const u64 *mask, const char *func, int line,
+void __mlog_printk(const u64 mask, const char *func, int line,
 		   const char *fmt, ...)
 {
 	struct va_format vaf;
@@ -72,14 +72,14 @@ void __mlog_printk(const u64 *mask, const char *func, int line,
 	const char *level;
 	const char *prefix = "";
 
-	if (!__mlog_test_u64(*mask, mlog_and_bits) ||
-	    __mlog_test_u64(*mask, mlog_not_bits))
+	if (!__mlog_test_u64(mask, mlog_and_bits) ||
+	    __mlog_test_u64(mask, mlog_not_bits))
 		return;
 
-	if (*mask & ML_ERROR) {
+	if (mask & ML_ERROR) {
 		level = KERN_ERR;
 		prefix = "ERROR: ";
-	} else if (*mask & ML_NOTICE) {
+	} else if (mask & ML_NOTICE) {
 		level = KERN_NOTICE;
 	} else {
 		level = KERN_INFO;
diff --git a/fs/ocfs2/cluster/masklog.h b/fs/ocfs2/cluster/masklog.h
index 308ea0eb35fd..0d0f4bf2c3d8 100644
--- a/fs/ocfs2/cluster/masklog.h
+++ b/fs/ocfs2/cluster/masklog.h
@@ -163,7 +163,7 @@ extern struct mlog_bits mlog_and_bits, mlog_not_bits;
 #endif
 
 __printf(4, 5)
-void __mlog_printk(const u64 *m, const char *func, int line,
+void __mlog_printk(const u64 m, const char *func, int line,
 		   const char *fmt, ...);
 
 /*
@@ -174,7 +174,7 @@ void __mlog_printk(const u64 *m, const char *func, int line,
 do {									\
 	u64 _m = MLOG_MASK_PREFIX | (mask);				\
 	if (_m & ML_ALLOWED_BITS)					\
-		__mlog_printk(&_m, __func__, __LINE__, fmt,		\
+		__mlog_printk(_m, __func__, __LINE__, fmt,		\
 			      ##__VA_ARGS__);				\
 } while (0)
 
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 25/26] isdn: eicon: mark divascapi incompatible with kasan
  2017-03-02 16:38 [PATCH 00/26] bring back stack frame warning with KASAN Arnd Bergmann
                   ` (23 preceding siblings ...)
  2017-03-02 16:38 ` [PATCH 24/26] ocfs2: " Arnd Bergmann
@ 2017-03-02 16:38 ` Arnd Bergmann
  2017-03-03 14:20   ` Andrey Ryabinin
  2017-03-02 16:38 ` [PATCH 26/26] kasan: rework Kconfig settings Arnd Bergmann
  2017-03-03 12:25 ` [PATCH 00/26] bring back stack frame warning with KASAN Alexander Potapenko
  26 siblings, 1 reply; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann

When CONFIG_KASAN is enabled, we have several functions that use rather
large kernel stacks, e.g.

drivers/isdn/hardware/eicon/message.c: In function 'group_optimization':
drivers/isdn/hardware/eicon/message.c:14841:1: warning: the frame size of 864 bytes is larger than 500 bytes [-Wframe-larger-than=]
drivers/isdn/hardware/eicon/message.c: In function 'add_b1':
drivers/isdn/hardware/eicon/message.c:7925:1: warning: the frame size of 1008 bytes is larger than 500 bytes [-Wframe-larger-than=]
drivers/isdn/hardware/eicon/message.c: In function 'add_b23':
drivers/isdn/hardware/eicon/message.c:8551:1: warning: the frame size of 928 bytes is larger than 500 bytes [-Wframe-larger-than=]
drivers/isdn/hardware/eicon/message.c: In function 'sig_ind':
drivers/isdn/hardware/eicon/message.c:6113:1: warning: the frame size of 2112 bytes is larger than 500 bytes [-Wframe-larger-than=]

To be on the safe side, and to enable a lower frame size warning limit, let's
just mark this driver as broken when KASAN is in use. I have tried to reduce
the stack size as I did with dozens of other drivers, but failed to come up
with a good solution for this one.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/isdn/hardware/eicon/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/isdn/hardware/eicon/Kconfig b/drivers/isdn/hardware/eicon/Kconfig
index 6082b6a5ced3..b64496062421 100644
--- a/drivers/isdn/hardware/eicon/Kconfig
+++ b/drivers/isdn/hardware/eicon/Kconfig
@@ -31,6 +31,7 @@ config ISDN_DIVAS_PRIPCI
 
 config ISDN_DIVAS_DIVACAPI
 	tristate "DIVA CAPI2.0 interface support"
+	depends on !KASAN || BROKEN
 	help
 	  You need this to provide the CAPI interface
 	  for DIVA Server cards.
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 26/26] kasan: rework Kconfig settings
  2017-03-02 16:38 [PATCH 00/26] bring back stack frame warning with KASAN Arnd Bergmann
                   ` (24 preceding siblings ...)
  2017-03-02 16:38 ` [PATCH 25/26] isdn: eicon: mark divascapi incompatible with kasan Arnd Bergmann
@ 2017-03-02 16:38 ` Arnd Bergmann
  2017-03-03 14:51   ` Andrey Ryabinin
  2017-03-03 12:25 ` [PATCH 00/26] bring back stack frame warning with KASAN Alexander Potapenko
  26 siblings, 1 reply; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann

We get a lot of very large stack frames using gcc-7.0.1 with the default
-fsanitize-address-use-after-scope --param asan-stack=1 options, which
can easily cause an overflow of the kernel stack, e.g.

drivers/acpi/nfit/core.c:2686:1: warning: the frame size of 4080 bytes is larger than 2048 bytes [-Wframe-larger-than=]
drivers/gpu/drm/amd/amdgpu/si.c:1756:1: warning: the frame size of 7304 bytes is larger than 2048 bytes [-Wframe-larger-than=]
drivers/gpu/drm/i915/gvt/handlers.c:2200:1: warning: the frame size of 43752 bytes is larger than 2048 bytes [-Wframe-larger-than=]
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c:952:1: warning: the frame size of 6032 bytes is larger than 2048 bytes [-Wframe-larger-than=]
drivers/isdn/hardware/avm/b1.c:637:1: warning: the frame size of 13200 bytes is larger than 2048 bytes [-Wframe-larger-than=]
drivers/media/dvb-frontends/stv090x.c:3089:1: warning: the frame size of 5880 bytes is larger than 2048 bytes [-Wframe-larger-than=]
drivers/media/i2c/cx25840/cx25840-core.c:4964:1: warning: the frame size of 93992 bytes is larger than 2048 bytes [-Wframe-larger-than=]
drivers/net/wireless/ralink/rt2x00/rt2800lib.c:4994:1: warning: the frame size of 23928 bytes is larger than 2048 bytes [-Wframe-larger-than=]
drivers/staging/dgnc/dgnc_tty.c:2788:1: warning: the frame size of 7072 bytes is larger than 2048 bytes [-Wframe-larger-than=]
fs/ntfs/mft.c:2762:1: warning: the frame size of 7432 bytes is larger than 2048 bytes [-Wframe-larger-than=]
lib/atomic64_test.c:242:1: warning: the frame size of 12648 bytes is larger than 2048 bytes [-Wframe-larger-than=]

To reduce this risk, -fsanitize-address-use-after-scope is now split out
into a separate Kconfig option, vhich cannot be selected at the same
time as KMEMCHECK, leading to stack frames that are smaller than 2
kilobytes most of the time on x86_64. An earlier version of this
patch also prevented combining KASAN_EXTRA with KASAN_INLINE, but that
is no longer necessary with the latest gcc-7.0.1 snapshot.

A lot of warnings with KASAN_EXTRA go away if we disable KMEMCHECK,
as -fsanitize-address-use-after-scope seems to understand the builtin
memcpy, but adds checking code around an extern memcpy call. I had
to work around a circular dependency, as DEBUG_SLAB/SLUB depended
on !KMEMCHECK, while KASAN did it the other way round. Now we handle
both the same way.

All patches to get the frame size below 3072 bytes with KASAN_EXTRA,
and below 2048 bytes without it have been submitted, so we can make
those the default now. Note that KASAN is only supported on arm64
and x86_64 at the moment, and both use 2048 byte stacks by default.
This reverts parts of commit commit 3f181b4 ("lib/Kconfig.debug:
disable -Wframe-larger-than warnings with KASAN=y").

I experimented a bit more with smaller stack frames and have another
follow-up series that reduces the warning limit for 64-bit architectures
to 1280 bytes and 1536 when CONFIG_KASAN (but not KASAN_EXTRA) is
enabled, this requires another ~25 patches to address the additional
warnings.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 lib/Kconfig.debug      |  9 ++++-----
 lib/Kconfig.kasan      | 11 ++++++++++-
 lib/Kconfig.kmemcheck  |  1 +
 scripts/Makefile.kasan |  3 +++
 4 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 97d62c2da6c2..27c838c40a36 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -216,10 +216,9 @@ config ENABLE_MUST_CHECK
 config FRAME_WARN
 	int "Warn for stack frames larger than (needs gcc 4.4)"
 	range 0 8192
-	default 0 if KASAN
-	default 2048 if GCC_PLUGIN_LATENT_ENTROPY
+	default 3072 if KASAN_EXTRA
 	default 1024 if !64BIT
-	default 2048 if 64BIT
+	default 1280 if 64BIT
 	help
 	  Tell gcc to warn at build time for stack frames larger than this.
 	  Setting this too low will cause a lot of warnings.
@@ -499,7 +498,7 @@ config DEBUG_OBJECTS_ENABLE_DEFAULT
 
 config DEBUG_SLAB
 	bool "Debug slab memory allocations"
-	depends on DEBUG_KERNEL && SLAB && !KMEMCHECK
+	depends on DEBUG_KERNEL && SLAB && !KMEMCHECK && !KASAN
 	help
 	  Say Y here to have the kernel do limited verification on memory
 	  allocation as well as poisoning memory on free to catch use of freed
@@ -511,7 +510,7 @@ config DEBUG_SLAB_LEAK
 
 config SLUB_DEBUG_ON
 	bool "SLUB debugging on by default"
-	depends on SLUB && SLUB_DEBUG && !KMEMCHECK
+	depends on SLUB && SLUB_DEBUG && !KMEMCHECK && !KASAN
 	default n
 	help
 	  Boot with debugging on by default. SLUB boots by default with
diff --git a/lib/Kconfig.kasan b/lib/Kconfig.kasan
index bd38aab05929..e88ce7cc13bb 100644
--- a/lib/Kconfig.kasan
+++ b/lib/Kconfig.kasan
@@ -5,7 +5,7 @@ if HAVE_ARCH_KASAN
 
 config KASAN
 	bool "KASan: runtime memory debugger"
-	depends on SLUB || (SLAB && !DEBUG_SLAB)
+	depends on SLUB || SLAB
 	select CONSTRUCTORS
 	select STACKDEPOT
 	help
@@ -20,6 +20,15 @@ config KASAN
 	  Currently CONFIG_KASAN doesn't work with CONFIG_DEBUG_SLAB
 	  (the resulting kernel does not boot).
 
+config KASAN_EXTRA
+	bool "KAsan: extra checks"
+	depends on KASAN
+	help
+	  This enables further checks in the kernel address sanitizer, for now
+	  it only includes the address-use-after-scope check which requires the
+	  use of KASAN_OUTLINE to avoid excessive kernel stack frame sizes that
+	  might lead to stack overflows.
+
 choice
 	prompt "Instrumentation type"
 	depends on KASAN
diff --git a/lib/Kconfig.kmemcheck b/lib/Kconfig.kmemcheck
index 846e039a86b4..58b9f3f81dc8 100644
--- a/lib/Kconfig.kmemcheck
+++ b/lib/Kconfig.kmemcheck
@@ -7,6 +7,7 @@ menuconfig KMEMCHECK
 	bool "kmemcheck: trap use of uninitialized memory"
 	depends on DEBUG_KERNEL
 	depends on !X86_USE_3DNOW
+	depends on !KASAN_EXTRA
 	depends on SLUB || SLAB
 	depends on !CC_OPTIMIZE_FOR_SIZE
 	depends on !FUNCTION_TRACER
diff --git a/scripts/Makefile.kasan b/scripts/Makefile.kasan
index 9576775a86f6..3b3148faf866 100644
--- a/scripts/Makefile.kasan
+++ b/scripts/Makefile.kasan
@@ -29,5 +29,8 @@ else
     endif
 endif
 
+ifdef CONFIG_KASAN_EXTRA
 CFLAGS_KASAN += $(call cc-option, -fsanitize-address-use-after-scope)
 endif
+
+endif
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* Re: [PATCH 02/26] rewrite READ_ONCE/WRITE_ONCE
  2017-03-02 16:38 ` [PATCH 02/26] rewrite READ_ONCE/WRITE_ONCE Arnd Bergmann
@ 2017-03-02 16:51   ` Christian Borntraeger
  2017-03-02 17:55     ` Arnd Bergmann
  0 siblings, 1 reply; 67+ messages in thread
From: Christian Borntraeger @ 2017-03-02 16:51 UTC (permalink / raw)
  To: Arnd Bergmann, kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Paul McKenney

On 03/02/2017 05:38 PM, Arnd Bergmann wrote:
> When CONFIG_KASAN is enabled, the READ_ONCE/WRITE_ONCE macros cause
> rather large kernel stacks, e.g.:
> 
> mm/vmscan.c: In function 'shrink_page_list':
> mm/vmscan.c:1333:1: error: the frame size of 3456 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
> block/cfq-iosched.c: In function 'cfqg_stats_add_aux':
> block/cfq-iosched.c:750:1: error: the frame size of 4048 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
> fs/btrfs/disk-io.c: In function 'open_ctree':
> fs/btrfs/disk-io.c:3314:1: error: the frame size of 3136 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
> fs/btrfs/relocation.c: In function 'build_backref_tree':
> fs/btrfs/relocation.c:1193:1: error: the frame size of 4336 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
> fs/fscache/stats.c: In function 'fscache_stats_show':
> fs/fscache/stats.c:287:1: error: the frame size of 6512 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
> fs/jbd2/commit.c: In function 'jbd2_journal_commit_transaction':
> fs/jbd2/commit.c:1139:1: error: the frame size of 3760 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
> 
> This attempts a rewrite of the two macros, using a simpler implementation
> for the most common case of having a naturally aligned 1, 2, 4, or (on
> 64-bit architectures) 8  byte object that can be accessed with a single
> instruction.  For these, we go back to a volatile pointer dereference
> that we had with the ACCESS_ONCE macro.

We had changed that back then because gcc 4.6 and 4.7 had a bug that could
removed the volatile statement on aggregate types like the following one

union ipte_control {
        unsigned long val;
        struct {
                unsigned long k  : 1;
                unsigned long kh : 31;
                unsigned long kg : 32;
        };
};

See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145

If I see that right, your __ALIGNED_WORD(x)
macro would say that for above structure  sizeof(x) == sizeof(long)) is true,
so it would fall back to the old volatile cast and might reintroduce the 
old compiler bug?

Could you maybe you fence your simple macro for anything older than 4.9? After
all there was no kasan support anyway on these older gcc version.

Christian

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 24/26] ocfs2: reduce stack size with KASAN
  2017-03-02 16:38 ` [PATCH 24/26] ocfs2: " Arnd Bergmann
@ 2017-03-02 17:46   ` Joe Perches
  2017-03-02 22:22     ` Arnd Bergmann
  0 siblings, 1 reply; 67+ messages in thread
From: Joe Perches @ 2017-03-02 17:46 UTC (permalink / raw)
  To: Arnd Bergmann, kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller

On Thu, 2017-03-02 at 17:38 +0100, Arnd Bergmann wrote:
> The internal logging infrastructure in ocfs2 causes special warning code to be
> used with KASAN, which produces rather large stack frames:

> fs/ocfs2/super.c: In function 'ocfs2_fill_super':
> fs/ocfs2/super.c:1219:1: error: the frame size of 3264 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]

At least by default it doesn't seem to.

gcc 6.2 allyesconfig, CONFIG_KASAN=y
with either CONFIG_KASAN_INLINE or CONFIG_KASAN_OUTLINE

gcc doesn't emit a stack warning

> By simply passing the mask by value instead of reference, we can avoid the
> problem completely.

Any idea why that's so?
 
>  On 64-bit architectures, this is also more efficient,

Efficient true, but the same overall stack no?

> while on the less common (at least among ocfs2 users) 32-bit architectures,
> I'm guessing that the resulting code is comparable to what it was before.
> 
> The current version was introduced by Joe Perches as an optimization, maybe
> he can see if my change regresses compared to his.

I don't see it.

> Cc: Joe Perches <joe@perches.com>
> Fixes: 7c2bd2f930ae ("ocfs2: reduce object size of mlog uses")
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
>  fs/ocfs2/cluster/masklog.c | 10 +++++-----
>  fs/o cfs2/cluster/masklog.h |  4 ++--
>  2 files changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/fs/ocfs2/cluster/masklog.c b/fs/ocfs2/cluster/masklog.c
> index d331c2386b94..9720c5443e4d 100644
> --- a/fs/ocfs2/cluster/masklog.c
> +++ b/fs/ocfs2/cluster/masklog.c
> @@ -64,7 +64,7 @@ static ssize_t mlog_mask_store(u64 mask, const char *buf, size_t count)
>  	return count;
>  }
>  
> -void __mlog_printk(const u64 *mask, const char *func, int line,
> +void __mlog_printk(const u64 mask, const char *func, int line,
>  		   const char *fmt, ...)
>  {
>  	struct va_format vaf;
> @@ -72,14 +72,14 @@ void __mlog_printk(const u64 *mask, const char *func, int line,
>  	const char *level;
>  	const char *prefix = "";
>  
> -	if (!__mlog_test_u64(*mask, mlog_and_bits) ||
> -	    __mlog_test_u64(*mask, mlog_not_bits))
> +	if (!__mlog_test_u64(mask, mlog_and_bits) ||
> +	    __mlog_test_u64(mask, mlog_not_bits))
>  		return;
>  
> -	if (*mask & ML_ERROR) {
> +	if (mask & ML_ERROR) {
>  		level = KERN_ERR;
>  		prefix = "ERROR: ";
> -	} else if (*mask & ML_NOTICE) {
> +	} else if (mask & ML_NOTICE) {
>  		level = KERN_NOTICE;
>  	} else {
>  		level = KERN_INFO;
> diff --git a/fs/ocfs2/cluster/masklog.h b/fs/ocfs2/cluster/masklog.h
> index 308ea0eb35fd..0d0f4bf2c3d8 100644
> --- a/fs/ocfs2/cluster/masklog.h
> +++ b/fs/ocfs2/cluster/masklog.h
> @@ -163,7 +163,7 @@ extern struct mlog_bits mlog_and_bits, mlog_not_bits;
>  #endif
>  
>  __printf(4, 5)
> -void __mlog_printk(const u64 *m, const char *func, int line,
> +void __mlog_printk(const u64 m, const char *func, int line,
>  		   const char *fmt, ...);
>  
>  /*
> @@ -174,7 +174,7 @@ void __mlog_printk(const u64 *m, const char *func, int line,
>  do {									\
>  	u64 _m = MLOG_MASK_PREFIX | (mask);				\
>  	if (_m & ML_ALLOWED_BITS)					\
> -		__mlog_printk(&_m, __func__, __LINE__, fmt,		\
> +		__mlog_printk(_m, __func__, __LINE__, fmt,		\
>  			      ##__VA_ARGS__);				\
>  } while (0)
>  

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 02/26] rewrite READ_ONCE/WRITE_ONCE
  2017-03-02 16:51   ` Christian Borntraeger
@ 2017-03-02 17:55     ` Arnd Bergmann
  2017-03-02 19:00       ` Christian Borntraeger
  0 siblings, 1 reply; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 17:55 UTC (permalink / raw)
  To: Christian Borntraeger
  Cc: kasan-dev, Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
	Networking, Linux Kernel Mailing List, linux-media,
	linux-wireless, kernel-build-reports, David S . Miller,
	Paul McKenney

On Thu, Mar 2, 2017 at 5:51 PM, Christian Borntraeger
<borntraeger@de.ibm.com> wrote:
> On 03/02/2017 05:38 PM, Arnd Bergmann wrote:
>>
>> This attempts a rewrite of the two macros, using a simpler implementation
>> for the most common case of having a naturally aligned 1, 2, 4, or (on
>> 64-bit architectures) 8  byte object that can be accessed with a single
>> instruction.  For these, we go back to a volatile pointer dereference
>> that we had with the ACCESS_ONCE macro.
>
> We had changed that back then because gcc 4.6 and 4.7 had a bug that could
> removed the volatile statement on aggregate types like the following one
>
> union ipte_control {
>         unsigned long val;
>         struct {
>                 unsigned long k  : 1;
>                 unsigned long kh : 31;
>                 unsigned long kg : 32;
>         };
> };
>
> See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145
>
> If I see that right, your __ALIGNED_WORD(x)
> macro would say that for above structure  sizeof(x) == sizeof(long)) is true,
> so it would fall back to the old volatile cast and might reintroduce the
> old compiler bug?

Ah, right, that's the missing piece. For some reason I didn't find
the reference in the source or the git log.

> Could you maybe you fence your simple macro for anything older than 4.9? After
> all there was no kasan support anyway on these older gcc version.

Yes, that should work, thanks!

     Arnd

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 02/26] rewrite READ_ONCE/WRITE_ONCE
  2017-03-02 17:55     ` Arnd Bergmann
@ 2017-03-02 19:00       ` Christian Borntraeger
  2017-03-02 21:45         ` Arnd Bergmann
  0 siblings, 1 reply; 67+ messages in thread
From: Christian Borntraeger @ 2017-03-02 19:00 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: kasan-dev, Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
	Networking, Linux Kernel Mailing List, linux-media,
	linux-wireless, kernel-build-reports, David S . Miller,
	Paul McKenney

On 03/02/2017 06:55 PM, Arnd Bergmann wrote:
> On Thu, Mar 2, 2017 at 5:51 PM, Christian Borntraeger
> <borntraeger@de.ibm.com> wrote:
>> On 03/02/2017 05:38 PM, Arnd Bergmann wrote:
>>>
>>> This attempts a rewrite of the two macros, using a simpler implementation
>>> for the most common case of having a naturally aligned 1, 2, 4, or (on
>>> 64-bit architectures) 8  byte object that can be accessed with a single
>>> instruction.  For these, we go back to a volatile pointer dereference
>>> that we had with the ACCESS_ONCE macro.
>>
>> We had changed that back then because gcc 4.6 and 4.7 had a bug that could
>> removed the volatile statement on aggregate types like the following one
>>
>> union ipte_control {
>>         unsigned long val;
>>         struct {
>>                 unsigned long k  : 1;
>>                 unsigned long kh : 31;
>>                 unsigned long kg : 32;
>>         };
>> };
>>
>> See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145
>>
>> If I see that right, your __ALIGNED_WORD(x)
>> macro would say that for above structure  sizeof(x) == sizeof(long)) is true,
>> so it would fall back to the old volatile cast and might reintroduce the
>> old compiler bug?

Oh dear, I should double check my sentences in emails before sending...anyway
the full story is referenced in 

commit 60815cf2e05057db5b78e398d9734c493560b11e
    Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/borntraeger/linux
which has a pointer to
http://marc.info/?i=54611D86.4040306%40de.ibm.com
which contains the full story.

> 
> Ah, right, that's the missing piece. For some reason I didn't find
> the reference in the source or the git log.
> 
>> Could you maybe you fence your simple macro for anything older than 4.9? After
>> all there was no kasan support anyway on these older gcc version.
> 
> Yes, that should work, thanks!

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 02/26] rewrite READ_ONCE/WRITE_ONCE
  2017-03-02 19:00       ` Christian Borntraeger
@ 2017-03-02 21:45         ` Arnd Bergmann
  2017-03-03  8:26           ` Christian Borntraeger
  0 siblings, 1 reply; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 21:45 UTC (permalink / raw)
  To: Christian Borntraeger
  Cc: kasan-dev, Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
	Networking, Linux Kernel Mailing List, linux-media,
	linux-wireless, kernel-build-reports, David S . Miller,
	Paul McKenney

On Thu, Mar 2, 2017 at 8:00 PM, Christian Borntraeger
<borntraeger@de.ibm.com> wrote:
> On 03/02/2017 06:55 PM, Arnd Bergmann wrote:
>> On Thu, Mar 2, 2017 at 5:51 PM, Christian Borntraeger
>> <borntraeger@de.ibm.com> wrote:
>>> On 03/02/2017 05:38 PM, Arnd Bergmann wrote:
>>>>
>>>> This attempts a rewrite of the two macros, using a simpler implementation
>>>> for the most common case of having a naturally aligned 1, 2, 4, or (on
>>>> 64-bit architectures) 8  byte object that can be accessed with a single
>>>> instruction.  For these, we go back to a volatile pointer dereference
>>>> that we had with the ACCESS_ONCE macro.
>>>
>>> We had changed that back then because gcc 4.6 and 4.7 had a bug that could
>>> removed the volatile statement on aggregate types like the following one
>>>
>>> union ipte_control {
>>>         unsigned long val;
>>>         struct {
>>>                 unsigned long k  : 1;
>>>                 unsigned long kh : 31;
>>>                 unsigned long kg : 32;
>>>         };
>>> };
>>>
>>> See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145
>>>
>>> If I see that right, your __ALIGNED_WORD(x)
>>> macro would say that for above structure  sizeof(x) == sizeof(long)) is true,
>>> so it would fall back to the old volatile cast and might reintroduce the
>>> old compiler bug?
>
> Oh dear, I should double check my sentences in emails before sending...anyway
> the full story is referenced in
>
> commit 60815cf2e05057db5b78e398d9734c493560b11e
>     Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/borntraeger/linux
> which has a pointer to
> http://marc.info/?i=54611D86.4040306%40de.ibm.com
> which contains the full story.

Ok, got it. So I guess the behavior of forcing aligned accesses on aligned
data is accidental, and allowing non-power-of-two arguments is also not
the main purpose. Maybe we could just bail out on new compilers if we get
either of those? That might catch code that accidentally does something
that is inherently non-atomic or that causes a trap when the intention was
to have a simple atomic access.

     Arnd

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 24/26] ocfs2: reduce stack size with KASAN
  2017-03-02 17:46   ` Joe Perches
@ 2017-03-02 22:22     ` Arnd Bergmann
  2017-03-02 22:40       ` Joe Perches
  0 siblings, 1 reply; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 22:22 UTC (permalink / raw)
  To: Joe Perches
  Cc: kasan-dev, Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
	Networking, Linux Kernel Mailing List, linux-media,
	linux-wireless, kernel-build-reports, David S . Miller

On Thu, Mar 2, 2017 at 6:46 PM, Joe Perches <joe@perches.com> wrote:
> On Thu, 2017-03-02 at 17:38 +0100, Arnd Bergmann wrote:
>> The internal logging infrastructure in ocfs2 causes special warning code to be
>> used with KASAN, which produces rather large stack frames:
>
>> fs/ocfs2/super.c: In function 'ocfs2_fill_super':
>> fs/ocfs2/super.c:1219:1: error: the frame size of 3264 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
>
> At least by default it doesn't seem to.
>
> gcc 6.2 allyesconfig, CONFIG_KASAN=y
> with either CONFIG_KASAN_INLINE or CONFIG_KASAN_OUTLINE
>
> gcc doesn't emit a stack warning

The warning is disabled until patch 26/26. which picks the 3072 default.
The 3264 number was with gcc-7, which is worse than gcc-6 since it enables
an extra check.

>> By simply passing the mask by value instead of reference, we can avoid the
>> problem completely.
>
> Any idea why that's so?

With KASAN, every time we inline the function, the compiler has to allocate
space for another copy of the variable plus a redzone to detect whether
passing it by reference into another function causes an overflow at runtime.

>>  On 64-bit architectures, this is also more efficient,
>
> Efficient true, but the same overall stack no?

Here is what I see with CONFIG_FRAME_WARN=300 and x86_64-linux-gcc-6.3.1:

before:
fs/ocfs2/super.c: In function 'ocfs2_parse_options.isra.3':
fs/ocfs2/super.c:1508:1: error: the frame size of 352 bytes is larger
than 300 bytes [-Werror=frame-larger-than=]
fs/ocfs2/super.c: In function 'ocfs2_enable_quotas':
fs/ocfs2/super.c:974:1: error: the frame size of 344 bytes is larger
than 300 bytes [-Werror=frame-larger-than=]
fs/ocfs2/super.c: In function 'ocfs2_fill_super':
fs/ocfs2/super.c:1219:1: error: the frame size of 552 bytes is larger
than 300 bytes [-Werror=frame-larger-than=]

after:
fs/ocfs2/super.c: In function 'ocfs2_fill_super':
fs/ocfs2/super.c:1219:1: error: the frame size of 472 bytes is larger
than 300 bytes [-Werror=frame-larger-than=]

and with gcc-7.0.1 (including -fsanitize-address-use-after-scope), before:
fs/ocfs2/super.c: In function 'ocfs2_check_volume':
fs/ocfs2/super.c:2512:1: error: the frame size of 768 bytes is larger
than 300 bytes [-Werror=frame-larger-than=]
fs/ocfs2/super.c: In function 'ocfs2_statfs':
fs/ocfs2/super.c:1717:1: error: the frame size of 320 bytes is larger
than 300 bytes [-Werror=frame-larger-than=]
fs/ocfs2/super.c: In function 'ocfs2_parse_options.isra.3':
fs/ocfs2/super.c:1508:1: error: the frame size of 464 bytes is larger
than 300 bytes [-Werror=frame-larger-than=]
fs/ocfs2/super.c: In function 'ocfs2_enable_quotas':
fs/ocfs2/super.c:974:1: error: the frame size of 320 bytes is larger
than 300 bytes [-Werror=frame-larger-than=]
fs/ocfs2/super.c: In function 'ocfs2_remount':
fs/ocfs2/super.c:752:1: error: the frame size of 568 bytes is larger
than 300 bytes [-Werror=frame-larger-than=]
fs/ocfs2/super.c: In function 'ocfs2_initialize_super.isra.8':
fs/ocfs2/super.c:2339:1: error: the frame size of 1712 bytes is larger
than 300 bytes [-Werror=frame-larger-than=]
fs/ocfs2/super.c: In function 'ocfs2_fill_super':
fs/ocfs2/super.c:1219:1: error: the frame size of 3264 bytes is larger
than 300 bytes [-Werror=frame-larger-than=]

after:
fs/ocfs2/super.c: In function 'ocfs2_fill_super':
fs/ocfs2/super.c:1219:1: error: the frame size of 704 bytes is larger
than 300 bytes [-Werror=frame-larger-than=]

     Arnd

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 24/26] ocfs2: reduce stack size with KASAN
  2017-03-02 22:22     ` Arnd Bergmann
@ 2017-03-02 22:40       ` Joe Perches
  2017-03-02 22:59         ` Arnd Bergmann
  0 siblings, 1 reply; 67+ messages in thread
From: Joe Perches @ 2017-03-02 22:40 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: kasan-dev, Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
	Networking, Linux Kernel Mailing List, linux-media,
	linux-wireless, kernel-build-reports, David S . Miller

On Thu, 2017-03-02 at 23:22 +0100, Arnd Bergmann wrote:
> On Thu, Mar 2, 2017 at 6:46 PM, Joe Perches <joe@perches.com> wrote:
> > On Thu, 2017-03-02 at 17:38 +0100, Arnd Bergmann wrote:
> > > The internal logging infrastructure in ocfs2 causes special warning code to be
> > > used with KASAN, which produces rather large stack frames:
> > > fs/ocfs2/super.c: In function 'ocfs2_fill_super':
> > > fs/ocfs2/super.c:1219:1: error: the frame size of 3264 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
> > 
> > At least by default it doesn't seem to.
> > 
> > gcc 6.2 allyesconfig, CONFIG_KASAN=y
> > with either CONFIG_KASAN_INLINE or CONFIG_KASAN_OUTLINE
> > 
> > gcc doesn't emit a stack warning
> 
> The warning is disabled until patch 26/26. which picks the 3072 default.
> The 3264 number was with gcc-7, which is worse than gcc-6 since it enables
> an extra check.
> 
> > > By simply passing the mask by value instead of reference, we can avoid the
> > > problem completely.
> > 
> > Any idea why that's so?
> 
> With KASAN, every time we inline the function, the compiler has to allocate
> space for another copy of the variable plus a redzone to detect whether
> passing it by reference into another function causes an overflow at runtime.

These logging functions aren't inlined.
You're referring to the stack frame?

> > >  On 64-bit architectures, this is also more efficient,
> > 
> > Efficient true, but the same overall stack no?
> 
> Here is what I see with CONFIG_FRAME_WARN=300 and x86_64-linux-gcc-6.3.1:
> 
> before:
[]
> fs/ocfs2/super.c:1219:1: error: the frame size of 552 bytes is larger
> than 300 bytes [-Werror=frame-larger-than=]
> 
> after:
> fs/ocfs2/super.c: In function 'ocfs2_fill_super':
> fs/ocfs2/super.c:1219:1: error: the frame size of 472 bytes is larger
> than 300 bytes [-Werror=frame-larger-than=]
> 
> and with gcc-7.0.1 (including -fsanitize-address-use-after-scope), before:
[]
> fs/ocfs2/super.c:1219:1: error: the frame size of 3264 bytes is larger
> than 300 bytes [-Werror=frame-larger-than=]
> 
> after:
> fs/ocfs2/super.c: In function 'ocfs2_fill_super':
> fs/ocfs2/super.c:1219:1: error: the frame size of 704 bytes is larger
> than 300 bytes [-Werror=frame-larger-than=]

Still doesn't make sense to me.

None of the logging functions are inlined as they are all
EXPORT_SYMBOL.

This just changes a pointer to a u64, which is the same
size on x86-64 (and is of course larger on x86-32).

Perhaps KASAN has the odd behavior and working around
KASAN's behavior may not be the proper thing to do.

Maybe if CONFIG_KASAN is set, the minimum stack should
be increased via THREAD_SIZE_ORDER or some such.

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 24/26] ocfs2: reduce stack size with KASAN
  2017-03-02 22:40       ` Joe Perches
@ 2017-03-02 22:59         ` Arnd Bergmann
  2017-03-02 23:58           ` Joe Perches
  0 siblings, 1 reply; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-02 22:59 UTC (permalink / raw)
  To: Joe Perches
  Cc: kasan-dev, Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
	Networking, Linux Kernel Mailing List, linux-media,
	linux-wireless, kernel-build-reports, David S . Miller

On Thu, Mar 2, 2017 at 11:40 PM, Joe Perches <joe@perches.com> wrote:
> On Thu, 2017-03-02 at 23:22 +0100, Arnd Bergmann wrote:
>> On Thu, Mar 2, 2017 at 6:46 PM, Joe Perches <joe@perches.com> wrote:
>> > On Thu, 2017-03-02 at 17:38 +0100, Arnd Bergmann wrote:
>> > > The internal logging infrastructure in ocfs2 causes special warning code to be
>> > > used with KASAN, which produces rather large stack frames:
>> > > fs/ocfs2/super.c: In function 'ocfs2_fill_super':
>> > > fs/ocfs2/super.c:1219:1: error: the frame size of 3264 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
>> >
>> > At least by default it doesn't seem to.
>> >
>> > gcc 6.2 allyesconfig, CONFIG_KASAN=y
>> > with either CONFIG_KASAN_INLINE or CONFIG_KASAN_OUTLINE
>> >
>> > gcc doesn't emit a stack warning
>>
>> The warning is disabled until patch 26/26. which picks the 3072 default.
>> The 3264 number was with gcc-7, which is worse than gcc-6 since it enables
>> an extra check.
>>
>> > > By simply passing the mask by value instead of reference, we can avoid the
>> > > problem completely.
>> >
>> > Any idea why that's so?
>>
>> With KASAN, every time we inline the function, the compiler has to allocate
>> space for another copy of the variable plus a redzone to detect whether
>> passing it by reference into another function causes an overflow at runtime.
>
> These logging functions aren't inlined.

Sorry, my mistake. In this case mlog() is a macro, not an inline functions.
The effect is the same though.

> You're referring to the stack frame?

The stack frame of the function that calls mlog(), yes.
>
> Still doesn't make sense to me.
>
> None of the logging functions are inlined as they are all
> EXPORT_SYMBOL.

mlog() is placed in the calling function.

> This just changes a pointer to a u64, which is the same
> size on x86-64 (and is of course larger on x86-32).

KASAN decides that passing a pointer to _m into an extern function
(_mlog_printk) is potentially dangerous, as that function might
keep a reference to that pointer after it goes out of scope,
or it might not know the correct length of the stack object pointed to.

We can see from looking at the __mlog_printk() function definition
that it's actually safe, but the compiler cannot see that when looking
at another source file.

> Perhaps KASAN has the odd behavior and working around
> KASAN's behavior may not be the proper thing to do.

Turning off KASAN fixes the problem, but the entire purpose of
KASAN is to identify code that is potentially dangerous.

> Maybe if CONFIG_KASAN is set, the minimum stack should
> be increased via THREAD_SIZE_ORDER or some such.

This is what happened in 3f181b4d8652 ("lib/Kconfig.debug:
disable -Wframe-larger-than warnings with KASAN=y").

I'm trying to revert that patch so we actually get warnings
again about functions that are still dangerous. I picked 3072
as an arbitrary limit, as there are only a handful of files
that use larger stack frames in the worst case, but we can
only use that limit after fixing up all the warnings it shows.

       Arnd

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 24/26] ocfs2: reduce stack size with KASAN
  2017-03-02 22:59         ` Arnd Bergmann
@ 2017-03-02 23:58           ` Joe Perches
  0 siblings, 0 replies; 67+ messages in thread
From: Joe Perches @ 2017-03-02 23:58 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: kasan-dev, Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
	Networking, Linux Kernel Mailing List, linux-media,
	linux-wireless, kernel-build-reports, David S . Miller

On Thu, 2017-03-02 at 23:59 +0100, Arnd Bergmann wrote:
> KASAN decides that passing a pointer to _m into an extern function
> (_mlog_printk) is potentially dangerous, as that function might
> keep a reference to that pointer after it goes out of scope,
> or it might not know the correct length of the stack object pointed to.
> 
> We can see from looking at the __mlog_printk() function definition
> that it's actually safe, but the compiler cannot see that when looking
> at another source file.

OK, thanks.

btw:

changing __mlog_printk can save ~11% (90+KB) of object text size
by removing __func__ and __LINE__ and using vsprintf pointer extension
%pS, __builtin_return_address(0) as it is already used in dlmmaster.

(defconfig x86-64, with ocfs2)

$ size fs/ocfs2/built-in.o*
   text	   data	    bss	    dec	    hex	filename
 759791	 111373	 105688	 976852	  ee7d4	fs/ocfs2/built-in.o.new
 852959	 111373	 105688	1070020	 1053c4	fs/ocfs2/built-in.o.old

It's nearly the same output.

---

 fs/ocfs2/cluster/masklog.c | 8 ++++----
 fs/ocfs2/cluster/masklog.h | 8 +++-----
 2 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/fs/ocfs2/cluster/masklog.c b/fs/ocfs2/cluster/masklog.c
index d331c2386b94..a3f080f37108 100644
--- a/fs/ocfs2/cluster/masklog.c
+++ b/fs/ocfs2/cluster/masklog.c
@@ -64,8 +64,7 @@ static ssize_t mlog_mask_store(u64 mask, const char *buf, size_t count)
 	return count;
 }
 
-void __mlog_printk(const u64 *mask, const char *func, int line,
-		   const char *fmt, ...)
+void __mlog_printk(const u64 *mask, const char *fmt, ...)
 {
 	struct va_format vaf;
 	va_list args;
@@ -90,9 +89,10 @@ void __mlog_printk(const u64 *mask, const char *func, int line,
 	vaf.fmt = fmt;
 	vaf.va = &args;
 
-	printk("%s(%s,%u,%u):%s:%d %s%pV",
+	printk("%s(%s,%u,%u):%pS %s%pV",
 	       level, current->comm, task_pid_nr(current),
-	       raw_smp_processor_id(), func, line, prefix, &vaf);
+	       raw_smp_processor_id(), __builtin_return_address(0),
+	       prefix, &vaf);
 
 	va_end(args);
 }
diff --git a/fs/ocfs2/cluster/masklog.h b/fs/ocfs2/cluster/masklog.h
index 3c16da69605d..56ba5baf625b 100644
--- a/fs/ocfs2/cluster/masklog.h
+++ b/fs/ocfs2/cluster/masklog.h
@@ -162,9 +162,8 @@ extern struct mlog_bits mlog_and_bits, mlog_not_bits;
 
 #endif
 
-__printf(4, 5) __nocapture(2)
-void __mlog_printk(const u64 *m, const char *func, int line,
-		   const char *fmt, ...);
+__printf(2, 3) __nocapture(2)
+void __mlog_printk(const u64 *m, const char *fmt, ...);
 
 /*
  * Testing before the __mlog_printk call lets the compiler eliminate the
@@ -174,8 +173,7 @@ void __mlog_printk(const u64 *m, const char *func, int line,
 do {									\
 	u64 _m = MLOG_MASK_PREFIX | (mask);				\
 	if (_m & ML_ALLOWED_BITS)					\
-		__mlog_printk(&_m, __func__, __LINE__, fmt,		\
-			      ##__VA_ARGS__);				\
+		__mlog_printk(&_m, fmt, ##__VA_ARGS__);			\
 } while (0)
 
 #define mlog_errno(st) ({						\

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* Re: [PATCH 02/26] rewrite READ_ONCE/WRITE_ONCE
  2017-03-02 21:45         ` Arnd Bergmann
@ 2017-03-03  8:26           ` Christian Borntraeger
  2017-03-03  9:54             ` Arnd Bergmann
  2017-03-03 14:49             ` Peter Zijlstra
  0 siblings, 2 replies; 67+ messages in thread
From: Christian Borntraeger @ 2017-03-03  8:26 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: kasan-dev, Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
	Networking, Linux Kernel Mailing List, linux-media,
	linux-wireless, kernel-build-reports, David S . Miller,
	Paul McKenney

On 03/02/2017 10:45 PM, Arnd Bergmann wrote:
> On Thu, Mar 2, 2017 at 8:00 PM, Christian Borntraeger
> <borntraeger@de.ibm.com> wrote:
>> On 03/02/2017 06:55 PM, Arnd Bergmann wrote:
>>> On Thu, Mar 2, 2017 at 5:51 PM, Christian Borntraeger
>>> <borntraeger@de.ibm.com> wrote:
>>>> On 03/02/2017 05:38 PM, Arnd Bergmann wrote:
>>>>>
>>>>> This attempts a rewrite of the two macros, using a simpler implementation
>>>>> for the most common case of having a naturally aligned 1, 2, 4, or (on
>>>>> 64-bit architectures) 8  byte object that can be accessed with a single
>>>>> instruction.  For these, we go back to a volatile pointer dereference
>>>>> that we had with the ACCESS_ONCE macro.
>>>>
>>>> We had changed that back then because gcc 4.6 and 4.7 had a bug that could
>>>> removed the volatile statement on aggregate types like the following one
>>>>
>>>> union ipte_control {
>>>>         unsigned long val;
>>>>         struct {
>>>>                 unsigned long k  : 1;
>>>>                 unsigned long kh : 31;
>>>>                 unsigned long kg : 32;
>>>>         };
>>>> };
>>>>
>>>> See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145
>>>>
>>>> If I see that right, your __ALIGNED_WORD(x)
>>>> macro would say that for above structure  sizeof(x) == sizeof(long)) is true,
>>>> so it would fall back to the old volatile cast and might reintroduce the
>>>> old compiler bug?
>>
>> Oh dear, I should double check my sentences in emails before sending...anyway
>> the full story is referenced in
>>
>> commit 60815cf2e05057db5b78e398d9734c493560b11e
>>     Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/borntraeger/linux
>> which has a pointer to
>> http://marc.info/?i=54611D86.4040306%40de.ibm.com
>> which contains the full story.
> 
> Ok, got it. So I guess the behavior of forcing aligned accesses on aligned
> data is accidental, and allowing non-power-of-two arguments is also not
> the main purpose.


Right. The main purpose is to read/write _ONCE_. You can assume a somewhat
atomic access for sizes <= word size. And there are certainly places that
rely on that. But the *ONCE thing is mostly used for things where we used
barrier() 10 years ago.


 Maybe we could just bail out on new compilers if we get
> either of those? That might catch code that accidentally does something
> that is inherently non-atomic or that causes a trap when the intention was
> to have a simple atomic access.

I think Linus stated that its ok to assume that the compiler is smart enough 
to uses a single instruction to access aligned and properly sized scalar types
for *ONCE.

Back then when I changed ACCESS_ONCE there were many places that did use it
for non-atomic, > word size accesses. For example on some architectures a pmd_t
is a typedef to an array, for which there is no way to read that atomically.
So the focus must be on the "ONCE" part.

If some code uses a properly aligned, word sized object we can also assume 
atomic access. If the access is not properly sized/aligned we do not get
atomicity, but we do get the "ONCE".
But adding a check for alignment/size would break the compilation of some
code.

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 02/26] rewrite READ_ONCE/WRITE_ONCE
  2017-03-03  8:26           ` Christian Borntraeger
@ 2017-03-03  9:54             ` Arnd Bergmann
  2017-03-03 14:49             ` Peter Zijlstra
  1 sibling, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-03  9:54 UTC (permalink / raw)
  To: Christian Borntraeger
  Cc: kasan-dev, Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
	Networking, Linux Kernel Mailing List, linux-media,
	linux-wireless, kernel-build-reports, David S . Miller,
	Paul McKenney

On Fri, Mar 3, 2017 at 9:26 AM, Christian Borntraeger
<borntraeger@de.ibm.com> wrote:
> On 03/02/2017 10:45 PM, Arnd Bergmann wrote:
>> Ok, got it. So I guess the behavior of forcing aligned accesses on aligned
>> data is accidental, and allowing non-power-of-two arguments is also not
>> the main purpose.
>
>
> Right. The main purpose is to read/write _ONCE_. You can assume a somewhat
> atomic access for sizes <= word size. And there are certainly places that
> rely on that. But the *ONCE thing is mostly used for things where we used
> barrier() 10 years ago.

Ok

>
>  Maybe we could just bail out on new compilers if we get
>> either of those? That might catch code that accidentally does something
>> that is inherently non-atomic or that causes a trap when the intention was
>> to have a simple atomic access.
>
> I think Linus stated that its ok to assume that the compiler is smart enough
> to uses a single instruction to access aligned and properly sized scalar types
> for *ONCE.
>
> Back then when I changed ACCESS_ONCE there were many places that did use it
> for non-atomic, > word size accesses. For example on some architectures a pmd_t
> is a typedef to an array, for which there is no way to read that atomically.
> So the focus must be on the "ONCE" part.
>
> If some code uses a properly aligned, word sized object we can also assume
> atomic access. If the access is not properly sized/aligned we do not get
> atomicity, but we do get the "ONCE".
> But adding a check for alignment/size would break the compilation of some
> code.

So what should be the expected behavior for objects that have a smaller
alignment? E.g. this structure

struct fourbytes {
   char bytes[4];
} __packed;

when passed into the current READ_ONCE() will be accessed with
a 32-bit load, while reading it with

struct fourbytes local = *(volatile struct fourbytes *)voidpointer;

on architectures like ARMv5 or lower will turn into four single-byte
reads to avoid an alignment trap when the pointer is actually
unaligned.

I can see arguments for and against either behavior, but what should
I do when modifying it for newer compilers? The possible options
that I see are

- keep assuming that the pointer will be aligned at runtime
  and doesn't trap
- use the regular gcc behavior and do byte-accesses on those
  architectures that otherwise might trap
- add a runtime alignment check to do atomic accesses whenever
  possible, but never trap
- fail the build

     Arnd

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 00/26] bring back stack frame warning with KASAN
  2017-03-02 16:38 [PATCH 00/26] bring back stack frame warning with KASAN Arnd Bergmann
                   ` (25 preceding siblings ...)
  2017-03-02 16:38 ` [PATCH 26/26] kasan: rework Kconfig settings Arnd Bergmann
@ 2017-03-03 12:25 ` Alexander Potapenko
  2017-03-03 12:54   ` Arnd Bergmann
  26 siblings, 1 reply; 67+ messages in thread
From: Alexander Potapenko @ 2017-03-03 12:25 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: kasan-dev, Andrey Ryabinin, Dmitry Vyukov, netdev, LKML,
	linux-media, linux-wireless, kernel-build-reports,
	David S . Miller

On Thu, Mar 2, 2017 at 5:38 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> It took a long while to get this done, but I'm finally ready
> to send the first half of the KASAN stack size patches that
> I did in response to the kernelci.org warnings.
>
> As before, it's worth mentioning that things are generally worse
> with gcc-7.0.1 because of the addition of -fsanitize-address-use-after-scope
> that are not present on kernelci, so my randconfig testing found
> a lot more than kernelci did.
>
> The main areas are:
>
> - READ_ONCE/WRITE_ONCE cause problems in lots of code
> - typecheck() causes huge problems in a few places
> - I'm introducing "noinline_for_kasan" and use it in a lot
>   of places that suffer from inline functions with local variables
>   - netlink, as used in various parts of the kernel
>   - a number of drivers/media drivers
>   - a handful of wireless network drivers
> - kmemcheck conflicts with -fsanitize-address-use-after-scope
>
> This series lets us add back a stack frame warning for 3072 bytes
> with -fsanitize-address-use-after-scope, or 2048 bytes without it.
>
> I have a follow-up series that further reduces the stack frame
> warning limit to 1280 bytes for all 64-bit architectures, and
> 1536 bytes with basic KASAN support (no -fsanitize-address-use-after-scope).
> For now, I'm only posting the first half, in order to keep
> it (barely) reviewable.
Can you please elaborate on why do you need this? Are you trying to
squeeze KASAN into some embedded device?
Noinlines sprayed over the codebase are hard to maintain, and certain
compiler changes may cause bloated stack frames in other places.
Maybe it should be enough to just increase the stack frame limit in
KASAN builds, as Dmitry suggested previously?
> Both series are tested with many hundred randconfig builds on both
> x86 and arm64, which are the only architectures supporting KASAN.
>
>         Arnd
>
>  [PATCH 01/26] compiler: introduce noinline_for_kasan annotation
>  [PATCH 02/26] rewrite READ_ONCE/WRITE_ONCE
>  [PATCH 03/26] typecheck.h: avoid local variables in typecheck() macro
>  [PATCH 04/26] tty: kbd: reduce stack size with KASAN
>  [PATCH 05/26] netlink: mark nla_put_{u8,u16,u32} noinline_for_kasan
>  [PATCH 06/26] rocker: mark rocker_tlv_put_* functions as
>  [PATCH 07/26] brcmsmac: reduce stack size with KASAN
>  [PATCH 08/26] brcmsmac: make some local variables 'static const' to
>  [PATCH 09/26] brcmsmac: split up wlc_phy_workarounds_nphy
>  [PATCH 10/26] brcmsmac: reindent split functions
>  [PATCH 11/26] rtlwifi: reduce stack usage for KASAN
>  [PATCH 12/26] wl3501_cs: reduce stack size for KASAN
>  [PATCH 13/26] rtl8180: reduce stack size for KASAN
>  [PATCH 14/26] [media] dvb-frontends: reduce stack size in i2c access
>  [PATCH 15/26] [media] tuners: i2c: reduce stack usage for
>  [PATCH 16/26] [media] i2c: adv7604: mark register access as
>  [PATCH 17/26] [media] i2c: ks0127: reduce stack frame size for KASAN
>  [PATCH 18/26] [media] i2c: cx25840: avoid stack overflow with KASAN
>  [PATCH 19/26] [media] r820t: mark register functions as
>  [PATCH 20/26] [media] em28xx: split up em28xx_dvb_init to reduce
>  [PATCH 21/26] drm/bridge: ps8622: reduce stack size for KASAN
>  [PATCH 22/26] drm/i915/gvt: don't overflow the kernel stack with
>  [PATCH 23/26] mtd: cfi: reduce stack size with KASAN
>  [PATCH 24/26] ocfs2: reduce stack size with KASAN
>  [PATCH 25/26] isdn: eicon: mark divascapi incompatible with kasan
>  [PATCH 26/26] kasan: rework Kconfig settings
>
>  arch/x86/include/asm/switch_to.h                                 |    2 +-
>  drivers/gpu/drm/bridge/parade-ps8622.c                           |    2 +-
>  drivers/gpu/drm/i915/gvt/mmio.h                                  |   17 +-
>  drivers/isdn/hardware/eicon/Kconfig                              |    1 +
>  drivers/media/dvb-frontends/ascot2e.c                            |    3 +-
>  drivers/media/dvb-frontends/cxd2841er.c                          |    4 +-
>  drivers/media/dvb-frontends/drx39xyj/drxj.c                      |   14 +-
>  drivers/media/dvb-frontends/helene.c                             |    4 +-
>  drivers/media/dvb-frontends/horus3a.c                            |    2 +-
>  drivers/media/dvb-frontends/itd1000.c                            |    2 +-
>  drivers/media/dvb-frontends/mt312.c                              |    2 +-
>  drivers/media/dvb-frontends/si2165.c                             |   14 +-
>  drivers/media/dvb-frontends/stb0899_drv.c                        |    2 +-
>  drivers/media/dvb-frontends/stb6100.c                            |    2 +-
>  drivers/media/dvb-frontends/stv0367.c                            |    2 +-
>  drivers/media/dvb-frontends/stv090x.c                            |    2 +-
>  drivers/media/dvb-frontends/stv6110.c                            |    2 +-
>  drivers/media/dvb-frontends/stv6110x.c                           |    2 +-
>  drivers/media/dvb-frontends/tda8083.c                            |    2 +-
>  drivers/media/dvb-frontends/zl10039.c                            |    2 +-
>  drivers/media/i2c/adv7604.c                                      |    4 +-
>  drivers/media/i2c/cx25840/cx25840-core.c                         |    4 +-
>  drivers/media/i2c/ks0127.c                                       |    2 +-
>  drivers/media/tuners/r820t.c                                     |    4 +-
>  drivers/media/tuners/tuner-i2c.h                                 |   15 +-
>  drivers/media/usb/em28xx/em28xx-dvb.c                            |  947 +++++++++++++++++++++------------------
>  drivers/mtd/chips/cfi_cmdset_0020.c                              |    8 +-
>  drivers/net/ethernet/rocker/rocker_tlv.h                         |   24 +-
>  drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c     | 1860 +++++++++++++++++++++++++++++++++++++----------------------------------------
>  drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225se.c         |    4 +-
>  drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8192e2ant.c |   41 +-
>  drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c |   26 +-
>  drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.c |   34 +-
>  drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c |   36 +-
>  drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a2ant.c |   38 +-
>  drivers/net/wireless/wl3501_cs.c                                 |   10 +-
>  drivers/tty/vt/keyboard.c                                        |    6 +-
>  fs/ocfs2/cluster/masklog.c                                       |   10 +-
>  fs/ocfs2/cluster/masklog.h                                       |    4 +-
>  fs/overlayfs/util.c                                              |    6 +-
>  include/linux/compiler.h                                         |   58 ++-
>  include/linux/mtd/map.h                                          |    8 +-
>  include/linux/typecheck.h                                        |    7 +-
>  include/net/netlink.h                                            |   36 +-
>  lib/Kconfig.debug                                                |    9 +-
>  lib/Kconfig.kasan                                                |   11 +-
>  lib/Kconfig.kmemcheck                                            |    1 +
>  scripts/Makefile.kasan                                           |    3 +
>  48 files changed, 1670 insertions(+), 1629 deletions(-)
>



-- 
Alexander Potapenko
Software Engineer

Google Germany GmbH
Erika-Mann-Straße, 33
80636 München

Geschäftsführer: Matthew Scott Sucherman, Paul Terence Manicle
Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 00/26] bring back stack frame warning with KASAN
  2017-03-03 12:25 ` [PATCH 00/26] bring back stack frame warning with KASAN Alexander Potapenko
@ 2017-03-03 12:54   ` Arnd Bergmann
  0 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-03 12:54 UTC (permalink / raw)
  To: Alexander Potapenko
  Cc: kasan-dev, Andrey Ryabinin, Dmitry Vyukov, Networking, LKML,
	linux-media, linux-wireless, kernel-build-reports,
	David S . Miller

On Fri, Mar 3, 2017 at 1:25 PM, Alexander Potapenko <glider@google.com> wrote:
> On Thu, Mar 2, 2017 at 5:38 PM, Arnd Bergmann <arnd@arndb.de> wrote:
>> It took a long while to get this done, but I'm finally ready
>> to send the first half of the KASAN stack size patches that
>> I did in response to the kernelci.org warnings.
>>
>> As before, it's worth mentioning that things are generally worse
>> with gcc-7.0.1 because of the addition of -fsanitize-address-use-after-scope
>> that are not present on kernelci, so my randconfig testing found
>> a lot more than kernelci did.
>>
>> The main areas are:
>>
>> - READ_ONCE/WRITE_ONCE cause problems in lots of code
>> - typecheck() causes huge problems in a few places
>> - I'm introducing "noinline_for_kasan" and use it in a lot
>>   of places that suffer from inline functions with local variables
>>   - netlink, as used in various parts of the kernel
>>   - a number of drivers/media drivers
>>   - a handful of wireless network drivers
>> - kmemcheck conflicts with -fsanitize-address-use-after-scope
>>
>> This series lets us add back a stack frame warning for 3072 bytes
>> with -fsanitize-address-use-after-scope, or 2048 bytes without it.
>>
>> I have a follow-up series that further reduces the stack frame
>> warning limit to 1280 bytes for all 64-bit architectures, and
>> 1536 bytes with basic KASAN support (no -fsanitize-address-use-after-scope).
>> For now, I'm only posting the first half, in order to keep
>> it (barely) reviewable.
>
> Can you please elaborate on why do you need this? Are you trying to
> squeeze KASAN into some embedded device?
> Noinlines sprayed over the codebase are hard to maintain, and certain
> compiler changes may cause bloated stack frames in other places.
> Maybe it should be enough to just increase the stack frame limit in
> KASAN builds, as Dmitry suggested previously?

The current state of mainline has doubled the kernel stack size with
KASAN, and completely turned off the warning for per-function
stack frames. In some cases, this is completely broken as we have
functions that exceed even the 32kb per-thread stacks by themselves,
so I want to turn on the warning again and fix all the outliers.

The hard part is deciding what size is reasonable for a given function,
as smaller limits cause more harmless warnings while larger limits
can hide more actual problems. Before running into the KASAN
problem, I had already determined that we can lower the warning
limit for 64-bit architectures from 2048 bytes to 1280 with just
a handful of patches that are generally a good cleanup anyway.

This led me to picking three separate warning limits, based on
what I found reasonable to work around in the code:

3072 bytes with -fsanitize-address-use-after-scope
1536 bytes with KASAN but without -fsanitize-address-use-after-scope
1280 bytes on 64-bit without KASAN
1024 bytes on 32-bit architectures

If we use higher limits, the patch series will get a bit shorter. For
the limits above, I needed a total of 51 patches, while this shorter
series of 26 patches has slightly laxer limits:

3072 bytes with -fsanitize-address-use-after-scope
2048 bytes on 64-bit architectures with or without KASAN, but
          without  -fsanitize-address-use-after-scope
1024 bytes on 32-bit architectures

The individual patches should list the highest frame size I ran
into, so I can try to reduce the number of patches if you have
a suggestion for a different set of limits.

       Arnd

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 01/26] compiler: introduce noinline_for_kasan annotation
  2017-03-02 16:38 ` [PATCH 01/26] compiler: introduce noinline_for_kasan annotation Arnd Bergmann
@ 2017-03-03 13:50   ` Andrey Ryabinin
  2017-03-03 13:55     ` Alexander Potapenko
  2017-03-03 16:34     ` David Laight
  0 siblings, 2 replies; 67+ messages in thread
From: Andrey Ryabinin @ 2017-03-03 13:50 UTC (permalink / raw)
  To: Arnd Bergmann, kasan-dev
  Cc: Alexander Potapenko, Dmitry Vyukov, netdev, linux-kernel,
	linux-media, linux-wireless, kernel-build-reports,
	David S . Miller



On 03/02/2017 07:38 PM, Arnd Bergmann wrote:
> When CONFIG_KASAN is set, we can run into some code that uses incredible
> amounts of kernel stack:
> 
> drivers/staging/dgnc/dgnc_neo.c:1056:1: error: the frame size of 11112 bytes is larger than 2048 bytes [-Werror=frame-larger-than=]
> drivers/media/i2c/cx25840/cx25840-core.c:4960:1: error: the frame size of 94000 bytes is larger than 2048 bytes [-Werror=frame-larger-than=]
> drivers/media/dvb-frontends/stv090x.c:3430:1: error: the frame size of 5312 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
> 
> This happens when a sanitizer uses stack memory each time an inline function
> gets called. This introduces a new annotation for those functions to make
> them either 'inline' or 'noinline' dependning on the CONFIG_KASAN symbol.
> 
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
>  include/linux/compiler.h | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/include/linux/compiler.h b/include/linux/compiler.h
> index f8110051188f..56b90897a459 100644
> --- a/include/linux/compiler.h
> +++ b/include/linux/compiler.h
> @@ -416,6 +416,17 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
>   */
>  #define noinline_for_stack noinline
>  
> +/*
> + * CONFIG_KASAN can lead to extreme stack usage with certain patterns when
> + * one function gets inlined many times and each instance requires a stack
> + * ckeck.
> + */
> +#ifdef CONFIG_KASAN
> +#define noinline_for_kasan noinline __maybe_unused


noinline_iff_kasan might be a better name.  noinline_for_kasan gives the impression
that we always noinline function for the sake of kasan, while noinline_iff_kasan
clearly indicates that function is noinline only if kasan is used.

> +#else
> +#define noinline_for_kasan inline
> +#endif
> +
>  #ifndef __always_inline
>  #define __always_inline inline
>  #endif
> 

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 01/26] compiler: introduce noinline_for_kasan annotation
  2017-03-03 13:50   ` Andrey Ryabinin
@ 2017-03-03 13:55     ` Alexander Potapenko
  2017-03-03 14:30       ` Arnd Bergmann
  2017-03-03 16:34     ` David Laight
  1 sibling, 1 reply; 67+ messages in thread
From: Alexander Potapenko @ 2017-03-03 13:55 UTC (permalink / raw)
  To: Andrey Ryabinin
  Cc: Arnd Bergmann, kasan-dev, Dmitry Vyukov, netdev, LKML,
	linux-media, linux-wireless, kernel-build-reports,
	David S . Miller

On Fri, Mar 3, 2017 at 2:50 PM, Andrey Ryabinin <aryabinin@virtuozzo.com> wrote:
>
>
> On 03/02/2017 07:38 PM, Arnd Bergmann wrote:
>> When CONFIG_KASAN is set, we can run into some code that uses incredible
>> amounts of kernel stack:
>>
>> drivers/staging/dgnc/dgnc_neo.c:1056:1: error: the frame size of 11112 bytes is larger than 2048 bytes [-Werror=frame-larger-than=]
>> drivers/media/i2c/cx25840/cx25840-core.c:4960:1: error: the frame size of 94000 bytes is larger than 2048 bytes [-Werror=frame-larger-than=]
>> drivers/media/dvb-frontends/stv090x.c:3430:1: error: the frame size of 5312 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
>>
>> This happens when a sanitizer uses stack memory each time an inline function
>> gets called. This introduces a new annotation for those functions to make
>> them either 'inline' or 'noinline' dependning on the CONFIG_KASAN symbol.
>>
>> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
>> ---
>>  include/linux/compiler.h | 11 +++++++++++
>>  1 file changed, 11 insertions(+)
>>
>> diff --git a/include/linux/compiler.h b/include/linux/compiler.h
>> index f8110051188f..56b90897a459 100644
>> --- a/include/linux/compiler.h
>> +++ b/include/linux/compiler.h
>> @@ -416,6 +416,17 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
>>   */
>>  #define noinline_for_stack noinline
>>
>> +/*
>> + * CONFIG_KASAN can lead to extreme stack usage with certain patterns when
>> + * one function gets inlined many times and each instance requires a stack
>> + * ckeck.
>> + */
>> +#ifdef CONFIG_KASAN
>> +#define noinline_for_kasan noinline __maybe_unused
>
>
> noinline_iff_kasan might be a better name.  noinline_for_kasan gives the impression
> that we always noinline function for the sake of kasan, while noinline_iff_kasan
> clearly indicates that function is noinline only if kasan is used.
FWIW we may be facing the same problem with other compiler-based
tools, e.g. KMSAN (which isn't there yet).
So it might be better to choose a macro name that doesn't use the name "KASAN".
E.g. noinline_iff_memtool (or noinline_iff_memory_tool if that's not too long).
WDYT?
>> +#else
>> +#define noinline_for_kasan inline
>> +#endif
>> +
>>  #ifndef __always_inline
>>  #define __always_inline inline
>>  #endif
>>
>
> --
> You received this message because you are subscribed to the Google Groups "kasan-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to kasan-dev+unsubscribe@googlegroups.com.
> To post to this group, send email to kasan-dev@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/kasan-dev/7e7a62de-3b79-6044-72fa-4ade418953d1%40virtuozzo.com.
> For more options, visit https://groups.google.com/d/optout.



-- 
Alexander Potapenko
Software Engineer

Google Germany GmbH
Erika-Mann-Straße, 33
80636 München

Geschäftsführer: Matthew Scott Sucherman, Paul Terence Manicle
Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 25/26] isdn: eicon: mark divascapi incompatible with kasan
  2017-03-02 16:38 ` [PATCH 25/26] isdn: eicon: mark divascapi incompatible with kasan Arnd Bergmann
@ 2017-03-03 14:20   ` Andrey Ryabinin
  2017-03-03 14:54     ` Arnd Bergmann
  0 siblings, 1 reply; 67+ messages in thread
From: Andrey Ryabinin @ 2017-03-03 14:20 UTC (permalink / raw)
  To: Arnd Bergmann, kasan-dev
  Cc: Alexander Potapenko, Dmitry Vyukov, netdev, linux-kernel,
	linux-media, linux-wireless, kernel-build-reports,
	David S . Miller



On 03/02/2017 07:38 PM, Arnd Bergmann wrote:
> When CONFIG_KASAN is enabled, we have several functions that use rather
> large kernel stacks, e.g.
> 
> drivers/isdn/hardware/eicon/message.c: In function 'group_optimization':
> drivers/isdn/hardware/eicon/message.c:14841:1: warning: the frame size of 864 bytes is larger than 500 bytes [-Wframe-larger-than=]
> drivers/isdn/hardware/eicon/message.c: In function 'add_b1':
> drivers/isdn/hardware/eicon/message.c:7925:1: warning: the frame size of 1008 bytes is larger than 500 bytes [-Wframe-larger-than=]
> drivers/isdn/hardware/eicon/message.c: In function 'add_b23':
> drivers/isdn/hardware/eicon/message.c:8551:1: warning: the frame size of 928 bytes is larger than 500 bytes [-Wframe-larger-than=]
> drivers/isdn/hardware/eicon/message.c: In function 'sig_ind':
> drivers/isdn/hardware/eicon/message.c:6113:1: warning: the frame size of 2112 bytes is larger than 500 bytes [-Wframe-larger-than=]
> 
> To be on the safe side, and to enable a lower frame size warning limit, let's
> just mark this driver as broken when KASAN is in use. I have tried to reduce
> the stack size as I did with dozens of other drivers, but failed to come up
> with a good solution for this one.
> 

This is kinda radical solution.
Wouldn't be better to just increase -Wframe-larger-than for this driver through Makefile?



> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
>  drivers/isdn/hardware/eicon/Kconfig | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/isdn/hardware/eicon/Kconfig b/drivers/isdn/hardware/eicon/Kconfig
> index 6082b6a5ced3..b64496062421 100644
> --- a/drivers/isdn/hardware/eicon/Kconfig
> +++ b/drivers/isdn/hardware/eicon/Kconfig
> @@ -31,6 +31,7 @@ config ISDN_DIVAS_PRIPCI
>  
>  config ISDN_DIVAS_DIVACAPI
>  	tristate "DIVA CAPI2.0 interface support"
> +	depends on !KASAN || BROKEN
>  	help
>  	  You need this to provide the CAPI interface
>  	  for DIVA Server cards.
> 

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 01/26] compiler: introduce noinline_for_kasan annotation
  2017-03-03 13:55     ` Alexander Potapenko
@ 2017-03-03 14:30       ` Arnd Bergmann
  2017-03-03 14:33         ` Alexander Potapenko
  0 siblings, 1 reply; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-03 14:30 UTC (permalink / raw)
  To: Alexander Potapenko
  Cc: Andrey Ryabinin, kasan-dev, Dmitry Vyukov, Networking, LKML,
	linux-media, linux-wireless, kernel-build-reports,
	David S . Miller

On Fri, Mar 3, 2017 at 2:55 PM, Alexander Potapenko <glider@google.com> wrote:
> On Fri, Mar 3, 2017 at 2:50 PM, Andrey Ryabinin <aryabinin@virtuozzo.com> wrote:

>>> @@ -416,6 +416,17 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
>>>   */
>>>  #define noinline_for_stack noinline
>>>
>>> +/*
>>> + * CONFIG_KASAN can lead to extreme stack usage with certain patterns when
>>> + * one function gets inlined many times and each instance requires a stack
>>> + * ckeck.
>>> + */
>>> +#ifdef CONFIG_KASAN
>>> +#define noinline_for_kasan noinline __maybe_unused
>>
>>
>> noinline_iff_kasan might be a better name.  noinline_for_kasan gives the impression
>> that we always noinline function for the sake of kasan, while noinline_iff_kasan
>> clearly indicates that function is noinline only if kasan is used.

Fine with me. I actually tried to come up with a name that implies that the
symbol is actually "inline" (or even __always_inline_ without KASAN, but
couldn't think of any good name for it.

> FWIW we may be facing the same problem with other compiler-based
> tools, e.g. KMSAN (which isn't there yet).
> So it might be better to choose a macro name that doesn't use the name "KASAN".
> E.g. noinline_iff_memtool (or noinline_iff_memory_tool if that's not too long).
> WDYT?

Would KMSAN also force local variables to be non-overlapping the way that
asan-stack=1 and -fsanitize-address-use-after-scope do? As I understood it,
KMSAN would add extra code for maintaining the uninit bits, but in an example
like this

int f(int *);
static inline __attribute__((always_inline)) int g(void)
{
    int i;
    f(&i);
    return i;
}
int f(void)
{
     return g()+g()+g()+g();
}

each of the four copies of 'i' could have the same location on the stack
and get marked uninitialized again before calling f(). We only need
noinline_for_kasan (whatever we end up calling that) for compiler
features that force each instance of 'i' to have its own stack redzone.

     Arnd

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 01/26] compiler: introduce noinline_for_kasan annotation
  2017-03-03 14:30       ` Arnd Bergmann
@ 2017-03-03 14:33         ` Alexander Potapenko
  2017-03-03 14:51           ` Arnd Bergmann
  0 siblings, 1 reply; 67+ messages in thread
From: Alexander Potapenko @ 2017-03-03 14:33 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Andrey Ryabinin, kasan-dev, Dmitry Vyukov, Networking, LKML,
	linux-media, linux-wireless, kernel-build-reports,
	David S . Miller

On Fri, Mar 3, 2017 at 3:30 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Fri, Mar 3, 2017 at 2:55 PM, Alexander Potapenko <glider@google.com> wrote:
>> On Fri, Mar 3, 2017 at 2:50 PM, Andrey Ryabinin <aryabinin@virtuozzo.com> wrote:
>
>>>> @@ -416,6 +416,17 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
>>>>   */
>>>>  #define noinline_for_stack noinline
>>>>
>>>> +/*
>>>> + * CONFIG_KASAN can lead to extreme stack usage with certain patterns when
>>>> + * one function gets inlined many times and each instance requires a stack
>>>> + * ckeck.
>>>> + */
>>>> +#ifdef CONFIG_KASAN
>>>> +#define noinline_for_kasan noinline __maybe_unused
>>>
>>>
>>> noinline_iff_kasan might be a better name.  noinline_for_kasan gives the impression
>>> that we always noinline function for the sake of kasan, while noinline_iff_kasan
>>> clearly indicates that function is noinline only if kasan is used.
>
> Fine with me. I actually tried to come up with a name that implies that the
> symbol is actually "inline" (or even __always_inline_ without KASAN, but
> couldn't think of any good name for it.
>
>> FWIW we may be facing the same problem with other compiler-based
>> tools, e.g. KMSAN (which isn't there yet).
>> So it might be better to choose a macro name that doesn't use the name "KASAN".
>> E.g. noinline_iff_memtool (or noinline_iff_memory_tool if that's not too long).
>> WDYT?
>
> Would KMSAN also force local variables to be non-overlapping the way that
> asan-stack=1 and -fsanitize-address-use-after-scope do? As I understood it,
> KMSAN would add extra code for maintaining the uninit bits, but in an example
> like this
The thing is that KMSAN (and other tools that insert heavyweight
instrumentation) may cause heavy register spilling which will also
blow up the stack frames.
> int f(int *);
> static inline __attribute__((always_inline)) int g(void)
> {
>     int i;
>     f(&i);
>     return i;
> }
> int f(void)
> {
>      return g()+g()+g()+g();
> }
>
> each of the four copies of 'i' could have the same location on the stack
> and get marked uninitialized again before calling f(). We only need
> noinline_for_kasan (whatever we end up calling that) for compiler
> features that force each instance of 'i' to have its own stack redzone.
>
>      Arnd



-- 
Alexander Potapenko
Software Engineer

Google Germany GmbH
Erika-Mann-Straße, 33
80636 München

Geschäftsführer: Matthew Scott Sucherman, Paul Terence Manicle
Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 02/26] rewrite READ_ONCE/WRITE_ONCE
  2017-03-03  8:26           ` Christian Borntraeger
  2017-03-03  9:54             ` Arnd Bergmann
@ 2017-03-03 14:49             ` Peter Zijlstra
  2017-03-03 14:57               ` Peter Zijlstra
  1 sibling, 1 reply; 67+ messages in thread
From: Peter Zijlstra @ 2017-03-03 14:49 UTC (permalink / raw)
  To: Christian Borntraeger
  Cc: Arnd Bergmann, kasan-dev, Andrey Ryabinin, Alexander Potapenko,
	Dmitry Vyukov, Networking, Linux Kernel Mailing List,
	linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Paul McKenney

On Fri, Mar 03, 2017 at 09:26:50AM +0100, Christian Borntraeger wrote:
> Right. The main purpose is to read/write _ONCE_. You can assume a somewhat
> atomic access for sizes <= word size. And there are certainly places that
> rely on that. But the *ONCE thing is mostly used for things where we used
> barrier() 10 years ago.

A lot of code relies on READ/WRITE_ONCE() to generate single
instructions for naturally aligned machined word sized loads/stores
(something GCC used to guarantee, but does no longer IIRC).

So much so that I would say its a bug if READ/WRITE_ONCE() doesn't
generate a single instruction under those conditions.

However, every time I've tried to introduce stricter
semantics/primitives to verify things Linus hated it.

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 26/26] kasan: rework Kconfig settings
  2017-03-02 16:38 ` [PATCH 26/26] kasan: rework Kconfig settings Arnd Bergmann
@ 2017-03-03 14:51   ` Andrey Ryabinin
  2017-03-03 15:03     ` Arnd Bergmann
  0 siblings, 1 reply; 67+ messages in thread
From: Andrey Ryabinin @ 2017-03-03 14:51 UTC (permalink / raw)
  To: Arnd Bergmann, kasan-dev
  Cc: Alexander Potapenko, Dmitry Vyukov, netdev, linux-kernel,
	linux-media, linux-wireless, kernel-build-reports,
	David S . Miller



On 03/02/2017 07:38 PM, Arnd Bergmann wrote:

> 
> diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
> index 97d62c2da6c2..27c838c40a36 100644
> --- a/lib/Kconfig.debug
> +++ b/lib/Kconfig.debug
> @@ -216,10 +216,9 @@ config ENABLE_MUST_CHECK
>  config FRAME_WARN
>  	int "Warn for stack frames larger than (needs gcc 4.4)"
>  	range 0 8192
> -	default 0 if KASAN
> -	default 2048 if GCC_PLUGIN_LATENT_ENTROPY
> +	default 3072 if KASAN_EXTRA
>  	default 1024 if !64BIT
> -	default 2048 if 64BIT
> +	default 1280 if 64BIT

This looks unrelated. Also, it means that now we have 1280 with KASAN=y && KASAN_EXTRA=n.
Judging from changelog I assume that this hunk slipped here from the follow up series.

>  	help
>  	  Tell gcc to warn at build time for stack frames larger than this.
>  	  Setting this too low will cause a lot of warnings.
> @@ -499,7 +498,7 @@ config DEBUG_OBJECTS_ENABLE_DEFAULT
>  
>  config DEBUG_SLAB
>  	bool "Debug slab memory allocations"
> -	depends on DEBUG_KERNEL && SLAB && !KMEMCHECK
> +	depends on DEBUG_KERNEL && SLAB && !KMEMCHECK && !KASAN
>  	help
>  	  Say Y here to have the kernel do limited verification on memory
>  	  allocation as well as poisoning memory on free to catch use of freed
> @@ -511,7 +510,7 @@ config DEBUG_SLAB_LEAK
>  
>  config SLUB_DEBUG_ON
>  	bool "SLUB debugging on by default"
> -	depends on SLUB && SLUB_DEBUG && !KMEMCHECK
> +	depends on SLUB && SLUB_DEBUG && !KMEMCHECK && !KASAN

Why? SLUB_DEBUG_ON works with KASAN.

>  	default n
>  	help
>  	  Boot with debugging on by default. SLUB boots by default with

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 01/26] compiler: introduce noinline_for_kasan annotation
  2017-03-03 14:33         ` Alexander Potapenko
@ 2017-03-03 14:51           ` Arnd Bergmann
  0 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-03 14:51 UTC (permalink / raw)
  To: Alexander Potapenko
  Cc: Andrey Ryabinin, kasan-dev, Dmitry Vyukov, Networking, LKML,
	linux-media, linux-wireless, kernel-build-reports,
	David S . Miller

On Fri, Mar 3, 2017 at 3:33 PM, Alexander Potapenko <glider@google.com> wrote:
> On Fri, Mar 3, 2017 at 3:30 PM, Arnd Bergmann <arnd@arndb.de> wrote:
>> On Fri, Mar 3, 2017 at 2:55 PM, Alexander Potapenko <glider@google.com> wrote:
>>
>> Would KMSAN also force local variables to be non-overlapping the way that
>> asan-stack=1 and -fsanitize-address-use-after-scope do? As I understood it,
>> KMSAN would add extra code for maintaining the uninit bits, but in an example
>> like this
> The thing is that KMSAN (and other tools that insert heavyweight
> instrumentation) may cause heavy register spilling which will also
> blow up the stack frames.

In that case, I would expect a mostly distinct set of functions to have large
stack frames with KMSAN, compared to the ones that need
noinline_for_kasan. In most cases I patched, the called inline function is
actually trivial, but invoked many times from the same caller.

     Arnd

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 25/26] isdn: eicon: mark divascapi incompatible with kasan
  2017-03-03 14:20   ` Andrey Ryabinin
@ 2017-03-03 14:54     ` Arnd Bergmann
  2017-03-03 15:22       ` Andrey Ryabinin
  0 siblings, 1 reply; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-03 14:54 UTC (permalink / raw)
  To: Andrey Ryabinin
  Cc: kasan-dev, Alexander Potapenko, Dmitry Vyukov, Networking,
	Linux Kernel Mailing List, linux-media, linux-wireless,
	kernel-build-reports, David S . Miller

On Fri, Mar 3, 2017 at 3:20 PM, Andrey Ryabinin <aryabinin@virtuozzo.com> wrote:
>
>
> On 03/02/2017 07:38 PM, Arnd Bergmann wrote:
>> When CONFIG_KASAN is enabled, we have several functions that use rather
>> large kernel stacks, e.g.
>>
>> drivers/isdn/hardware/eicon/message.c: In function 'group_optimization':
>> drivers/isdn/hardware/eicon/message.c:14841:1: warning: the frame size of 864 bytes is larger than 500 bytes [-Wframe-larger-than=]
>> drivers/isdn/hardware/eicon/message.c: In function 'add_b1':
>> drivers/isdn/hardware/eicon/message.c:7925:1: warning: the frame size of 1008 bytes is larger than 500 bytes [-Wframe-larger-than=]
>> drivers/isdn/hardware/eicon/message.c: In function 'add_b23':
>> drivers/isdn/hardware/eicon/message.c:8551:1: warning: the frame size of 928 bytes is larger than 500 bytes [-Wframe-larger-than=]
>> drivers/isdn/hardware/eicon/message.c: In function 'sig_ind':
>> drivers/isdn/hardware/eicon/message.c:6113:1: warning: the frame size of 2112 bytes is larger than 500 bytes [-Wframe-larger-than=]
>>
>> To be on the safe side, and to enable a lower frame size warning limit, let's
>> just mark this driver as broken when KASAN is in use. I have tried to reduce
>> the stack size as I did with dozens of other drivers, but failed to come up
>> with a good solution for this one.
>>
>
> This is kinda radical solution.
> Wouldn't be better to just increase -Wframe-larger-than for this driver through Makefile?

I thought about it too, and decided for disabling the driver entirely
since I suspected that
not only the per-function stack frame is overly large here but also
depth of the call chain,
which would then lead us to hiding an actual stack overflow.

Note that this driver is almost certainly broken, it hasn't seen any
updates other than
style and compile-warning fixes in 10 years and doesn't support any of
the hardware
introduced since 2002 (the company still makes PCIe ISDN adapters, but
the driver
only supports legacy PCI versions and older buses).

    Arnd

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 02/26] rewrite READ_ONCE/WRITE_ONCE
  2017-03-03 14:49             ` Peter Zijlstra
@ 2017-03-03 14:57               ` Peter Zijlstra
  0 siblings, 0 replies; 67+ messages in thread
From: Peter Zijlstra @ 2017-03-03 14:57 UTC (permalink / raw)
  To: Christian Borntraeger
  Cc: Arnd Bergmann, kasan-dev, Andrey Ryabinin, Alexander Potapenko,
	Dmitry Vyukov, Networking, Linux Kernel Mailing List,
	linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Paul McKenney

On Fri, Mar 03, 2017 at 03:49:38PM +0100, Peter Zijlstra wrote:
> On Fri, Mar 03, 2017 at 09:26:50AM +0100, Christian Borntraeger wrote:
> > Right. The main purpose is to read/write _ONCE_. You can assume a somewhat
> > atomic access for sizes <= word size. And there are certainly places that
> > rely on that. But the *ONCE thing is mostly used for things where we used
> > barrier() 10 years ago.
> 
> A lot of code relies on READ/WRITE_ONCE() to generate single
> instructions for naturally aligned machined word sized loads/stores
> (something GCC used to guarantee, but does no longer IIRC).
> 
> So much so that I would say its a bug if READ/WRITE_ONCE() doesn't
> generate a single instruction under those conditions.
> 
> However, every time I've tried to introduce stricter
> semantics/primitives to verify things Linus hated it.

See here for the last attempt:

  https://marc.info/?l=linux-virtualization&m=148007765918101&w=2

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 26/26] kasan: rework Kconfig settings
  2017-03-03 14:51   ` Andrey Ryabinin
@ 2017-03-03 15:03     ` Arnd Bergmann
  0 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-03 15:03 UTC (permalink / raw)
  To: Andrey Ryabinin
  Cc: kasan-dev, Alexander Potapenko, Dmitry Vyukov, Networking,
	Linux Kernel Mailing List, linux-media, linux-wireless,
	kernel-build-reports, David S . Miller

On Fri, Mar 3, 2017 at 3:51 PM, Andrey Ryabinin <aryabinin@virtuozzo.com> wrote:
>
>
> On 03/02/2017 07:38 PM, Arnd Bergmann wrote:
>
>>
>> diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
>> index 97d62c2da6c2..27c838c40a36 100644
>> --- a/lib/Kconfig.debug
>> +++ b/lib/Kconfig.debug
>> @@ -216,10 +216,9 @@ config ENABLE_MUST_CHECK
>>  config FRAME_WARN
>>       int "Warn for stack frames larger than (needs gcc 4.4)"
>>       range 0 8192
>> -     default 0 if KASAN
>> -     default 2048 if GCC_PLUGIN_LATENT_ENTROPY
>> +     default 3072 if KASAN_EXTRA
>>       default 1024 if !64BIT
>> -     default 2048 if 64BIT
>> +     default 1280 if 64BIT
>
> This looks unrelated. Also, it means that now we have 1280 with KASAN=y && KASAN_EXTRA=n.
> Judging from changelog I assume that this hunk slipped here from the follow up series.

Right, this slipped in by accident, I've already fixed it up locally.

>>       help
>>         Tell gcc to warn at build time for stack frames larger than this.
>>         Setting this too low will cause a lot of warnings.
>> @@ -499,7 +498,7 @@ config DEBUG_OBJECTS_ENABLE_DEFAULT
>>
>>  config DEBUG_SLAB
>>       bool "Debug slab memory allocations"
>> -     depends on DEBUG_KERNEL && SLAB && !KMEMCHECK
>> +     depends on DEBUG_KERNEL && SLAB && !KMEMCHECK && !KASAN
>>       help
>>         Say Y here to have the kernel do limited verification on memory
>>         allocation as well as poisoning memory on free to catch use of freed
>> @@ -511,7 +510,7 @@ config DEBUG_SLAB_LEAK
>>
>>  config SLUB_DEBUG_ON
>>       bool "SLUB debugging on by default"
>> -     depends on SLUB && SLUB_DEBUG && !KMEMCHECK
>> +     depends on SLUB && SLUB_DEBUG && !KMEMCHECK && !KASAN
>
> Why? SLUB_DEBUG_ON works with KASAN.

Ok, will fix. I wrongly guessed that kmemcheck and kasan had the
same reason for the two dependencies here.

    Arnd

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 25/26] isdn: eicon: mark divascapi incompatible with kasan
  2017-03-03 14:54     ` Arnd Bergmann
@ 2017-03-03 15:22       ` Andrey Ryabinin
  2017-03-03 15:37         ` Arnd Bergmann
  0 siblings, 1 reply; 67+ messages in thread
From: Andrey Ryabinin @ 2017-03-03 15:22 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: kasan-dev, Alexander Potapenko, Dmitry Vyukov, Networking,
	Linux Kernel Mailing List, linux-media, linux-wireless,
	kernel-build-reports, David S . Miller



On 03/03/2017 05:54 PM, Arnd Bergmann wrote:
> On Fri, Mar 3, 2017 at 3:20 PM, Andrey Ryabinin <aryabinin@virtuozzo.com> wrote:
>>
>>
>> On 03/02/2017 07:38 PM, Arnd Bergmann wrote:
>>> When CONFIG_KASAN is enabled, we have several functions that use rather
>>> large kernel stacks, e.g.
>>>
>>> drivers/isdn/hardware/eicon/message.c: In function 'group_optimization':
>>> drivers/isdn/hardware/eicon/message.c:14841:1: warning: the frame size of 864 bytes is larger than 500 bytes [-Wframe-larger-than=]
>>> drivers/isdn/hardware/eicon/message.c: In function 'add_b1':
>>> drivers/isdn/hardware/eicon/message.c:7925:1: warning: the frame size of 1008 bytes is larger than 500 bytes [-Wframe-larger-than=]
>>> drivers/isdn/hardware/eicon/message.c: In function 'add_b23':
>>> drivers/isdn/hardware/eicon/message.c:8551:1: warning: the frame size of 928 bytes is larger than 500 bytes [-Wframe-larger-than=]
>>> drivers/isdn/hardware/eicon/message.c: In function 'sig_ind':
>>> drivers/isdn/hardware/eicon/message.c:6113:1: warning: the frame size of 2112 bytes is larger than 500 bytes [-Wframe-larger-than=]
>>>
>>> To be on the safe side, and to enable a lower frame size warning limit, let's
>>> just mark this driver as broken when KASAN is in use. I have tried to reduce
>>> the stack size as I did with dozens of other drivers, but failed to come up
>>> with a good solution for this one.
>>>
>>
>> This is kinda radical solution.
>> Wouldn't be better to just increase -Wframe-larger-than for this driver through Makefile?
> 
> I thought about it too, and decided for disabling the driver entirely
> since I suspected that
> not only the per-function stack frame is overly large here but also
> depth of the call chain,
> which would then lead us to hiding an actual stack overflow.
> 

No one complained so far ;)
Disabling the driver like you did will throw it out from allmodconfig so it will receive less compile-testing.


> Note that this driver is almost certainly broken, it hasn't seen any
> updates other than
> style and compile-warning fixes in 10 years and doesn't support any of
> the hardware
> introduced since 2002 (the company still makes PCIe ISDN adapters, but
> the driver
> only supports legacy PCI versions and older buses).

Which means that it's unlikely that someone will run this driver with KASAN and trigger stack overflow (if it's really possible).

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 25/26] isdn: eicon: mark divascapi incompatible with kasan
  2017-03-03 15:22       ` Andrey Ryabinin
@ 2017-03-03 15:37         ` Arnd Bergmann
  0 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-03 15:37 UTC (permalink / raw)
  To: Andrey Ryabinin
  Cc: kasan-dev, Alexander Potapenko, Dmitry Vyukov, Networking,
	Linux Kernel Mailing List, linux-media, linux-wireless,
	kernel-build-reports, David S . Miller

On Fri, Mar 3, 2017 at 4:22 PM, Andrey Ryabinin <aryabinin@virtuozzo.com> wrote:
> On 03/03/2017 05:54 PM, Arnd Bergmann wrote:
>> On Fri, Mar 3, 2017 at 3:20 PM, Andrey Ryabinin <aryabinin@virtuozzo.com> wrote:
>>> On 03/02/2017 07:38 PM, Arnd Bergmann wrote:
>>>
>>> This is kinda radical solution.
>>> Wouldn't be better to just increase -Wframe-larger-than for this driver through Makefile?
>>
>> I thought about it too, and decided for disabling the driver entirely
>> since I suspected that
>> not only the per-function stack frame is overly large here but also
>> depth of the call chain,
>> which would then lead us to hiding an actual stack overflow.
>>
>
> No one complained so far ;)
> Disabling the driver like you did will throw it out from allmodconfig so it will receive less compile-testing.

Good point, I'll add a driver specific flag then and leave it there.

>> Note that this driver is almost certainly broken, it hasn't seen any
>> updates other than
>> style and compile-warning fixes in 10 years and doesn't support any of
>> the hardware
>> introduced since 2002 (the company still makes PCIe ISDN adapters, but
>> the driver
>> only supports legacy PCI versions and older buses).
>
> Which means that it's unlikely that someone will run this driver with KASAN
and trigger stack overflow (if it's really possible).

True.

   Arnd

^ permalink raw reply	[flat|nested] 67+ messages in thread

* RE: [PATCH 01/26] compiler: introduce noinline_for_kasan annotation
  2017-03-03 13:50   ` Andrey Ryabinin
  2017-03-03 13:55     ` Alexander Potapenko
@ 2017-03-03 16:34     ` David Laight
  1 sibling, 0 replies; 67+ messages in thread
From: David Laight @ 2017-03-03 16:34 UTC (permalink / raw)
  To: 'Andrey Ryabinin', Arnd Bergmann, kasan-dev
  Cc: Alexander Potapenko, Dmitry Vyukov, netdev, linux-kernel,
	linux-media, linux-wireless, kernel-build-reports,
	David S . Miller

From: Andrey Ryabinin
> Sent: 03 March 2017 13:50
...
> noinline_iff_kasan might be a better name.  noinline_for_kasan gives the impression
> that we always noinline function for the sake of kasan, while noinline_iff_kasan
> clearly indicates that function is noinline only if kasan is used.

noinline_if_stackbloat

	David

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 07/26] brcmsmac: reduce stack size with KASAN
  2017-03-02 16:38 ` [PATCH 07/26] brcmsmac: reduce stack size with KASAN Arnd Bergmann
@ 2017-03-06  9:16   ` Arend Van Spriel
  2017-03-06 10:38     ` Arnd Bergmann
  0 siblings, 1 reply; 67+ messages in thread
From: Arend Van Spriel @ 2017-03-06  9:16 UTC (permalink / raw)
  To: Arnd Bergmann, kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller

On 2-3-2017 17:38, Arnd Bergmann wrote:
> The wlc_phy_table_write_nphy/wlc_phy_table_read_nphy functions always put an object
> on the stack, which will each require a redzone with KASAN and lead to possible
> stack overflow:
> 
> drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c: In function 'wlc_phy_workarounds_nphy':
> drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c:17135:1: warning: the frame size of 6312 bytes is larger than 1000 bytes [-Wframe-larger-than=]

Looks like this warning text ended up in the wrong commit message. Got
me confused for a sec :-p

> This marks the two functions as noinline_for_kasan, avoiding the problem entirely.

Frankly I seriously dislike annotating code for the sake of some
(dynamic) memory analyzer. To me the whole thing seems rather
unnecessary. If the code passes the 2048 stack limit without KASAN it
would seem the limit with KASAN should be such that no warning is given.
I suspect that it is rather difficult to predict the additional size of
the instrumentation code and on some systems there might be a real issue
with increased stack usage.

Regards,
Arend

> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
>  drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
> index b3aab2fe96eb..42dc8e1f483d 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
> @@ -14157,7 +14157,7 @@ static void wlc_phy_bphy_init_nphy(struct brcms_phy *pi)
>  	write_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_STEP, 0x668);
>  }
>  
> -void
> +noinline_for_kasan void
>  wlc_phy_table_write_nphy(struct brcms_phy *pi, u32 id, u32 len, u32 offset,
>  			 u32 width, const void *data)
>  {
> @@ -14171,7 +14171,7 @@ wlc_phy_table_write_nphy(struct brcms_phy *pi, u32 id, u32 len, u32 offset,
>  	wlc_phy_write_table_nphy(pi, &tbl);
>  }
>  
> -void
> +noinline_for_kasan void
>  wlc_phy_table_read_nphy(struct brcms_phy *pi, u32 id, u32 len, u32 offset,
>  			u32 width, void *data)
>  {
> 

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 08/26] brcmsmac: make some local variables 'static const' to reduce stack size
  2017-03-02 16:38 ` [PATCH 08/26] brcmsmac: make some local variables 'static const' to reduce stack size Arnd Bergmann
@ 2017-03-06  9:30   ` Arend Van Spriel
  2017-03-06 16:19     ` Kalle Valo
  0 siblings, 1 reply; 67+ messages in thread
From: Arend Van Spriel @ 2017-03-06  9:30 UTC (permalink / raw)
  To: Arnd Bergmann, kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller

On 2-3-2017 17:38, Arnd Bergmann wrote:
> With KASAN and a couple of other patches applied, this driver is one
> of the few remaining ones that actually use more than 2048 bytes of
> kernel stack:
> 
> broadcom/brcm80211/brcmsmac/phy/phy_n.c: In function 'wlc_phy_workarounds_nphy_gainctrl':
> broadcom/brcm80211/brcmsmac/phy/phy_n.c:16065:1: warning: the frame size of 3264 bytes is larger than 2048 bytes [-Wframe-larger-than=]
> broadcom/brcm80211/brcmsmac/phy/phy_n.c: In function 'wlc_phy_workarounds_nphy':
> broadcom/brcm80211/brcmsmac/phy/phy_n.c:17138:1: warning: the frame size of 2864 bytes is larger than 2048 bytes [-Wframe-larger-than=]
> 
> Here, I'm reducing the stack size by marking as many local variables as
> 'static const' as I can without changing the actual code.

Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
>  .../broadcom/brcm80211/brcmsmac/phy/phy_n.c        | 197 ++++++++++-----------
>  1 file changed, 97 insertions(+), 100 deletions(-)
> 
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
> index 42dc8e1f483d..48a4df488d75 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
> @@ -14764,8 +14764,8 @@ static void wlc_phy_ipa_restore_tx_digi_filts_nphy(struct brcms_phy *pi)
>  }
>  
>  static void
> -wlc_phy_set_rfseq_nphy(struct brcms_phy *pi, u8 cmd, u8 *events, u8 *dlys,
> -		       u8 len)
> +wlc_phy_set_rfseq_nphy(struct brcms_phy *pi, u8 cmd, const u8 *events,
> +		       const u8 *dlys, u8 len)
>  {
>  	u32 t1_offset, t2_offset;
>  	u8 ctr;
> @@ -15240,16 +15240,16 @@ static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(struct brcms_phy *pi)
>  static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi)
>  {
>  	u16 currband;
> -	s8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 };
> -	s8 *lna1_gain_db = NULL;
> -	s8 *lna1_gain_db_2 = NULL;
> -	s8 *lna2_gain_db = NULL;
> -	s8 tiaA_gain_db_rev7[] = { -9, -6, -3, 0, 3, 3, 3, 3, 3, 3 };
> -	s8 *tia_gain_db;
> -	s8 tiaA_gainbits_rev7[] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 };
> -	s8 *tia_gainbits;
> -	u16 rfseqA_init_gain_rev7[] = { 0x624f, 0x624f };
> -	u16 *rfseq_init_gain;
> +	static const s8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 };
> +	const s8 *lna1_gain_db = NULL;
> +	const s8 *lna1_gain_db_2 = NULL;
> +	const s8 *lna2_gain_db = NULL;
> +	static const s8 tiaA_gain_db_rev7[] = { -9, -6, -3, 0, 3, 3, 3, 3, 3, 3 };
> +	const s8 *tia_gain_db;
> +	static const s8 tiaA_gainbits_rev7[] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 };
> +	const s8 *tia_gainbits;
> +	static const u16 rfseqA_init_gain_rev7[] = { 0x624f, 0x624f };
> +	const u16 *rfseq_init_gain;
>  	u16 init_gaincode;
>  	u16 clip1hi_gaincode;
>  	u16 clip1md_gaincode = 0;
> @@ -15310,10 +15310,9 @@ static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi)
>  
>  			if ((freq <= 5080) || (freq == 5825)) {
>  
> -				s8 lna1A_gain_db_rev7[] = { 11, 16, 20, 24 };
> -				s8 lna1A_gain_db_2_rev7[] = {
> -					11, 17, 22, 25};
> -				s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
> +				static const s8 lna1A_gain_db_rev7[] = { 11, 16, 20, 24 };
> +				static const s8 lna1A_gain_db_2_rev7[] = { 11, 17, 22, 25};
> +				static const s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
>  
>  				crsminu_th = 0x3e;
>  				lna1_gain_db = lna1A_gain_db_rev7;
> @@ -15321,10 +15320,9 @@ static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi)
>  				lna2_gain_db = lna2A_gain_db_rev7;
>  			} else if ((freq >= 5500) && (freq <= 5700)) {
>  
> -				s8 lna1A_gain_db_rev7[] = { 11, 17, 21, 25 };
> -				s8 lna1A_gain_db_2_rev7[] = {
> -					12, 18, 22, 26};
> -				s8 lna2A_gain_db_rev7[] = { 1, 8, 12, 16 };
> +				static const s8 lna1A_gain_db_rev7[] = { 11, 17, 21, 25 };
> +				static const s8 lna1A_gain_db_2_rev7[] = { 12, 18, 22, 26};
> +				static const s8 lna2A_gain_db_rev7[] = { 1, 8, 12, 16 };
>  
>  				crsminu_th = 0x45;
>  				clip1md_gaincode_B = 0x14;
> @@ -15335,10 +15333,9 @@ static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi)
>  				lna2_gain_db = lna2A_gain_db_rev7;
>  			} else {
>  
> -				s8 lna1A_gain_db_rev7[] = { 12, 18, 22, 26 };
> -				s8 lna1A_gain_db_2_rev7[] = {
> -					12, 18, 22, 26};
> -				s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
> +				static const s8 lna1A_gain_db_rev7[] = { 12, 18, 22, 26 };
> +				static const s8 lna1A_gain_db_2_rev7[] = { 12, 18, 22, 26};
> +				static const s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
>  
>  				crsminu_th = 0x41;
>  				lna1_gain_db = lna1A_gain_db_rev7;
> @@ -15450,65 +15447,65 @@ static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi)
>  		NPHY_RFSEQ_CMD_CLR_HIQ_DIS,
>  		NPHY_RFSEQ_CMD_SET_HPF_BW
>  	};
> -	u8 rfseq_updategainu_dlys[] = { 10, 30, 1 };
> -	s8 lna1G_gain_db[] = { 7, 11, 16, 23 };
> -	s8 lna1G_gain_db_rev4[] = { 8, 12, 17, 25 };
> -	s8 lna1G_gain_db_rev5[] = { 9, 13, 18, 26 };
> -	s8 lna1G_gain_db_rev6[] = { 8, 13, 18, 25 };
> -	s8 lna1G_gain_db_rev6_224B0[] = { 10, 14, 19, 27 };
> -	s8 lna1A_gain_db[] = { 7, 11, 17, 23 };
> -	s8 lna1A_gain_db_rev4[] = { 8, 12, 18, 23 };
> -	s8 lna1A_gain_db_rev5[] = { 6, 10, 16, 21 };
> -	s8 lna1A_gain_db_rev6[] = { 6, 10, 16, 21 };
> -	s8 *lna1_gain_db = NULL;
> -	s8 lna2G_gain_db[] = { -5, 6, 10, 14 };
> -	s8 lna2G_gain_db_rev5[] = { -3, 7, 11, 16 };
> -	s8 lna2G_gain_db_rev6[] = { -5, 6, 10, 14 };
> -	s8 lna2G_gain_db_rev6_224B0[] = { -5, 6, 10, 15 };
> -	s8 lna2A_gain_db[] = { -6, 2, 6, 10 };
> -	s8 lna2A_gain_db_rev4[] = { -5, 2, 6, 10 };
> -	s8 lna2A_gain_db_rev5[] = { -7, 0, 4, 8 };
> -	s8 lna2A_gain_db_rev6[] = { -7, 0, 4, 8 };
> -	s8 *lna2_gain_db = NULL;
> -	s8 tiaG_gain_db[] = {
> +	static const u8 rfseq_updategainu_dlys[] = { 10, 30, 1 };
> +	static const s8 lna1G_gain_db[] = { 7, 11, 16, 23 };
> +	static const s8 lna1G_gain_db_rev4[] = { 8, 12, 17, 25 };
> +	static const s8 lna1G_gain_db_rev5[] = { 9, 13, 18, 26 };
> +	static const s8 lna1G_gain_db_rev6[] = { 8, 13, 18, 25 };
> +	static const s8 lna1G_gain_db_rev6_224B0[] = { 10, 14, 19, 27 };
> +	static const s8 lna1A_gain_db[] = { 7, 11, 17, 23 };
> +	static const s8 lna1A_gain_db_rev4[] = { 8, 12, 18, 23 };
> +	static const s8 lna1A_gain_db_rev5[] = { 6, 10, 16, 21 };
> +	static const s8 lna1A_gain_db_rev6[] = { 6, 10, 16, 21 };
> +	const s8 *lna1_gain_db = NULL;
> +	static const s8 lna2G_gain_db[] = { -5, 6, 10, 14 };
> +	static const s8 lna2G_gain_db_rev5[] = { -3, 7, 11, 16 };
> +	static const s8 lna2G_gain_db_rev6[] = { -5, 6, 10, 14 };
> +	static const s8 lna2G_gain_db_rev6_224B0[] = { -5, 6, 10, 15 };
> +	static const s8 lna2A_gain_db[] = { -6, 2, 6, 10 };
> +	static const s8 lna2A_gain_db_rev4[] = { -5, 2, 6, 10 };
> +	static const s8 lna2A_gain_db_rev5[] = { -7, 0, 4, 8 };
> +	static const s8 lna2A_gain_db_rev6[] = { -7, 0, 4, 8 };
> +	const s8 *lna2_gain_db = NULL;
> +	static const s8 tiaG_gain_db[] = {
>  		0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A };
> -	s8 tiaA_gain_db[] = {
> +	static const s8 tiaA_gain_db[] = {
>  		0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 };
> -	s8 tiaA_gain_db_rev4[] = {
> +	static const s8 tiaA_gain_db_rev4[] = {
>  		0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
> -	s8 tiaA_gain_db_rev5[] = {
> +	static const s8 tiaA_gain_db_rev5[] = {
>  		0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
> -	s8 tiaA_gain_db_rev6[] = {
> +	static const s8 tiaA_gain_db_rev6[] = {
>  		0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
> -	s8 *tia_gain_db;
> -	s8 tiaG_gainbits[] = {
> +	const s8 *tia_gain_db;
> +	static const s8 tiaG_gainbits[] = {
>  		0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 };
> -	s8 tiaA_gainbits[] = {
> +	static const s8 tiaA_gainbits[] = {
>  		0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06 };
> -	s8 tiaA_gainbits_rev4[] = {
> +	static const s8 tiaA_gainbits_rev4[] = {
>  		0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
> -	s8 tiaA_gainbits_rev5[] = {
> +	static const s8 tiaA_gainbits_rev5[] = {
>  		0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
> -	s8 tiaA_gainbits_rev6[] = {
> +	static const s8 tiaA_gainbits_rev6[] = {
>  		0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
> -	s8 *tia_gainbits;
> -	s8 lpf_gain_db[] = { 0x00, 0x06, 0x0c, 0x12, 0x12, 0x12 };
> -	s8 lpf_gainbits[] = { 0x00, 0x01, 0x02, 0x03, 0x03, 0x03 };
> -	u16 rfseqG_init_gain[] = { 0x613f, 0x613f, 0x613f, 0x613f };
> -	u16 rfseqG_init_gain_rev4[] = { 0x513f, 0x513f, 0x513f, 0x513f };
> -	u16 rfseqG_init_gain_rev5[] = { 0x413f, 0x413f, 0x413f, 0x413f };
> -	u16 rfseqG_init_gain_rev5_elna[] = {
> +	const s8 *tia_gainbits;
> +	static const s8 lpf_gain_db[] = { 0x00, 0x06, 0x0c, 0x12, 0x12, 0x12 };
> +	static const s8 lpf_gainbits[] = { 0x00, 0x01, 0x02, 0x03, 0x03, 0x03 };
> +	static const u16 rfseqG_init_gain[] = { 0x613f, 0x613f, 0x613f, 0x613f };
> +	static const u16 rfseqG_init_gain_rev4[] = { 0x513f, 0x513f, 0x513f, 0x513f };
> +	static const u16 rfseqG_init_gain_rev5[] = { 0x413f, 0x413f, 0x413f, 0x413f };
> +	static const u16 rfseqG_init_gain_rev5_elna[] = {
>  		0x013f, 0x013f, 0x013f, 0x013f };
> -	u16 rfseqG_init_gain_rev6[] = { 0x513f, 0x513f };
> -	u16 rfseqG_init_gain_rev6_224B0[] = { 0x413f, 0x413f };
> -	u16 rfseqG_init_gain_rev6_elna[] = { 0x113f, 0x113f };
> -	u16 rfseqA_init_gain[] = { 0x516f, 0x516f, 0x516f, 0x516f };
> -	u16 rfseqA_init_gain_rev4[] = { 0x614f, 0x614f, 0x614f, 0x614f };
> -	u16 rfseqA_init_gain_rev4_elna[] = {
> +	static const u16 rfseqG_init_gain_rev6[] = { 0x513f, 0x513f };
> +	static const u16 rfseqG_init_gain_rev6_224B0[] = { 0x413f, 0x413f };
> +	static const u16 rfseqG_init_gain_rev6_elna[] = { 0x113f, 0x113f };
> +	static const u16 rfseqA_init_gain[] = { 0x516f, 0x516f, 0x516f, 0x516f };
> +	static const u16 rfseqA_init_gain_rev4[] = { 0x614f, 0x614f, 0x614f, 0x614f };
> +	static const u16 rfseqA_init_gain_rev4_elna[] = {
>  		0x314f, 0x314f, 0x314f, 0x314f };
> -	u16 rfseqA_init_gain_rev5[] = { 0x714f, 0x714f, 0x714f, 0x714f };
> -	u16 rfseqA_init_gain_rev6[] = { 0x714f, 0x714f };
> -	u16 *rfseq_init_gain;
> +	static const u16 rfseqA_init_gain_rev5[] = { 0x714f, 0x714f, 0x714f, 0x714f };
> +	static const u16 rfseqA_init_gain_rev6[] = { 0x714f, 0x714f };
> +	const u16 *rfseq_init_gain;
>  	u16 initG_gaincode = 0x627e;
>  	u16 initG_gaincode_rev4 = 0x527e;
>  	u16 initG_gaincode_rev5 = 0x427e;
> @@ -15538,10 +15535,10 @@ static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi)
>  	u16 clip1mdA_gaincode_rev6 = 0x2084;
>  	u16 clip1md_gaincode = 0;
>  	u16 clip1loG_gaincode = 0x0074;
> -	u16 clip1loG_gaincode_rev5[] = {
> +	static const u16 clip1loG_gaincode_rev5[] = {
>  		0x0062, 0x0064, 0x006a, 0x106a, 0x106c, 0x1074, 0x107c, 0x207c
>  	};
> -	u16 clip1loG_gaincode_rev6[] = {
> +	static const u16 clip1loG_gaincode_rev6[] = {
>  		0x106a, 0x106c, 0x1074, 0x107c, 0x007e, 0x107e, 0x207e, 0x307e
>  	};
>  	u16 clip1loG_gaincode_rev6_224B0 = 0x1074;
> @@ -16066,7 +16063,7 @@ static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi)
>  
>  static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
>  {
> -	u8 rfseq_rx2tx_events[] = {
> +	static const u8 rfseq_rx2tx_events[] = {
>  		NPHY_RFSEQ_CMD_NOP,
>  		NPHY_RFSEQ_CMD_RXG_FBW,
>  		NPHY_RFSEQ_CMD_TR_SWITCH,
> @@ -16076,7 +16073,7 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
>  		NPHY_RFSEQ_CMD_EXT_PA
>  	};
>  	u8 rfseq_rx2tx_dlys[] = { 8, 6, 6, 2, 4, 60, 1 };
> -	u8 rfseq_tx2rx_events[] = {
> +	static const u8 rfseq_tx2rx_events[] = {
>  		NPHY_RFSEQ_CMD_NOP,
>  		NPHY_RFSEQ_CMD_EXT_PA,
>  		NPHY_RFSEQ_CMD_TX_GAIN,
> @@ -16085,8 +16082,8 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
>  		NPHY_RFSEQ_CMD_RXG_FBW,
>  		NPHY_RFSEQ_CMD_CLR_HIQ_DIS
>  	};
> -	u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 };
> -	u8 rfseq_tx2rx_events_rev3[] = {
> +	static const u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 };
> +	static const u8 rfseq_tx2rx_events_rev3[] = {
>  		NPHY_REV3_RFSEQ_CMD_EXT_PA,
>  		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
>  		NPHY_REV3_RFSEQ_CMD_TX_GAIN,
> @@ -16096,7 +16093,7 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
>  		NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
>  		NPHY_REV3_RFSEQ_CMD_END
>  	};
> -	u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 };
> +	static const u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 };
>  	u8 rfseq_rx2tx_events_rev3[] = {
>  		NPHY_REV3_RFSEQ_CMD_NOP,
>  		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
> @@ -16110,7 +16107,7 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
>  	};
>  	u8 rfseq_rx2tx_dlys_rev3[] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 };
>  
> -	u8 rfseq_rx2tx_events_rev3_ipa[] = {
> +	static const u8 rfseq_rx2tx_events_rev3_ipa[] = {
>  		NPHY_REV3_RFSEQ_CMD_NOP,
>  		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
>  		NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
> @@ -16121,15 +16118,15 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
>  		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
>  		NPHY_REV3_RFSEQ_CMD_END
>  	};
> -	u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
> -	u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f };
> +	static const u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
> +	static const u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f };
>  
>  	s16 alpha0, alpha1, alpha2;
>  	s16 beta0, beta1, beta2;
>  	u32 leg_data_weights, ht_data_weights, nss1_data_weights,
>  	    stbc_data_weights;
>  	u8 chan_freq_range = 0;
> -	u16 dac_control = 0x0002;
> +	static const u16 dac_control = 0x0002;
>  	u16 aux_adc_vmid_rev7_core0[] = { 0x8e, 0x96, 0x96, 0x96 };
>  	u16 aux_adc_vmid_rev7_core1[] = { 0x8f, 0x9f, 0x9f, 0x96 };
>  	u16 aux_adc_vmid_rev4[] = { 0xa2, 0xb4, 0xb4, 0x89 };
> @@ -16139,8 +16136,8 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
>  	u16 aux_adc_gain_rev4[] = { 0x02, 0x02, 0x02, 0x00 };
>  	u16 aux_adc_gain_rev3[] = { 0x02, 0x02, 0x02, 0x00 };
>  	u16 *aux_adc_gain;
> -	u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 };
> -	u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 };
> +	static const u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 };
> +	static const u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 };
>  	s32 min_nvar_val = 0x18d;
>  	s32 min_nvar_offset_6mbps = 20;
>  	u8 pdetrange;
> @@ -16151,9 +16148,9 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
>  	u16 rfseq_rx2tx_lpf_h_hpc_rev7 = 0x77;
>  	u16 rfseq_tx2rx_lpf_h_hpc_rev7 = 0x77;
>  	u16 rfseq_pktgn_lpf_h_hpc_rev7 = 0x77;
> -	u16 rfseq_htpktgn_lpf_hpc_rev7[] = { 0x77, 0x11, 0x11 };
> -	u16 rfseq_pktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
> -	u16 rfseq_cckpktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
> +	static const u16 rfseq_htpktgn_lpf_hpc_rev7[] = { 0x77, 0x11, 0x11 };
> +	static const u16 rfseq_pktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
> +	static const u16 rfseq_cckpktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
>  	u16 ipalvlshift_3p3_war_en = 0;
>  	u16 rccal_bcap_val, rccal_scap_val;
>  	u16 rccal_tx20_11b_bcap = 0;
> @@ -24291,13 +24288,13 @@ static void wlc_phy_update_txcal_ladder_nphy(struct brcms_phy *pi, u16 core)
>  	u16 bbmult;
>  	u16 tblentry;
>  
> -	struct nphy_txiqcal_ladder ladder_lo[] = {
> +	static const struct nphy_txiqcal_ladder ladder_lo[] = {
>  		{3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0},
>  		{25, 0}, {25, 1}, {25, 2}, {25, 3}, {25, 4}, {25, 5},
>  		{25, 6}, {25, 7}, {35, 7}, {50, 7}, {71, 7}, {100, 7}
>  	};
>  
> -	struct nphy_txiqcal_ladder ladder_iq[] = {
> +	static const struct nphy_txiqcal_ladder ladder_iq[] = {
>  		{3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0},
>  		{25, 0}, {35, 0}, {50, 0}, {71, 0}, {100, 0}, {100, 1},
>  		{100, 2}, {100, 3}, {100, 4}, {100, 5}, {100, 6}, {100, 7}
> @@ -25773,67 +25770,67 @@ wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain,
>  	u16 cal_gain[2];
>  	struct nphy_iqcal_params cal_params[2];
>  	u32 tbl_len;
> -	void *tbl_ptr;
> +	const void *tbl_ptr;
>  	bool ladder_updated[2];
>  	u8 mphase_cal_lastphase = 0;
>  	int bcmerror = 0;
>  	bool phyhang_avoid_state = false;
>  
> -	u16 tbl_tx_iqlo_cal_loft_ladder_20[] = {
> +	static const u16 tbl_tx_iqlo_cal_loft_ladder_20[] = {
>  		0x0300, 0x0500, 0x0700, 0x0900, 0x0d00, 0x1100, 0x1900, 0x1901,
>  		0x1902,
>  		0x1903, 0x1904, 0x1905, 0x1906, 0x1907, 0x2407, 0x3207, 0x4607,
>  		0x6407
>  	};
>  
> -	u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = {
> +	static const u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = {
>  		0x0200, 0x0300, 0x0600, 0x0900, 0x0d00, 0x1100, 0x1900, 0x2400,
>  		0x3200,
>  		0x4600, 0x6400, 0x6401, 0x6402, 0x6403, 0x6404, 0x6405, 0x6406,
>  		0x6407
>  	};
>  
> -	u16 tbl_tx_iqlo_cal_loft_ladder_40[] = {
> +	static const u16 tbl_tx_iqlo_cal_loft_ladder_40[] = {
>  		0x0200, 0x0300, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1201,
>  		0x1202,
>  		0x1203, 0x1204, 0x1205, 0x1206, 0x1207, 0x1907, 0x2307, 0x3207,
>  		0x4707
>  	};
>  
> -	u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = {
> +	static const u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = {
>  		0x0100, 0x0200, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1900,
>  		0x2300,
>  		0x3200, 0x4700, 0x4701, 0x4702, 0x4703, 0x4704, 0x4705, 0x4706,
>  		0x4707
>  	};
>  
> -	u16 tbl_tx_iqlo_cal_startcoefs[] = {
> +	static const u16 tbl_tx_iqlo_cal_startcoefs[] = {
>  		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
>  		0x0000
>  	};
>  
> -	u16 tbl_tx_iqlo_cal_cmds_fullcal[] = {
> +	static const u16 tbl_tx_iqlo_cal_cmds_fullcal[] = {
>  		0x8123, 0x8264, 0x8086, 0x8245, 0x8056,
>  		0x9123, 0x9264, 0x9086, 0x9245, 0x9056
>  	};
>  
> -	u16 tbl_tx_iqlo_cal_cmds_recal[] = {
> +	static const u16 tbl_tx_iqlo_cal_cmds_recal[] = {
>  		0x8101, 0x8253, 0x8053, 0x8234, 0x8034,
>  		0x9101, 0x9253, 0x9053, 0x9234, 0x9034
>  	};
>  
> -	u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[] = {
> +	static const u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[] = {
>  		0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
>  		0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
>  		0x0000
>  	};
>  
> -	u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = {
> +	static const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = {
>  		0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234,
>  		0x9434, 0x9334, 0x9084, 0x9267, 0x9056, 0x9234
>  	};
>  
> -	u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = {
> +	static const u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = {
>  		0x8423, 0x8323, 0x8073, 0x8256, 0x8045, 0x8223,
>  		0x9423, 0x9323, 0x9073, 0x9256, 0x9045, 0x9223
>  	};
> 

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 09/26] brcmsmac: split up wlc_phy_workarounds_nphy
  2017-03-02 16:38 ` [PATCH 09/26] brcmsmac: split up wlc_phy_workarounds_nphy Arnd Bergmann
@ 2017-03-06  9:31   ` Arend Van Spriel
  0 siblings, 0 replies; 67+ messages in thread
From: Arend Van Spriel @ 2017-03-06  9:31 UTC (permalink / raw)
  To: Arnd Bergmann, kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller

On 2-3-2017 17:38, Arnd Bergmann wrote:
> The stack consumption in this driver is still relatively high, with one
> remaining warning if the warning level is lowered to 1536 bytes:
> 
> drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c:17135:1: error: the frame size of 1880 bytes is larger than 1536 bytes [-Werror=frame-larger-than=]
> 
> The affected function is actually a collection of three separate implementations,
> and each of them is fairly large by itself. Splitting them up is done easily
> and improves readability at the same time.
> 
> I'm leaving the original indentation to make the review easier.

Thanks ;-)

Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
>  .../broadcom/brcm80211/brcmsmac/phy/phy_n.c        | 178 ++++++++++++---------
>  1 file changed, 104 insertions(+), 74 deletions(-)
> 
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
> index 48a4df488d75..d76c092bb6b4 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
> @@ -16061,52 +16061,8 @@ static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi)
>  	}
>  }
>  
> -static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
> +static void wlc_phy_workarounds_nphy_rev7(struct brcms_phy *pi)
>  {
> -	static const u8 rfseq_rx2tx_events[] = {
> -		NPHY_RFSEQ_CMD_NOP,
> -		NPHY_RFSEQ_CMD_RXG_FBW,
> -		NPHY_RFSEQ_CMD_TR_SWITCH,
> -		NPHY_RFSEQ_CMD_CLR_HIQ_DIS,
> -		NPHY_RFSEQ_CMD_RXPD_TXPD,
> -		NPHY_RFSEQ_CMD_TX_GAIN,
> -		NPHY_RFSEQ_CMD_EXT_PA
> -	};
> -	u8 rfseq_rx2tx_dlys[] = { 8, 6, 6, 2, 4, 60, 1 };
> -	static const u8 rfseq_tx2rx_events[] = {
> -		NPHY_RFSEQ_CMD_NOP,
> -		NPHY_RFSEQ_CMD_EXT_PA,
> -		NPHY_RFSEQ_CMD_TX_GAIN,
> -		NPHY_RFSEQ_CMD_RXPD_TXPD,
> -		NPHY_RFSEQ_CMD_TR_SWITCH,
> -		NPHY_RFSEQ_CMD_RXG_FBW,
> -		NPHY_RFSEQ_CMD_CLR_HIQ_DIS
> -	};
> -	static const u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 };
> -	static const u8 rfseq_tx2rx_events_rev3[] = {
> -		NPHY_REV3_RFSEQ_CMD_EXT_PA,
> -		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
> -		NPHY_REV3_RFSEQ_CMD_TX_GAIN,
> -		NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
> -		NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
> -		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
> -		NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
> -		NPHY_REV3_RFSEQ_CMD_END
> -	};
> -	static const u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 };
> -	u8 rfseq_rx2tx_events_rev3[] = {
> -		NPHY_REV3_RFSEQ_CMD_NOP,
> -		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
> -		NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
> -		NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
> -		NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
> -		NPHY_REV3_RFSEQ_CMD_TX_GAIN,
> -		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
> -		NPHY_REV3_RFSEQ_CMD_EXT_PA,
> -		NPHY_REV3_RFSEQ_CMD_END
> -	};
> -	u8 rfseq_rx2tx_dlys_rev3[] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 };
> -
>  	static const u8 rfseq_rx2tx_events_rev3_ipa[] = {
>  		NPHY_REV3_RFSEQ_CMD_NOP,
>  		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
> @@ -16120,29 +16076,15 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
>  	};
>  	static const u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
>  	static const u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f };
> -
> -	s16 alpha0, alpha1, alpha2;
> -	s16 beta0, beta1, beta2;
> -	u32 leg_data_weights, ht_data_weights, nss1_data_weights,
> -	    stbc_data_weights;
> +	u32 leg_data_weights;
>  	u8 chan_freq_range = 0;
>  	static const u16 dac_control = 0x0002;
>  	u16 aux_adc_vmid_rev7_core0[] = { 0x8e, 0x96, 0x96, 0x96 };
>  	u16 aux_adc_vmid_rev7_core1[] = { 0x8f, 0x9f, 0x9f, 0x96 };
> -	u16 aux_adc_vmid_rev4[] = { 0xa2, 0xb4, 0xb4, 0x89 };
> -	u16 aux_adc_vmid_rev3[] = { 0xa2, 0xb4, 0xb4, 0x89 };
> -	u16 *aux_adc_vmid;
>  	u16 aux_adc_gain_rev7[] = { 0x02, 0x02, 0x02, 0x02 };
> -	u16 aux_adc_gain_rev4[] = { 0x02, 0x02, 0x02, 0x00 };
> -	u16 aux_adc_gain_rev3[] = { 0x02, 0x02, 0x02, 0x00 };
> -	u16 *aux_adc_gain;
> -	static const u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 };
> -	static const u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 };
>  	s32 min_nvar_val = 0x18d;
>  	s32 min_nvar_offset_6mbps = 20;
>  	u8 pdetrange;
> -	u8 triso;
> -	u16 regval;
>  	u16 afectrl_adc_ctrl1_rev7 = 0x20;
>  	u16 afectrl_adc_ctrl2_rev7 = 0x0;
>  	u16 rfseq_rx2tx_lpf_h_hpc_rev7 = 0x77;
> @@ -16171,17 +16113,6 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
>  	u16 freq;
>  	int coreNum;
>  
> -	if (CHSPEC_IS5G(pi->radio_chanspec))
> -		wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 0);
> -	else
> -		wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 1);
> -
> -	if (pi->phyhang_avoid)
> -		wlc_phy_stay_in_carriersearch_nphy(pi, true);
> -
> -	or_phy_reg(pi, 0xb1, NPHY_IQFlip_ADC1 | NPHY_IQFlip_ADC2);
> -
> -	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
>  
>  		if (NREV_IS(pi->pubpi.phy_rev, 7)) {
>  			mod_phy_reg(pi, 0x221, (0x1 << 4), (1 << 4));
> @@ -16703,8 +16634,62 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
>  					 &aux_adc_gain_rev7);
>  		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x1c, 16,
>  					 &aux_adc_gain_rev7);
> +}
>  
> -	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
> +static void wlc_phy_workarounds_nphy_rev3(struct brcms_phy *pi)
> +{
> +	static const u8 rfseq_tx2rx_events_rev3[] = {
> +		NPHY_REV3_RFSEQ_CMD_EXT_PA,
> +		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
> +		NPHY_REV3_RFSEQ_CMD_TX_GAIN,
> +		NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
> +		NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
> +		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
> +		NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
> +		NPHY_REV3_RFSEQ_CMD_END
> +	};
> +	static const u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 };
> +	u8 rfseq_rx2tx_events_rev3[] = {
> +		NPHY_REV3_RFSEQ_CMD_NOP,
> +		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
> +		NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
> +		NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
> +		NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
> +		NPHY_REV3_RFSEQ_CMD_TX_GAIN,
> +		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
> +		NPHY_REV3_RFSEQ_CMD_EXT_PA,
> +		NPHY_REV3_RFSEQ_CMD_END
> +	};
> +	u8 rfseq_rx2tx_dlys_rev3[] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 };
> +	static const u8 rfseq_rx2tx_events_rev3_ipa[] = {
> +		NPHY_REV3_RFSEQ_CMD_NOP,
> +		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
> +		NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
> +		NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
> +		NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
> +		NPHY_REV3_RFSEQ_CMD_TX_GAIN,
> +		NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS,
> +		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
> +		NPHY_REV3_RFSEQ_CMD_END
> +	};
> +	static const u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
> +	s16 alpha0, alpha1, alpha2;
> +	s16 beta0, beta1, beta2;
> +	u32 leg_data_weights, ht_data_weights, nss1_data_weights,
> +	    stbc_data_weights;
> +	u8 chan_freq_range = 0;
> +	static const u16 dac_control = 0x0002;
> +	u16 aux_adc_vmid_rev4[] = { 0xa2, 0xb4, 0xb4, 0x89 };
> +	u16 aux_adc_vmid_rev3[] = { 0xa2, 0xb4, 0xb4, 0x89 };
> +	u16 *aux_adc_vmid;
> +	u16 aux_adc_gain_rev4[] = { 0x02, 0x02, 0x02, 0x00 };
> +	u16 aux_adc_gain_rev3[] = { 0x02, 0x02, 0x02, 0x00 };
> +	u16 *aux_adc_gain;
> +	static const u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 };
> +	static const u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 };
> +	s32 min_nvar_val = 0x18d;
> +	u8 pdetrange;
> +	u8 triso;
>  
>  		write_phy_reg(pi, 0x23f, 0x1f8);
>  		write_phy_reg(pi, 0x240, 0x1f8);
> @@ -17030,7 +17015,33 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
>  					      MHF4_BPHY_TXCORE0,
>  					      MHF4_BPHY_TXCORE0, BRCM_BAND_ALL);
>  		}
> -	} else {
> +}
> +
> +void wlc_phy_workarounds_nphy_rev1(struct brcms_phy *pi)
> +{
> +	static const u8 rfseq_rx2tx_events[] = {
> +		NPHY_RFSEQ_CMD_NOP,
> +		NPHY_RFSEQ_CMD_RXG_FBW,
> +		NPHY_RFSEQ_CMD_TR_SWITCH,
> +		NPHY_RFSEQ_CMD_CLR_HIQ_DIS,
> +		NPHY_RFSEQ_CMD_RXPD_TXPD,
> +		NPHY_RFSEQ_CMD_TX_GAIN,
> +		NPHY_RFSEQ_CMD_EXT_PA
> +	};
> +	u8 rfseq_rx2tx_dlys[] = { 8, 6, 6, 2, 4, 60, 1 };
> +	static const u8 rfseq_tx2rx_events[] = {
> +		NPHY_RFSEQ_CMD_NOP,
> +		NPHY_RFSEQ_CMD_EXT_PA,
> +		NPHY_RFSEQ_CMD_TX_GAIN,
> +		NPHY_RFSEQ_CMD_RXPD_TXPD,
> +		NPHY_RFSEQ_CMD_TR_SWITCH,
> +		NPHY_RFSEQ_CMD_RXG_FBW,
> +		NPHY_RFSEQ_CMD_CLR_HIQ_DIS
> +	};
> +	static const u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 };
> +	s16 alpha0, alpha1, alpha2;
> +	s16 beta0, beta1, beta2;
> +	u16 regval;
>  
>  		if (pi->sh->boardflags2 & BFL2_SKWRKFEM_BRD ||
>  		    (pi->sh->boardtype == 0x8b)) {
> @@ -17128,7 +17139,26 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
>  			mod_phy_reg(pi, 0x221,
>  				    NPHY_FORCESIG_DECODEGATEDCLKS,
>  				    NPHY_FORCESIG_DECODEGATEDCLKS);
> -	}
> +}
> +
> +static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
> +{
> +	if (CHSPEC_IS5G(pi->radio_chanspec))
> +		wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 0);
> +	else
> +		wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 1);
> +
> +	if (pi->phyhang_avoid)
> +		wlc_phy_stay_in_carriersearch_nphy(pi, true);
> +
> +	or_phy_reg(pi, 0xb1, NPHY_IQFlip_ADC1 | NPHY_IQFlip_ADC2);
> +
> +	if (NREV_GE(pi->pubpi.phy_rev, 7))
> +		wlc_phy_workarounds_nphy_rev7(pi);
> +	else if (NREV_GE(pi->pubpi.phy_rev, 3))
> +		wlc_phy_workarounds_nphy_rev3(pi);
> +	else
> +		wlc_phy_workarounds_nphy_rev1(pi);
>  
>  	if (pi->phyhang_avoid)
>  		wlc_phy_stay_in_carriersearch_nphy(pi, false);
> 

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 10/26] brcmsmac: reindent split functions
  2017-03-02 16:38 ` [PATCH 10/26] brcmsmac: reindent split functions Arnd Bergmann
@ 2017-03-06  9:33   ` Arend Van Spriel
  2017-03-06 16:24     ` Kalle Valo
  0 siblings, 1 reply; 67+ messages in thread
From: Arend Van Spriel @ 2017-03-06  9:33 UTC (permalink / raw)
  To: Arnd Bergmann, kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller

On 2-3-2017 17:38, Arnd Bergmann wrote:
> In the previous commit I left the indentation alone to help reviewing
> the patch, this one now runs the three new functions through 'indent -kr -8'
> with some manual fixups to avoid silliness.
> 
> No changes other than whitespace are intended here.

Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
>  .../broadcom/brcm80211/brcmsmac/phy/phy_n.c        | 1507 +++++++++-----------
>  1 file changed, 697 insertions(+), 810 deletions(-)
> 
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
> index d76c092bb6b4..9b39789c673d 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
> @@ -16074,7 +16074,8 @@ static void wlc_phy_workarounds_nphy_rev7(struct brcms_phy *pi)
>  		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
>  		NPHY_REV3_RFSEQ_CMD_END
>  	};
> -	static const u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
> +	static const u8 rfseq_rx2tx_dlys_rev3_ipa[] =
> +		{ 8, 6, 6, 4, 4, 16, 43, 1, 1 };
>  	static const u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f };
>  	u32 leg_data_weights;
>  	u8 chan_freq_range = 0;
> @@ -16114,526 +16115,452 @@ static void wlc_phy_workarounds_nphy_rev7(struct brcms_phy *pi)
>  	int coreNum;
>  
>  
> -		if (NREV_IS(pi->pubpi.phy_rev, 7)) {
> -			mod_phy_reg(pi, 0x221, (0x1 << 4), (1 << 4));
> -
> -			mod_phy_reg(pi, 0x160, (0x7f << 0), (32 << 0));
> -			mod_phy_reg(pi, 0x160, (0x7f << 8), (39 << 8));
> -			mod_phy_reg(pi, 0x161, (0x7f << 0), (46 << 0));
> -			mod_phy_reg(pi, 0x161, (0x7f << 8), (51 << 8));
> -			mod_phy_reg(pi, 0x162, (0x7f << 0), (55 << 0));
> -			mod_phy_reg(pi, 0x162, (0x7f << 8), (58 << 8));
> -			mod_phy_reg(pi, 0x163, (0x7f << 0), (60 << 0));
> -			mod_phy_reg(pi, 0x163, (0x7f << 8), (62 << 8));
> -			mod_phy_reg(pi, 0x164, (0x7f << 0), (62 << 0));
> -			mod_phy_reg(pi, 0x164, (0x7f << 8), (63 << 8));
> -			mod_phy_reg(pi, 0x165, (0x7f << 0), (63 << 0));
> -			mod_phy_reg(pi, 0x165, (0x7f << 8), (64 << 8));
> -			mod_phy_reg(pi, 0x166, (0x7f << 0), (64 << 0));
> -			mod_phy_reg(pi, 0x166, (0x7f << 8), (64 << 8));
> -			mod_phy_reg(pi, 0x167, (0x7f << 0), (64 << 0));
> -			mod_phy_reg(pi, 0x167, (0x7f << 8), (64 << 8));
> -		}
> -
> -		if (NREV_LE(pi->pubpi.phy_rev, 8)) {
> -			write_phy_reg(pi, 0x23f, 0x1b0);
> -			write_phy_reg(pi, 0x240, 0x1b0);
> -		}
> +	if (NREV_IS(pi->pubpi.phy_rev, 7)) {
> +		mod_phy_reg(pi, 0x221, (0x1 << 4), (1 << 4));
> +
> +		mod_phy_reg(pi, 0x160, (0x7f << 0), (32 << 0));
> +		mod_phy_reg(pi, 0x160, (0x7f << 8), (39 << 8));
> +		mod_phy_reg(pi, 0x161, (0x7f << 0), (46 << 0));
> +		mod_phy_reg(pi, 0x161, (0x7f << 8), (51 << 8));
> +		mod_phy_reg(pi, 0x162, (0x7f << 0), (55 << 0));
> +		mod_phy_reg(pi, 0x162, (0x7f << 8), (58 << 8));
> +		mod_phy_reg(pi, 0x163, (0x7f << 0), (60 << 0));
> +		mod_phy_reg(pi, 0x163, (0x7f << 8), (62 << 8));
> +		mod_phy_reg(pi, 0x164, (0x7f << 0), (62 << 0));
> +		mod_phy_reg(pi, 0x164, (0x7f << 8), (63 << 8));
> +		mod_phy_reg(pi, 0x165, (0x7f << 0), (63 << 0));
> +		mod_phy_reg(pi, 0x165, (0x7f << 8), (64 << 8));
> +		mod_phy_reg(pi, 0x166, (0x7f << 0), (64 << 0));
> +		mod_phy_reg(pi, 0x166, (0x7f << 8), (64 << 8));
> +		mod_phy_reg(pi, 0x167, (0x7f << 0), (64 << 0));
> +		mod_phy_reg(pi, 0x167, (0x7f << 8), (64 << 8));
> +	}
>  
> -		if (NREV_GE(pi->pubpi.phy_rev, 8))
> -			mod_phy_reg(pi, 0xbd, (0xff << 0), (114 << 0));
> +	if (NREV_LE(pi->pubpi.phy_rev, 8)) {
> +		write_phy_reg(pi, 0x23f, 0x1b0);
> +		write_phy_reg(pi, 0x240, 0x1b0);
> +	}
>  
> -		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16,
> -					 &dac_control);
> -		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x10, 16,
> -					 &dac_control);
> +	if (NREV_GE(pi->pubpi.phy_rev, 8))
> +		mod_phy_reg(pi, 0xbd, (0xff << 0), (114 << 0));
>  
> -		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
> -					1, 0, 32, &leg_data_weights);
> -		leg_data_weights = leg_data_weights & 0xffffff;
> -		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
> -					 1, 0, 32, &leg_data_weights);
> +	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16,
> +				 &dac_control);
> +	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x10, 16,
> +				 &dac_control);
>  
> -		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
> -					 2, 0x15e, 16,
> -					 rfseq_rx2tx_dacbufpu_rev7);
> -		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x16e, 16,
> -					 rfseq_rx2tx_dacbufpu_rev7);
> +	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
> +				1, 0, 32, &leg_data_weights);
> +	leg_data_weights = leg_data_weights & 0xffffff;
> +	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
> +				 1, 0, 32, &leg_data_weights);
>  
> -		if (PHY_IPA(pi))
> -			wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
> -					       rfseq_rx2tx_events_rev3_ipa,
> -					       rfseq_rx2tx_dlys_rev3_ipa,
> -					       ARRAY_SIZE(rfseq_rx2tx_events_rev3_ipa));
> +	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
> +				 2, 0x15e, 16, rfseq_rx2tx_dacbufpu_rev7);
> +	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x16e, 16,
> +				 rfseq_rx2tx_dacbufpu_rev7);
>  
> -		mod_phy_reg(pi, 0x299, (0x3 << 14), (0x1 << 14));
> -		mod_phy_reg(pi, 0x29d, (0x3 << 14), (0x1 << 14));
> +	if (PHY_IPA(pi))
> +		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
> +				       rfseq_rx2tx_events_rev3_ipa,
> +				       rfseq_rx2tx_dlys_rev3_ipa,
> +				       ARRAY_SIZE
> +				       (rfseq_rx2tx_events_rev3_ipa));
>  
> -		tx_lpf_bw_ofdm_20mhz = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x154);
> -		tx_lpf_bw_ofdm_40mhz = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x159);
> -		tx_lpf_bw_11b = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x152);
> +	mod_phy_reg(pi, 0x299, (0x3 << 14), (0x1 << 14));
> +	mod_phy_reg(pi, 0x29d, (0x3 << 14), (0x1 << 14));
>  
> -		if (PHY_IPA(pi)) {
> +	tx_lpf_bw_ofdm_20mhz = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x154);
> +	tx_lpf_bw_ofdm_40mhz = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x159);
> +	tx_lpf_bw_11b = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x152);
>  
> -			if (((pi->pubpi.radiorev == 5)
> -			     && (CHSPEC_IS40(pi->radio_chanspec) == 1))
> -			    || (pi->pubpi.radiorev == 7)
> -			    || (pi->pubpi.radiorev == 8)) {
> +	if (PHY_IPA(pi)) {
>  
> -				rccal_bcap_val =
> -					read_radio_reg(
> -						pi,
> -						RADIO_2057_RCCAL_BCAP_VAL);
> -				rccal_scap_val =
> -					read_radio_reg(
> -						pi,
> -						RADIO_2057_RCCAL_SCAP_VAL);
> +		if (((pi->pubpi.radiorev == 5)
> +		     && (CHSPEC_IS40(pi->radio_chanspec) == 1))
> +		    || (pi->pubpi.radiorev == 7)
> +		    || (pi->pubpi.radiorev == 8)) {
>  
> -				rccal_tx20_11b_bcap = rccal_bcap_val;
> -				rccal_tx20_11b_scap = rccal_scap_val;
> +			rccal_bcap_val =
> +			    read_radio_reg(pi, RADIO_2057_RCCAL_BCAP_VAL);
> +			rccal_scap_val =
> +			    read_radio_reg(pi, RADIO_2057_RCCAL_SCAP_VAL);
>  
> -				if ((pi->pubpi.radiorev == 5) &&
> -				    (CHSPEC_IS40(pi->radio_chanspec) == 1)) {
> +			rccal_tx20_11b_bcap = rccal_bcap_val;
> +			rccal_tx20_11b_scap = rccal_scap_val;
>  
> -					rccal_tx20_11n_bcap = rccal_bcap_val;
> -					rccal_tx20_11n_scap = rccal_scap_val;
> -					rccal_tx40_11n_bcap = 0xc;
> -					rccal_tx40_11n_scap = 0xc;
> +			if ((pi->pubpi.radiorev == 5) &&
> +			    (CHSPEC_IS40(pi->radio_chanspec) == 1)) {
>  
> -					rccal_ovrd = true;
> +				rccal_tx20_11n_bcap = rccal_bcap_val;
> +				rccal_tx20_11n_scap = rccal_scap_val;
> +				rccal_tx40_11n_bcap = 0xc;
> +				rccal_tx40_11n_scap = 0xc;
>  
> -				} else if ((pi->pubpi.radiorev == 7)
> -					   || (pi->pubpi.radiorev == 8)) {
> +				rccal_ovrd = true;
>  
> -					tx_lpf_bw_ofdm_20mhz = 4;
> -					tx_lpf_bw_11b = 1;
> +			} else if ((pi->pubpi.radiorev == 7)
> +				   || (pi->pubpi.radiorev == 8)) {
>  
> -					if (CHSPEC_IS2G(pi->radio_chanspec)) {
> -						rccal_tx20_11n_bcap = 0xc;
> -						rccal_tx20_11n_scap = 0xc;
> -						rccal_tx40_11n_bcap = 0xa;
> -						rccal_tx40_11n_scap = 0xa;
> -					} else {
> -						rccal_tx20_11n_bcap = 0x14;
> -						rccal_tx20_11n_scap = 0x14;
> -						rccal_tx40_11n_bcap = 0xf;
> -						rccal_tx40_11n_scap = 0xf;
> -					}
> +				tx_lpf_bw_ofdm_20mhz = 4;
> +				tx_lpf_bw_11b = 1;
>  
> -					rccal_ovrd = true;
> +				if (CHSPEC_IS2G(pi->radio_chanspec)) {
> +					rccal_tx20_11n_bcap = 0xc;
> +					rccal_tx20_11n_scap = 0xc;
> +					rccal_tx40_11n_bcap = 0xa;
> +					rccal_tx40_11n_scap = 0xa;
> +				} else {
> +					rccal_tx20_11n_bcap = 0x14;
> +					rccal_tx20_11n_scap = 0x14;
> +					rccal_tx40_11n_bcap = 0xf;
> +					rccal_tx40_11n_scap = 0xf;
>  				}
> +
> +				rccal_ovrd = true;
>  			}
> +		}
>  
> -		} else {
> +	} else {
>  
> -			if (pi->pubpi.radiorev == 5) {
> +		if (pi->pubpi.radiorev == 5) {
>  
> -				tx_lpf_bw_ofdm_20mhz = 1;
> -				tx_lpf_bw_ofdm_40mhz = 3;
> +			tx_lpf_bw_ofdm_20mhz = 1;
> +			tx_lpf_bw_ofdm_40mhz = 3;
>  
> -				rccal_bcap_val =
> -					read_radio_reg(
> -						pi,
> -						RADIO_2057_RCCAL_BCAP_VAL);
> -				rccal_scap_val =
> -					read_radio_reg(
> -						pi,
> -						RADIO_2057_RCCAL_SCAP_VAL);
> +			rccal_bcap_val =
> +			    read_radio_reg(pi, RADIO_2057_RCCAL_BCAP_VAL);
> +			rccal_scap_val =
> +			    read_radio_reg(pi, RADIO_2057_RCCAL_SCAP_VAL);
>  
> -				rccal_tx20_11b_bcap = rccal_bcap_val;
> -				rccal_tx20_11b_scap = rccal_scap_val;
> +			rccal_tx20_11b_bcap = rccal_bcap_val;
> +			rccal_tx20_11b_scap = rccal_scap_val;
>  
> -				rccal_tx20_11n_bcap = 0x13;
> -				rccal_tx20_11n_scap = 0x11;
> -				rccal_tx40_11n_bcap = 0x13;
> -				rccal_tx40_11n_scap = 0x11;
> +			rccal_tx20_11n_bcap = 0x13;
> +			rccal_tx20_11n_scap = 0x11;
> +			rccal_tx40_11n_bcap = 0x13;
> +			rccal_tx40_11n_scap = 0x11;
>  
> -				rccal_ovrd = true;
> -			}
> +			rccal_ovrd = true;
>  		}
> +	}
>  
> -		if (rccal_ovrd) {
> -
> -			rx2tx_lpf_rc_lut_tx20_11b =
> -				(rccal_tx20_11b_bcap << 8) |
> -				(rccal_tx20_11b_scap << 3) |
> -				tx_lpf_bw_11b;
> -			rx2tx_lpf_rc_lut_tx20_11n =
> -				(rccal_tx20_11n_bcap << 8) |
> -				(rccal_tx20_11n_scap << 3) |
> -				tx_lpf_bw_ofdm_20mhz;
> -			rx2tx_lpf_rc_lut_tx40_11n =
> -				(rccal_tx40_11n_bcap << 8) |
> -				(rccal_tx40_11n_scap << 3) |
> -				tx_lpf_bw_ofdm_40mhz;
> +	if (rccal_ovrd) {
>  
> -			for (coreNum = 0; coreNum <= 1; coreNum++) {
> -				wlc_phy_table_write_nphy(
> -					pi, NPHY_TBL_ID_RFSEQ,
> -					1,
> -					0x152 + coreNum * 0x10,
> -					16,
> -					&rx2tx_lpf_rc_lut_tx20_11b);
> -				wlc_phy_table_write_nphy(
> -					pi, NPHY_TBL_ID_RFSEQ,
> -					1,
> -					0x153 + coreNum * 0x10,
> -					16,
> -					&rx2tx_lpf_rc_lut_tx20_11n);
> -				wlc_phy_table_write_nphy(
> -					pi, NPHY_TBL_ID_RFSEQ,
> -					1,
> -					0x154 + coreNum * 0x10,
> -					16,
> -					&rx2tx_lpf_rc_lut_tx20_11n);
> -				wlc_phy_table_write_nphy(
> -					pi, NPHY_TBL_ID_RFSEQ,
> -					1,
> -					0x155 + coreNum * 0x10,
> -					16,
> -					&rx2tx_lpf_rc_lut_tx40_11n);
> -				wlc_phy_table_write_nphy(
> -					pi, NPHY_TBL_ID_RFSEQ,
> -					1,
> -					0x156 + coreNum * 0x10,
> -					16,
> -					&rx2tx_lpf_rc_lut_tx40_11n);
> -				wlc_phy_table_write_nphy(
> -					pi, NPHY_TBL_ID_RFSEQ,
> -					1,
> -					0x157 + coreNum * 0x10,
> -					16,
> -					&rx2tx_lpf_rc_lut_tx40_11n);
> -				wlc_phy_table_write_nphy(
> -					pi, NPHY_TBL_ID_RFSEQ,
> -					1,
> -					0x158 + coreNum * 0x10,
> -					16,
> -					&rx2tx_lpf_rc_lut_tx40_11n);
> -				wlc_phy_table_write_nphy(
> -					pi, NPHY_TBL_ID_RFSEQ,
> -					1,
> -					0x159 + coreNum * 0x10,
> -					16,
> -					&rx2tx_lpf_rc_lut_tx40_11n);
> -			}
> +		rx2tx_lpf_rc_lut_tx20_11b =
> +		    (rccal_tx20_11b_bcap << 8) |
> +		    (rccal_tx20_11b_scap << 3) | tx_lpf_bw_11b;
> +		rx2tx_lpf_rc_lut_tx20_11n =
> +		    (rccal_tx20_11n_bcap << 8) |
> +		    (rccal_tx20_11n_scap << 3) | tx_lpf_bw_ofdm_20mhz;
> +		rx2tx_lpf_rc_lut_tx40_11n =
> +		    (rccal_tx40_11n_bcap << 8) |
> +		    (rccal_tx40_11n_scap << 3) | tx_lpf_bw_ofdm_40mhz;
>  
> -			wlc_phy_rfctrl_override_nphy_rev7(
> -				pi, (0x1 << 4),
> -				1, 0x3, 0,
> -				NPHY_REV7_RFCTRLOVERRIDE_ID2);
> +		for (coreNum = 0; coreNum <= 1; coreNum++) {
> +			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
> +						 0x152 + coreNum * 0x10, 16,
> +						 &rx2tx_lpf_rc_lut_tx20_11b);
> +			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
> +						 0x153 + coreNum * 0x10, 16,
> +						 &rx2tx_lpf_rc_lut_tx20_11n);
> +			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
> +						 0x154 + coreNum * 0x10, 16,
> +						 &rx2tx_lpf_rc_lut_tx20_11n);
> +			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
> +						 0x155 + coreNum * 0x10, 16,
> +						 &rx2tx_lpf_rc_lut_tx40_11n);
> +			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
> +						 0x156 + coreNum * 0x10, 16,
> +						 &rx2tx_lpf_rc_lut_tx40_11n);
> +			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
> +						 0x157 + coreNum * 0x10, 16,
> +						 &rx2tx_lpf_rc_lut_tx40_11n);
> +			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
> +						 0x158 + coreNum * 0x10, 16,
> +						 &rx2tx_lpf_rc_lut_tx40_11n);
> +			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
> +						 0x159 + coreNum * 0x10, 16,
> +						 &rx2tx_lpf_rc_lut_tx40_11n);
>  		}
>  
> -		write_phy_reg(pi, 0x32f, 0x3);
> +		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 1, 0x3, 0,
> +						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
> +	}
>  
> -		if ((pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6))
> -			wlc_phy_rfctrl_override_nphy_rev7(
> -				pi, (0x1 << 2),
> -				1, 0x3, 0,
> -				NPHY_REV7_RFCTRLOVERRIDE_ID0);
> +	write_phy_reg(pi, 0x32f, 0x3);
>  
> -		if ((pi->pubpi.radiorev == 3) || (pi->pubpi.radiorev == 4) ||
> -		    (pi->pubpi.radiorev == 6)) {
> -			if ((pi->sh->sromrev >= 8)
> -			    && (pi->sh->boardflags2 & BFL2_IPALVLSHIFT_3P3))
> -				ipalvlshift_3p3_war_en = 1;
> -
> -			if (ipalvlshift_3p3_war_en) {
> -				write_radio_reg(pi, RADIO_2057_GPAIO_CONFIG,
> -						0x5);
> -				write_radio_reg(pi, RADIO_2057_GPAIO_SEL1,
> -						0x30);
> -				write_radio_reg(pi, RADIO_2057_GPAIO_SEL0, 0x0);
> -				or_radio_reg(pi,
> -					     RADIO_2057_RXTXBIAS_CONFIG_CORE0,
> -					     0x1);
> -				or_radio_reg(pi,
> -					     RADIO_2057_RXTXBIAS_CONFIG_CORE1,
> -					     0x1);
> -
> -				ipa2g_mainbias = 0x1f;
> -
> -				ipa2g_casconv = 0x6f;
> -
> -				ipa2g_biasfilt = 0xaa;
> -			} else {
> +	if ((pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6))
> +		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 1, 0x3, 0,
> +						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
>  
> -				ipa2g_mainbias = 0x2b;
> +	if ((pi->pubpi.radiorev == 3) || (pi->pubpi.radiorev == 4) ||
> +	    (pi->pubpi.radiorev == 6)) {
> +		if ((pi->sh->sromrev >= 8)
> +		    && (pi->sh->boardflags2 & BFL2_IPALVLSHIFT_3P3))
> +			ipalvlshift_3p3_war_en = 1;
>  
> -				ipa2g_casconv = 0x7f;
> +		if (ipalvlshift_3p3_war_en) {
> +			write_radio_reg(pi, RADIO_2057_GPAIO_CONFIG, 0x5);
> +			write_radio_reg(pi, RADIO_2057_GPAIO_SEL1, 0x30);
> +			write_radio_reg(pi, RADIO_2057_GPAIO_SEL0, 0x0);
> +			or_radio_reg(pi, RADIO_2057_RXTXBIAS_CONFIG_CORE0, 0x1);
> +			or_radio_reg(pi, RADIO_2057_RXTXBIAS_CONFIG_CORE1, 0x1);
>  
> -				ipa2g_biasfilt = 0xee;
> -			}
> +			ipa2g_mainbias = 0x1f;
>  
> -			if (CHSPEC_IS2G(pi->radio_chanspec)) {
> -				for (coreNum = 0; coreNum <= 1; coreNum++) {
> -					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
> -							 coreNum, IPA2G_IMAIN,
> -							 ipa2g_mainbias);
> -					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
> -							 coreNum, IPA2G_CASCONV,
> -							 ipa2g_casconv);
> -					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
> -							 coreNum,
> -							 IPA2G_BIAS_FILTER,
> -							 ipa2g_biasfilt);
> -				}
> -			}
> -		}
> +			ipa2g_casconv = 0x6f;
>  
> -		if (PHY_IPA(pi)) {
> -			if (CHSPEC_IS2G(pi->radio_chanspec)) {
> -				if ((pi->pubpi.radiorev == 3)
> -				    || (pi->pubpi.radiorev == 4)
> -				    || (pi->pubpi.radiorev == 6))
> -					txgm_idac_bleed = 0x7f;
> +			ipa2g_biasfilt = 0xaa;
> +		} else {
>  
> -				for (coreNum = 0; coreNum <= 1; coreNum++) {
> -					if (txgm_idac_bleed != 0)
> -						WRITE_RADIO_REG4(
> -							pi, RADIO_2057,
> -							CORE, coreNum,
> -							TXGM_IDAC_BLEED,
> -							txgm_idac_bleed);
> -				}
> +			ipa2g_mainbias = 0x2b;
>  
> -				if (pi->pubpi.radiorev == 5) {
> -
> -					for (coreNum = 0; coreNum <= 1;
> -					     coreNum++) {
> -						WRITE_RADIO_REG4(pi, RADIO_2057,
> -								 CORE, coreNum,
> -								 IPA2G_CASCONV,
> -								 0x13);
> -						WRITE_RADIO_REG4(pi, RADIO_2057,
> -								 CORE, coreNum,
> -								 IPA2G_IMAIN,
> -								 0x1f);
> -						WRITE_RADIO_REG4(
> -							pi, RADIO_2057,
> -							CORE, coreNum,
> -							IPA2G_BIAS_FILTER,
> -							0xee);
> -						WRITE_RADIO_REG4(pi, RADIO_2057,
> -								 CORE, coreNum,
> -								 PAD2G_IDACS,
> -								 0x8a);
> -						WRITE_RADIO_REG4(
> -							pi, RADIO_2057,
> -							CORE, coreNum,
> -							PAD_BIAS_FILTER_BWS,
> -							0x3e);
> -					}
> +			ipa2g_casconv = 0x7f;
>  
> -				} else if ((pi->pubpi.radiorev == 7)
> -					   || (pi->pubpi.radiorev == 8)) {
> +			ipa2g_biasfilt = 0xee;
> +		}
>  
> -					if (CHSPEC_IS40(pi->radio_chanspec) ==
> -					    0) {
> -						WRITE_RADIO_REG4(pi, RADIO_2057,
> -								 CORE, 0,
> -								 IPA2G_IMAIN,
> -								 0x14);
> -						WRITE_RADIO_REG4(pi, RADIO_2057,
> -								 CORE, 1,
> -								 IPA2G_IMAIN,
> -								 0x12);
> -					} else {
> -						WRITE_RADIO_REG4(pi, RADIO_2057,
> -								 CORE, 0,
> -								 IPA2G_IMAIN,
> -								 0x16);
> -						WRITE_RADIO_REG4(pi, RADIO_2057,
> -								 CORE, 1,
> -								 IPA2G_IMAIN,
> -								 0x16);
> -					}
> -				}
> +		if (CHSPEC_IS2G(pi->radio_chanspec)) {
> +			for (coreNum = 0; coreNum <= 1; coreNum++) {
> +				WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
> +						 coreNum, IPA2G_IMAIN,
> +						 ipa2g_mainbias);
> +				WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
> +						 coreNum, IPA2G_CASCONV,
> +						 ipa2g_casconv);
> +				WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
> +						 coreNum,
> +						 IPA2G_BIAS_FILTER,
> +						 ipa2g_biasfilt);
> +			}
> +		}
> +	}
>  
> -			} else {
> -				freq = CHAN5G_FREQ(CHSPEC_CHANNEL(
> -							pi->radio_chanspec));
> -				if (((freq >= 5180) && (freq <= 5230))
> -				    || ((freq >= 5745) && (freq <= 5805))) {
> -					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
> -							 0, IPA5G_BIAS_FILTER,
> -							 0xff);
> -					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
> -							 1, IPA5G_BIAS_FILTER,
> -							 0xff);
> -				}
> +	if (PHY_IPA(pi)) {
> +		if (CHSPEC_IS2G(pi->radio_chanspec)) {
> +			if ((pi->pubpi.radiorev == 3)
> +			    || (pi->pubpi.radiorev == 4)
> +			    || (pi->pubpi.radiorev == 6))
> +				txgm_idac_bleed = 0x7f;
> +
> +			for (coreNum = 0; coreNum <= 1; coreNum++) {
> +				if (txgm_idac_bleed != 0)
> +					WRITE_RADIO_REG4(pi, RADIO_2057,
> +							 CORE, coreNum,
> +							 TXGM_IDAC_BLEED,
> +							 txgm_idac_bleed);
>  			}
> -		} else {
>  
> -			if (pi->pubpi.radiorev != 5) {
> +			if (pi->pubpi.radiorev == 5) {
>  				for (coreNum = 0; coreNum <= 1; coreNum++) {
> +					WRITE_RADIO_REG4(pi, RADIO_2057,
> +							 CORE, coreNum,
> +							 IPA2G_CASCONV,
> +							 0x13);
> +					WRITE_RADIO_REG4(pi, RADIO_2057,
> +							 CORE, coreNum,
> +							 IPA2G_IMAIN,
> +							 0x1f);
> +					WRITE_RADIO_REG4(pi, RADIO_2057,
> +							 CORE, coreNum,
> +							 IPA2G_BIAS_FILTER,
> +							 0xee);
> +					WRITE_RADIO_REG4(pi, RADIO_2057,
> +							 CORE, coreNum,
> +							 PAD2G_IDACS,
> +							 0x8a);
> +					WRITE_RADIO_REG4(pi, RADIO_2057,
> +							 CORE, coreNum,
> +							 PAD_BIAS_FILTER_BWS,
> +							 0x3e);
> +				}
> +			} else if ((pi->pubpi.radiorev == 7) ||
> +				   (pi->pubpi.radiorev == 8)) {
> +
> +				if (CHSPEC_IS40(pi->radio_chanspec) == 0) {
> +					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
> +							 0, IPA2G_IMAIN, 0x14);
> +					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
> +							 1, IPA2G_IMAIN, 0x12);
> +				} else {
>  					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
> -							 coreNum,
> -							 TXMIX2G_TUNE_BOOST_PU,
> -							 0x61);
> +							 0, IPA2G_IMAIN, 0x16);
>  					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
> -							 coreNum,
> -							 TXGM_IDAC_BLEED, 0x70);
> +							 1, IPA2G_IMAIN, 0x16);
>  				}
>  			}
> -		}
>  
> -		if (pi->pubpi.radiorev == 4) {
> -			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
> -						 0x05, 16,
> -						 &afectrl_adc_ctrl1_rev7);
> -			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
> -						 0x15, 16,
> -						 &afectrl_adc_ctrl1_rev7);
> +		} else {
> +			freq =
> +			    CHAN5G_FREQ(CHSPEC_CHANNEL
> +					(pi->radio_chanspec));
> +			if (((freq >= 5180) && (freq <= 5230))
> +			    || ((freq >= 5745) && (freq <= 5805))) {
> +				WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
> +						 0, IPA5G_BIAS_FILTER, 0xff);
> +				WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
> +						 1, IPA5G_BIAS_FILTER, 0xff);
> +			}
> +		}
> +	} else {
>  
> +		if (pi->pubpi.radiorev != 5) {
>  			for (coreNum = 0; coreNum <= 1; coreNum++) {
>  				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
> -						 AFE_VCM_CAL_MASTER, 0x0);
> -				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
> -						 AFE_SET_VCM_I, 0x3f);
> +						 TXMIX2G_TUNE_BOOST_PU, 0x61);
>  				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
> -						 AFE_SET_VCM_Q, 0x3f);
> +						 TXGM_IDAC_BLEED, 0x70);
>  			}
> -		} else {
> -			mod_phy_reg(pi, 0xa6, (0x1 << 2), (0x1 << 2));
> -			mod_phy_reg(pi, 0x8f, (0x1 << 2), (0x1 << 2));
> -			mod_phy_reg(pi, 0xa7, (0x1 << 2), (0x1 << 2));
> -			mod_phy_reg(pi, 0xa5, (0x1 << 2), (0x1 << 2));
> -
> -			mod_phy_reg(pi, 0xa6, (0x1 << 0), 0);
> -			mod_phy_reg(pi, 0x8f, (0x1 << 0), (0x1 << 0));
> -			mod_phy_reg(pi, 0xa7, (0x1 << 0), 0);
> -			mod_phy_reg(pi, 0xa5, (0x1 << 0), (0x1 << 0));
> -
> -			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
> -						 0x05, 16,
> -						 &afectrl_adc_ctrl2_rev7);
> -			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
> -						 0x15, 16,
> -						 &afectrl_adc_ctrl2_rev7);
> -
> -			mod_phy_reg(pi, 0xa6, (0x1 << 2), 0);
> -			mod_phy_reg(pi, 0x8f, (0x1 << 2), 0);
> -			mod_phy_reg(pi, 0xa7, (0x1 << 2), 0);
> -			mod_phy_reg(pi, 0xa5, (0x1 << 2), 0);
>  		}
> +	}
>  
> -		write_phy_reg(pi, 0x6a, 0x2);
> +	if (pi->pubpi.radiorev == 4) {
> +		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x05, 16,
> +					 &afectrl_adc_ctrl1_rev7);
> +		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x15, 16,
> +					 &afectrl_adc_ctrl1_rev7);
>  
> -		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 256, 32,
> -					 &min_nvar_offset_6mbps);
> +		for (coreNum = 0; coreNum <= 1; coreNum++) {
> +			WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
> +					 AFE_VCM_CAL_MASTER, 0x0);
> +			WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
> +					 AFE_SET_VCM_I, 0x3f);
> +			WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
> +					 AFE_SET_VCM_Q, 0x3f);
> +		}
> +	} else {
> +		mod_phy_reg(pi, 0xa6, (0x1 << 2), (0x1 << 2));
> +		mod_phy_reg(pi, 0x8f, (0x1 << 2), (0x1 << 2));
> +		mod_phy_reg(pi, 0xa7, (0x1 << 2), (0x1 << 2));
> +		mod_phy_reg(pi, 0xa5, (0x1 << 2), (0x1 << 2));
>  
> -		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x138, 16,
> -					 &rfseq_pktgn_lpf_hpc_rev7);
> +		mod_phy_reg(pi, 0xa6, (0x1 << 0), 0);
> +		mod_phy_reg(pi, 0x8f, (0x1 << 0), (0x1 << 0));
> +		mod_phy_reg(pi, 0xa7, (0x1 << 0), 0);
> +		mod_phy_reg(pi, 0xa5, (0x1 << 0), (0x1 << 0));
>  
> -		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x141, 16,
> -					 &rfseq_pktgn_lpf_h_hpc_rev7);
> +		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x05, 16,
> +					 &afectrl_adc_ctrl2_rev7);
> +		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x15, 16,
> +					 &afectrl_adc_ctrl2_rev7);
>  
> -		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 3, 0x133, 16,
> -					 &rfseq_htpktgn_lpf_hpc_rev7);
> +		mod_phy_reg(pi, 0xa6, (0x1 << 2), 0);
> +		mod_phy_reg(pi, 0x8f, (0x1 << 2), 0);
> +		mod_phy_reg(pi, 0xa7, (0x1 << 2), 0);
> +		mod_phy_reg(pi, 0xa5, (0x1 << 2), 0);
> +	}
>  
> -		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x146, 16,
> -					 &rfseq_cckpktgn_lpf_hpc_rev7);
> +	write_phy_reg(pi, 0x6a, 0x2);
>  
> -		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x123, 16,
> -					 &rfseq_tx2rx_lpf_h_hpc_rev7);
> +	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 256, 32,
> +				 &min_nvar_offset_6mbps);
>  
> -		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x12A, 16,
> -					 &rfseq_rx2tx_lpf_h_hpc_rev7);
> +	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x138, 16,
> +				 &rfseq_pktgn_lpf_hpc_rev7);
>  
> -		if (CHSPEC_IS40(pi->radio_chanspec) == 0) {
> -			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
> -						 32, &min_nvar_val);
> -			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
> -						 127, 32, &min_nvar_val);
> -		} else {
> -			min_nvar_val = noise_var_tbl_rev7[3];
> -			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
> -						 32, &min_nvar_val);
> +	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x141, 16,
> +				 &rfseq_pktgn_lpf_h_hpc_rev7);
>  
> -			min_nvar_val = noise_var_tbl_rev7[127];
> -			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
> -						 127, 32, &min_nvar_val);
> -		}
> +	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 3, 0x133, 16,
> +				 &rfseq_htpktgn_lpf_hpc_rev7);
>  
> -		wlc_phy_workarounds_nphy_gainctrl(pi);
> +	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x146, 16,
> +				 &rfseq_cckpktgn_lpf_hpc_rev7);
>  
> -		pdetrange =
> -			(CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
> -			pdetrange : pi->srom_fem2g.pdetrange;
> +	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x123, 16,
> +				 &rfseq_tx2rx_lpf_h_hpc_rev7);
>  
> -		if (pdetrange == 0) {
> -			chan_freq_range =
> -				wlc_phy_get_chan_freq_range_nphy(pi, 0);
> -			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
> -				aux_adc_vmid_rev7_core0[3] = 0x70;
> -				aux_adc_vmid_rev7_core1[3] = 0x70;
> -				aux_adc_gain_rev7[3] = 2;
> -			} else {
> -				aux_adc_vmid_rev7_core0[3] = 0x80;
> -				aux_adc_vmid_rev7_core1[3] = 0x80;
> -				aux_adc_gain_rev7[3] = 3;
> -			}
> -		} else if (pdetrange == 1) {
> -			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
> -				aux_adc_vmid_rev7_core0[3] = 0x7c;
> -				aux_adc_vmid_rev7_core1[3] = 0x7c;
> -				aux_adc_gain_rev7[3] = 2;
> -			} else {
> -				aux_adc_vmid_rev7_core0[3] = 0x8c;
> -				aux_adc_vmid_rev7_core1[3] = 0x8c;
> -				aux_adc_gain_rev7[3] = 1;
> -			}
> -		} else if (pdetrange == 2) {
> -			if (pi->pubpi.radioid == BCM2057_ID) {
> -				if ((pi->pubpi.radiorev == 5)
> -				    || (pi->pubpi.radiorev == 7)
> -				    || (pi->pubpi.radiorev == 8)) {
> -					if (chan_freq_range ==
> -					    WL_CHAN_FREQ_RANGE_2G) {
> -						aux_adc_vmid_rev7_core0[3] =
> -							0x8c;
> -						aux_adc_vmid_rev7_core1[3] =
> -							0x8c;
> -						aux_adc_gain_rev7[3] = 0;
> -					} else {
> -						aux_adc_vmid_rev7_core0[3] =
> -							0x96;
> -						aux_adc_vmid_rev7_core1[3] =
> -							0x96;
> -						aux_adc_gain_rev7[3] = 0;
> -					}
> +	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x12A, 16,
> +				 &rfseq_rx2tx_lpf_h_hpc_rev7);
> +
> +	if (CHSPEC_IS40(pi->radio_chanspec) == 0) {
> +		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
> +					 32, &min_nvar_val);
> +		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
> +					 127, 32, &min_nvar_val);
> +	} else {
> +		min_nvar_val = noise_var_tbl_rev7[3];
> +		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
> +					 32, &min_nvar_val);
> +
> +		min_nvar_val = noise_var_tbl_rev7[127];
> +		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
> +					 127, 32, &min_nvar_val);
> +	}
> +
> +	wlc_phy_workarounds_nphy_gainctrl(pi);
> +
> +	pdetrange = (CHSPEC_IS5G(pi->radio_chanspec)) ?
> +		    pi->srom_fem5g.pdetrange : pi->srom_fem2g.pdetrange;
> +
> +	if (pdetrange == 0) {
> +		chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0);
> +		if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
> +			aux_adc_vmid_rev7_core0[3] = 0x70;
> +			aux_adc_vmid_rev7_core1[3] = 0x70;
> +			aux_adc_gain_rev7[3] = 2;
> +		} else {
> +			aux_adc_vmid_rev7_core0[3] = 0x80;
> +			aux_adc_vmid_rev7_core1[3] = 0x80;
> +			aux_adc_gain_rev7[3] = 3;
> +		}
> +	} else if (pdetrange == 1) {
> +		if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
> +			aux_adc_vmid_rev7_core0[3] = 0x7c;
> +			aux_adc_vmid_rev7_core1[3] = 0x7c;
> +			aux_adc_gain_rev7[3] = 2;
> +		} else {
> +			aux_adc_vmid_rev7_core0[3] = 0x8c;
> +			aux_adc_vmid_rev7_core1[3] = 0x8c;
> +			aux_adc_gain_rev7[3] = 1;
> +		}
> +	} else if (pdetrange == 2) {
> +		if (pi->pubpi.radioid == BCM2057_ID) {
> +			if ((pi->pubpi.radiorev == 5)
> +			    || (pi->pubpi.radiorev == 7)
> +			    || (pi->pubpi.radiorev == 8)) {
> +				if (chan_freq_range ==
> +				    WL_CHAN_FREQ_RANGE_2G) {
> +					aux_adc_vmid_rev7_core0[3] = 0x8c;
> +					aux_adc_vmid_rev7_core1[3] = 0x8c;
> +					aux_adc_gain_rev7[3] = 0;
> +				} else {
> +					aux_adc_vmid_rev7_core0[3] = 0x96;
> +					aux_adc_vmid_rev7_core1[3] = 0x96;
> +					aux_adc_gain_rev7[3] = 0;
>  				}
>  			}
> +		}
>  
> -		} else if (pdetrange == 3) {
> -			if (chan_freq_range == WL_CHAN_FREQ_RANGE_2G) {
> -				aux_adc_vmid_rev7_core0[3] = 0x89;
> -				aux_adc_vmid_rev7_core1[3] = 0x89;
> -				aux_adc_gain_rev7[3] = 0;
> -			}
> +	} else if (pdetrange == 3) {
> +		if (chan_freq_range == WL_CHAN_FREQ_RANGE_2G) {
> +			aux_adc_vmid_rev7_core0[3] = 0x89;
> +			aux_adc_vmid_rev7_core1[3] = 0x89;
> +			aux_adc_gain_rev7[3] = 0;
> +		}
>  
> -		} else if (pdetrange == 5) {
> +	} else if (pdetrange == 5) {
>  
> -			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
> -				aux_adc_vmid_rev7_core0[3] = 0x80;
> -				aux_adc_vmid_rev7_core1[3] = 0x80;
> -				aux_adc_gain_rev7[3] = 3;
> -			} else {
> -				aux_adc_vmid_rev7_core0[3] = 0x70;
> -				aux_adc_vmid_rev7_core1[3] = 0x70;
> -				aux_adc_gain_rev7[3] = 2;
> -			}
> +		if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
> +			aux_adc_vmid_rev7_core0[3] = 0x80;
> +			aux_adc_vmid_rev7_core1[3] = 0x80;
> +			aux_adc_gain_rev7[3] = 3;
> +		} else {
> +			aux_adc_vmid_rev7_core0[3] = 0x70;
> +			aux_adc_vmid_rev7_core1[3] = 0x70;
> +			aux_adc_gain_rev7[3] = 2;
>  		}
> +	}
>  
> -		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x08, 16,
> -					 &aux_adc_vmid_rev7_core0);
> -		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x18, 16,
> -					 &aux_adc_vmid_rev7_core1);
> -		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x0c, 16,
> -					 &aux_adc_gain_rev7);
> -		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x1c, 16,
> -					 &aux_adc_gain_rev7);
> +	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x08, 16,
> +				 &aux_adc_vmid_rev7_core0);
> +	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x18, 16,
> +				 &aux_adc_vmid_rev7_core1);
> +	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x0c, 16,
> +				 &aux_adc_gain_rev7);
> +	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x1c, 16,
> +				 &aux_adc_gain_rev7);
>  }
>  
>  static void wlc_phy_workarounds_nphy_rev3(struct brcms_phy *pi)
> @@ -16672,7 +16599,8 @@ static void wlc_phy_workarounds_nphy_rev3(struct brcms_phy *pi)
>  		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
>  		NPHY_REV3_RFSEQ_CMD_END
>  	};
> -	static const u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
> +	static const u8 rfseq_rx2tx_dlys_rev3_ipa[] =
> +	    { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
>  	s16 alpha0, alpha1, alpha2;
>  	s16 beta0, beta1, beta2;
>  	u32 leg_data_weights, ht_data_weights, nss1_data_weights,
> @@ -16691,330 +16619,290 @@ static void wlc_phy_workarounds_nphy_rev3(struct brcms_phy *pi)
>  	u8 pdetrange;
>  	u8 triso;
>  
> -		write_phy_reg(pi, 0x23f, 0x1f8);
> -		write_phy_reg(pi, 0x240, 0x1f8);
> -
> -		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
> -					1, 0, 32, &leg_data_weights);
> -		leg_data_weights = leg_data_weights & 0xffffff;
> -		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
> -					 1, 0, 32, &leg_data_weights);
> -
> -		alpha0 = 293;
> -		alpha1 = 435;
> -		alpha2 = 261;
> -		beta0 = 366;
> -		beta1 = 205;
> -		beta2 = 32;
> -		write_phy_reg(pi, 0x145, alpha0);
> -		write_phy_reg(pi, 0x146, alpha1);
> -		write_phy_reg(pi, 0x147, alpha2);
> -		write_phy_reg(pi, 0x148, beta0);
> -		write_phy_reg(pi, 0x149, beta1);
> -		write_phy_reg(pi, 0x14a, beta2);
> -
> -		write_phy_reg(pi, 0x38, 0xC);
> -		write_phy_reg(pi, 0x2ae, 0xC);
> -
> -		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX,
> -				       rfseq_tx2rx_events_rev3,
> -				       rfseq_tx2rx_dlys_rev3,
> -				       ARRAY_SIZE(rfseq_tx2rx_events_rev3));
> -
> -		if (PHY_IPA(pi))
> -			wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
> -					       rfseq_rx2tx_events_rev3_ipa,
> -					       rfseq_rx2tx_dlys_rev3_ipa,
> -					       ARRAY_SIZE(rfseq_rx2tx_events_rev3_ipa));
> -
> -		if ((pi->sh->hw_phyrxchain != 0x3) &&
> -		    (pi->sh->hw_phyrxchain != pi->sh->hw_phytxchain)) {
> -
> -			if (PHY_IPA(pi)) {
> -				rfseq_rx2tx_dlys_rev3[5] = 59;
> -				rfseq_rx2tx_dlys_rev3[6] = 1;
> -				rfseq_rx2tx_events_rev3[7] =
> -					NPHY_REV3_RFSEQ_CMD_END;
> -			}
> -
> -			wlc_phy_set_rfseq_nphy(
> -				pi, NPHY_RFSEQ_RX2TX,
> -				rfseq_rx2tx_events_rev3,
> -				rfseq_rx2tx_dlys_rev3,
> -				ARRAY_SIZE(rfseq_rx2tx_events_rev3));
> -		}
> +	write_phy_reg(pi, 0x23f, 0x1f8);
> +	write_phy_reg(pi, 0x240, 0x1f8);
> +
> +	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
> +				1, 0, 32, &leg_data_weights);
> +	leg_data_weights = leg_data_weights & 0xffffff;
> +	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
> +				 1, 0, 32, &leg_data_weights);
> +
> +	alpha0 = 293;
> +	alpha1 = 435;
> +	alpha2 = 261;
> +	beta0 = 366;
> +	beta1 = 205;
> +	beta2 = 32;
> +	write_phy_reg(pi, 0x145, alpha0);
> +	write_phy_reg(pi, 0x146, alpha1);
> +	write_phy_reg(pi, 0x147, alpha2);
> +	write_phy_reg(pi, 0x148, beta0);
> +	write_phy_reg(pi, 0x149, beta1);
> +	write_phy_reg(pi, 0x14a, beta2);
> +
> +	write_phy_reg(pi, 0x38, 0xC);
> +	write_phy_reg(pi, 0x2ae, 0xC);
> +
> +	wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX,
> +			       rfseq_tx2rx_events_rev3,
> +			       rfseq_tx2rx_dlys_rev3,
> +			       ARRAY_SIZE(rfseq_tx2rx_events_rev3));
>  
> -		if (CHSPEC_IS2G(pi->radio_chanspec))
> -			write_phy_reg(pi, 0x6a, 0x2);
> -		else
> -			write_phy_reg(pi, 0x6a, 0x9c40);
> -
> -		mod_phy_reg(pi, 0x294, (0xf << 8), (7 << 8));
> +	if (PHY_IPA(pi))
> +		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
> +				       rfseq_rx2tx_events_rev3_ipa,
> +				       rfseq_rx2tx_dlys_rev3_ipa,
> +				       ARRAY_SIZE (rfseq_rx2tx_events_rev3_ipa));
>  
> -		if (CHSPEC_IS40(pi->radio_chanspec) == 0) {
> -			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
> -						 32, &min_nvar_val);
> -			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
> -						 127, 32, &min_nvar_val);
> -		} else {
> -			min_nvar_val = noise_var_tbl_rev3[3];
> -			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
> -						 32, &min_nvar_val);
> +	if ((pi->sh->hw_phyrxchain != 0x3) &&
> +	    (pi->sh->hw_phyrxchain != pi->sh->hw_phytxchain)) {
>  
> -			min_nvar_val = noise_var_tbl_rev3[127];
> -			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
> -						 127, 32, &min_nvar_val);
> +		if (PHY_IPA(pi)) {
> +			rfseq_rx2tx_dlys_rev3[5] = 59;
> +			rfseq_rx2tx_dlys_rev3[6] = 1;
> +			rfseq_rx2tx_events_rev3[7] = NPHY_REV3_RFSEQ_CMD_END;
>  		}
>  
> -		wlc_phy_workarounds_nphy_gainctrl(pi);
> +		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
> +				       rfseq_rx2tx_events_rev3,
> +				       rfseq_rx2tx_dlys_rev3,
> +				       ARRAY_SIZE (rfseq_rx2tx_events_rev3));
> +	}
>  
> -		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16,
> -					 &dac_control);
> -		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x10, 16,
> -					 &dac_control);
> +	if (CHSPEC_IS2G(pi->radio_chanspec))
> +		write_phy_reg(pi, 0x6a, 0x2);
> +	else
> +		write_phy_reg(pi, 0x6a, 0x9c40);
>  
> -		pdetrange =
> -			(CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
> -			pdetrange : pi->srom_fem2g.pdetrange;
> +	mod_phy_reg(pi, 0x294, (0xf << 8), (7 << 8));
>  
> -		if (pdetrange == 0) {
> -			if (NREV_GE(pi->pubpi.phy_rev, 4)) {
> -				aux_adc_vmid = aux_adc_vmid_rev4;
> -				aux_adc_gain = aux_adc_gain_rev4;
> -			} else {
> -				aux_adc_vmid = aux_adc_vmid_rev3;
> -				aux_adc_gain = aux_adc_gain_rev3;
> -			}
> -			chan_freq_range =
> -				wlc_phy_get_chan_freq_range_nphy(pi, 0);
> -			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
> -				switch (chan_freq_range) {
> -				case WL_CHAN_FREQ_RANGE_5GL:
> -					aux_adc_vmid[3] = 0x89;
> -					aux_adc_gain[3] = 0;
> -					break;
> -				case WL_CHAN_FREQ_RANGE_5GM:
> -					aux_adc_vmid[3] = 0x89;
> -					aux_adc_gain[3] = 0;
> -					break;
> -				case WL_CHAN_FREQ_RANGE_5GH:
> -					aux_adc_vmid[3] = 0x89;
> -					aux_adc_gain[3] = 0;
> -					break;
> -				default:
> -					break;
> -				}
> -			}
> -			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> -						 0x08, 16, aux_adc_vmid);
> -			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> -						 0x18, 16, aux_adc_vmid);
> -			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> -						 0x0c, 16, aux_adc_gain);
> -			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> -						 0x1c, 16, aux_adc_gain);
> -		} else if (pdetrange == 1) {
> -			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> -						 0x08, 16, sk_adc_vmid);
> -			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> -						 0x18, 16, sk_adc_vmid);
> -			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> -						 0x0c, 16, sk_adc_gain);
> -			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> -						 0x1c, 16, sk_adc_gain);
> -		} else if (pdetrange == 2) {
> +	if (CHSPEC_IS40(pi->radio_chanspec) == 0) {
> +		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
> +					 32, &min_nvar_val);
> +		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
> +					 127, 32, &min_nvar_val);
> +	} else {
> +		min_nvar_val = noise_var_tbl_rev3[3];
> +		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
> +					 32, &min_nvar_val);
>  
> -			u16 bcm_adc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x74 };
> -			u16 bcm_adc_gain[] = { 0x02, 0x02, 0x02, 0x04 };
> +		min_nvar_val = noise_var_tbl_rev3[127];
> +		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
> +					 127, 32, &min_nvar_val);
> +	}
>  
> -			if (NREV_GE(pi->pubpi.phy_rev, 6)) {
> -				chan_freq_range =
> -					wlc_phy_get_chan_freq_range_nphy(pi, 0);
> -				if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
> -					bcm_adc_vmid[3] = 0x8e;
> -					bcm_adc_gain[3] = 0x03;
> -				} else {
> -					bcm_adc_vmid[3] = 0x94;
> -					bcm_adc_gain[3] = 0x03;
> -				}
> -			} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
> -				bcm_adc_vmid[3] = 0x84;
> -				bcm_adc_gain[3] = 0x02;
> -			}
> +	wlc_phy_workarounds_nphy_gainctrl(pi);
>  
> -			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> -						 0x08, 16, bcm_adc_vmid);
> -			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> -						 0x18, 16, bcm_adc_vmid);
> -			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> -						 0x0c, 16, bcm_adc_gain);
> -			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> -						 0x1c, 16, bcm_adc_gain);
> -		} else if (pdetrange == 3) {
> -			chan_freq_range =
> -				wlc_phy_get_chan_freq_range_nphy(pi, 0);
> -			if ((NREV_GE(pi->pubpi.phy_rev, 4))
> -			    && (chan_freq_range == WL_CHAN_FREQ_RANGE_2G)) {
> +	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16,
> +				 &dac_control);
> +	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x10, 16,
> +				 &dac_control);
>  
> -				u16 auxadc_vmid[] = {
> -					0xa2, 0xb4, 0xb4, 0x270
> -				};
> -				u16 auxadc_gain[] = {
> -					0x02, 0x02, 0x02, 0x00
> -				};
> +	pdetrange = (CHSPEC_IS5G(pi->radio_chanspec)) ?
> +			pi->srom_fem5g.pdetrange : pi->srom_fem2g.pdetrange;
>  
> -				wlc_phy_table_write_nphy(pi,
> -							 NPHY_TBL_ID_AFECTRL, 4,
> -							 0x08, 16, auxadc_vmid);
> -				wlc_phy_table_write_nphy(pi,
> -							 NPHY_TBL_ID_AFECTRL, 4,
> -							 0x18, 16, auxadc_vmid);
> -				wlc_phy_table_write_nphy(pi,
> -							 NPHY_TBL_ID_AFECTRL, 4,
> -							 0x0c, 16, auxadc_gain);
> -				wlc_phy_table_write_nphy(pi,
> -							 NPHY_TBL_ID_AFECTRL, 4,
> -							 0x1c, 16, auxadc_gain);
> +	if (pdetrange == 0) {
> +		if (NREV_GE(pi->pubpi.phy_rev, 4)) {
> +			aux_adc_vmid = aux_adc_vmid_rev4;
> +			aux_adc_gain = aux_adc_gain_rev4;
> +		} else {
> +			aux_adc_vmid = aux_adc_vmid_rev3;
> +			aux_adc_gain = aux_adc_gain_rev3;
> +		}
> +		chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0);
> +		if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
> +			switch (chan_freq_range) {
> +			case WL_CHAN_FREQ_RANGE_5GL:
> +				aux_adc_vmid[3] = 0x89;
> +				aux_adc_gain[3] = 0;
> +				break;
> +			case WL_CHAN_FREQ_RANGE_5GM:
> +				aux_adc_vmid[3] = 0x89;
> +				aux_adc_gain[3] = 0;
> +				break;
> +			case WL_CHAN_FREQ_RANGE_5GH:
> +				aux_adc_vmid[3] = 0x89;
> +				aux_adc_gain[3] = 0;
> +				break;
> +			default:
> +				break;
>  			}
> -		} else if ((pdetrange == 4) || (pdetrange == 5)) {
> -			u16 bcm_adc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x0 };
> -			u16 bcm_adc_gain[] = { 0x02, 0x02, 0x02, 0x0 };
> -			u16 Vmid[2], Av[2];
> +		}
> +		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> +					 0x08, 16, aux_adc_vmid);
> +		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> +					 0x18, 16, aux_adc_vmid);
> +		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> +					 0x0c, 16, aux_adc_gain);
> +		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> +					 0x1c, 16, aux_adc_gain);
> +	} else if (pdetrange == 1) {
> +		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> +					 0x08, 16, sk_adc_vmid);
> +		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> +					 0x18, 16, sk_adc_vmid);
> +		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> +					 0x0c, 16, sk_adc_gain);
> +		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> +					 0x1c, 16, sk_adc_gain);
> +	} else if (pdetrange == 2) {
> +
> +		u16 bcm_adc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x74 };
> +		u16 bcm_adc_gain[] = { 0x02, 0x02, 0x02, 0x04 };
>  
> +		if (NREV_GE(pi->pubpi.phy_rev, 6)) {
>  			chan_freq_range =
> -				wlc_phy_get_chan_freq_range_nphy(pi, 0);
> +			    wlc_phy_get_chan_freq_range_nphy(pi, 0);
>  			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
> -				Vmid[0] = (pdetrange == 4) ? 0x8e : 0x89;
> -				Vmid[1] = (pdetrange == 4) ? 0x96 : 0x89;
> -				Av[0] = (pdetrange == 4) ? 2 : 0;
> -				Av[1] = (pdetrange == 4) ? 2 : 0;
> +				bcm_adc_vmid[3] = 0x8e;
> +				bcm_adc_gain[3] = 0x03;
>  			} else {
> -				Vmid[0] = (pdetrange == 4) ? 0x89 : 0x74;
> -				Vmid[1] = (pdetrange == 4) ? 0x8b : 0x70;
> -				Av[0] = (pdetrange == 4) ? 2 : 0;
> -				Av[1] = (pdetrange == 4) ? 2 : 0;
> +				bcm_adc_vmid[3] = 0x94;
> +				bcm_adc_gain[3] = 0x03;
>  			}
> +		} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
> +			bcm_adc_vmid[3] = 0x84;
> +			bcm_adc_gain[3] = 0x02;
> +		}
> +
> +		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> +					 0x08, 16, bcm_adc_vmid);
> +		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> +					 0x18, 16, bcm_adc_vmid);
> +		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> +					 0x0c, 16, bcm_adc_gain);
> +		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> +					 0x1c, 16, bcm_adc_gain);
> +	} else if (pdetrange == 3) {
> +		chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0);
> +		if ((NREV_GE(pi->pubpi.phy_rev, 4)) &&
> +		    (chan_freq_range == WL_CHAN_FREQ_RANGE_2G)) {
> +			u16 auxadc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x270 };
> +			u16 auxadc_gain[] = { 0x02, 0x02, 0x02, 0x00 };
>  
> -			bcm_adc_vmid[3] = Vmid[0];
> -			bcm_adc_gain[3] = Av[0];
>  			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> -						 0x08, 16, bcm_adc_vmid);
> +						 0x08, 16, auxadc_vmid);
>  			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> -						 0x0c, 16, bcm_adc_gain);
> -
> -			bcm_adc_vmid[3] = Vmid[1];
> -			bcm_adc_gain[3] = Av[1];
> +						 0x18, 16, auxadc_vmid);
>  			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> -						 0x18, 16, bcm_adc_vmid);
> +						 0x0c, 16, auxadc_gain);
>  			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> -						 0x1c, 16, bcm_adc_gain);
> +						 0x1c, 16, auxadc_gain);
>  		}
> +	} else if ((pdetrange == 4) || (pdetrange == 5)) {
> +		u16 bcm_adc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x0 };
> +		u16 bcm_adc_gain[] = { 0x02, 0x02, 0x02, 0x0 };
> +		u16 Vmid[2], Av[2];
>  
> -		write_radio_reg(pi,
> -				(RADIO_2056_RX_MIXA_MAST_BIAS | RADIO_2056_RX0),
> -				0x0);
> -		write_radio_reg(pi,
> -				(RADIO_2056_RX_MIXA_MAST_BIAS | RADIO_2056_RX1),
> -				0x0);
> +		chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0);
> +		if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
> +			Vmid[0] = (pdetrange == 4) ? 0x8e : 0x89;
> +			Vmid[1] = (pdetrange == 4) ? 0x96 : 0x89;
> +			Av[0] = (pdetrange == 4) ? 2 : 0;
> +			Av[1] = (pdetrange == 4) ? 2 : 0;
> +		} else {
> +			Vmid[0] = (pdetrange == 4) ? 0x89 : 0x74;
> +			Vmid[1] = (pdetrange == 4) ? 0x8b : 0x70;
> +			Av[0] = (pdetrange == 4) ? 2 : 0;
> +			Av[1] = (pdetrange == 4) ? 2 : 0;
> +		}
>  
> -		write_radio_reg(pi,
> -				(RADIO_2056_RX_MIXA_BIAS_MAIN | RADIO_2056_RX0),
> -				0x6);
> -		write_radio_reg(pi,
> -				(RADIO_2056_RX_MIXA_BIAS_MAIN | RADIO_2056_RX1),
> -				0x6);
> +		bcm_adc_vmid[3] = Vmid[0];
> +		bcm_adc_gain[3] = Av[0];
> +		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> +					 0x08, 16, bcm_adc_vmid);
> +		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> +					 0x0c, 16, bcm_adc_gain);
> +
> +		bcm_adc_vmid[3] = Vmid[1];
> +		bcm_adc_gain[3] = Av[1];
> +		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> +					 0x18, 16, bcm_adc_vmid);
> +		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
> +					 0x1c, 16, bcm_adc_gain);
> +	}
>  
> -		write_radio_reg(pi,
> -				(RADIO_2056_RX_MIXA_BIAS_AUX | RADIO_2056_RX0),
> -				0x7);
> -		write_radio_reg(pi,
> -				(RADIO_2056_RX_MIXA_BIAS_AUX | RADIO_2056_RX1),
> -				0x7);
> +	write_radio_reg(pi, (RADIO_2056_RX_MIXA_MAST_BIAS | RADIO_2056_RX0), 0x0);
> +	write_radio_reg(pi, (RADIO_2056_RX_MIXA_MAST_BIAS | RADIO_2056_RX1), 0x0);
>  
> -		write_radio_reg(pi,
> -				(RADIO_2056_RX_MIXA_LOB_BIAS | RADIO_2056_RX0),
> -				0x88);
> -		write_radio_reg(pi,
> -				(RADIO_2056_RX_MIXA_LOB_BIAS | RADIO_2056_RX1),
> -				0x88);
> +	write_radio_reg(pi, (RADIO_2056_RX_MIXA_BIAS_MAIN | RADIO_2056_RX0), 0x6);
> +	write_radio_reg(pi, (RADIO_2056_RX_MIXA_BIAS_MAIN | RADIO_2056_RX1), 0x6);
>  
> -		write_radio_reg(pi,
> -				(RADIO_2056_RX_MIXA_CMFB_IDAC | RADIO_2056_RX0),
> -				0x0);
> -		write_radio_reg(pi,
> -				(RADIO_2056_RX_MIXA_CMFB_IDAC | RADIO_2056_RX1),
> -				0x0);
> +	write_radio_reg(pi, (RADIO_2056_RX_MIXA_BIAS_AUX | RADIO_2056_RX0), 0x7);
> +	write_radio_reg(pi, (RADIO_2056_RX_MIXA_BIAS_AUX | RADIO_2056_RX1), 0x7);
>  
> -		write_radio_reg(pi,
> -				(RADIO_2056_RX_MIXG_CMFB_IDAC | RADIO_2056_RX0),
> -				0x0);
> -		write_radio_reg(pi,
> -				(RADIO_2056_RX_MIXG_CMFB_IDAC | RADIO_2056_RX1),
> -				0x0);
> +	write_radio_reg(pi, (RADIO_2056_RX_MIXA_LOB_BIAS | RADIO_2056_RX0), 0x88);
> +	write_radio_reg(pi, (RADIO_2056_RX_MIXA_LOB_BIAS | RADIO_2056_RX1), 0x88);
>  
> -		triso =
> -			(CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
> -			triso : pi->srom_fem2g.triso;
> -		if (triso == 7) {
> -			wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_0);
> -			wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_1);
> -		}
> +	write_radio_reg(pi, (RADIO_2056_RX_MIXA_CMFB_IDAC | RADIO_2056_RX0), 0x0);
> +	write_radio_reg(pi, (RADIO_2056_RX_MIXA_CMFB_IDAC | RADIO_2056_RX1), 0x0);
>  
> -		wlc_phy_war_txchain_upd_nphy(pi, pi->sh->hw_phytxchain);
> +	write_radio_reg(pi, (RADIO_2056_RX_MIXG_CMFB_IDAC | RADIO_2056_RX0), 0x0);
> +	write_radio_reg(pi, (RADIO_2056_RX_MIXG_CMFB_IDAC | RADIO_2056_RX1), 0x0);
>  
> -		if (((pi->sh->boardflags2 & BFL2_APLL_WAR) &&
> -		     (CHSPEC_IS5G(pi->radio_chanspec))) ||
> -		    (((pi->sh->boardflags2 & BFL2_GPLL_WAR) ||
> -		      (pi->sh->boardflags2 & BFL2_GPLL_WAR2)) &&
> -		     (CHSPEC_IS2G(pi->radio_chanspec)))) {
> -			nss1_data_weights = 0x00088888;
> -			ht_data_weights = 0x00088888;
> -			stbc_data_weights = 0x00088888;
> -		} else {
> -			nss1_data_weights = 0x88888888;
> -			ht_data_weights = 0x88888888;
> -			stbc_data_weights = 0x88888888;
> -		}
> -		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
> -					 1, 1, 32, &nss1_data_weights);
> -		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
> -					 1, 2, 32, &ht_data_weights);
> -		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
> -					 1, 3, 32, &stbc_data_weights);
> -
> -		if (NREV_IS(pi->pubpi.phy_rev, 4)) {
> -			if (CHSPEC_IS5G(pi->radio_chanspec)) {
> -				write_radio_reg(pi,
> -						RADIO_2056_TX_GMBB_IDAC |
> -						RADIO_2056_TX0, 0x70);
> -				write_radio_reg(pi,
> -						RADIO_2056_TX_GMBB_IDAC |
> -						RADIO_2056_TX1, 0x70);
> -			}
> -		}
> +	triso = (CHSPEC_IS5G(pi->radio_chanspec)) ?
> +		 pi->srom_fem5g.triso : pi->srom_fem2g.triso;
> +	if (triso == 7) {
> +		wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_0);
> +		wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_1);
> +	}
>  
> -		if (!pi->edcrs_threshold_lock) {
> -			write_phy_reg(pi, 0x224, 0x3eb);
> -			write_phy_reg(pi, 0x225, 0x3eb);
> -			write_phy_reg(pi, 0x226, 0x341);
> -			write_phy_reg(pi, 0x227, 0x341);
> -			write_phy_reg(pi, 0x228, 0x42b);
> -			write_phy_reg(pi, 0x229, 0x42b);
> -			write_phy_reg(pi, 0x22a, 0x381);
> -			write_phy_reg(pi, 0x22b, 0x381);
> -			write_phy_reg(pi, 0x22c, 0x42b);
> -			write_phy_reg(pi, 0x22d, 0x42b);
> -			write_phy_reg(pi, 0x22e, 0x381);
> -			write_phy_reg(pi, 0x22f, 0x381);
> +	wlc_phy_war_txchain_upd_nphy(pi, pi->sh->hw_phytxchain);
> +
> +	if (((pi->sh->boardflags2 & BFL2_APLL_WAR) &&
> +	     (CHSPEC_IS5G(pi->radio_chanspec))) ||
> +	    (((pi->sh->boardflags2 & BFL2_GPLL_WAR) ||
> +	      (pi->sh->boardflags2 & BFL2_GPLL_WAR2)) &&
> +	     (CHSPEC_IS2G(pi->radio_chanspec)))) {
> +		nss1_data_weights = 0x00088888;
> +		ht_data_weights = 0x00088888;
> +		stbc_data_weights = 0x00088888;
> +	} else {
> +		nss1_data_weights = 0x88888888;
> +		ht_data_weights = 0x88888888;
> +		stbc_data_weights = 0x88888888;
> +	}
> +	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
> +				 1, 1, 32, &nss1_data_weights);
> +	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
> +				 1, 2, 32, &ht_data_weights);
> +	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
> +				 1, 3, 32, &stbc_data_weights);
> +
> +	if (NREV_IS(pi->pubpi.phy_rev, 4)) {
> +		if (CHSPEC_IS5G(pi->radio_chanspec)) {
> +			write_radio_reg(pi,
> +					RADIO_2056_TX_GMBB_IDAC |
> +					RADIO_2056_TX0, 0x70);
> +			write_radio_reg(pi,
> +					RADIO_2056_TX_GMBB_IDAC |
> +					RADIO_2056_TX1, 0x70);
>  		}
> +	}
>  
> -		if (NREV_GE(pi->pubpi.phy_rev, 6)) {
> +	if (!pi->edcrs_threshold_lock) {
> +		write_phy_reg(pi, 0x224, 0x3eb);
> +		write_phy_reg(pi, 0x225, 0x3eb);
> +		write_phy_reg(pi, 0x226, 0x341);
> +		write_phy_reg(pi, 0x227, 0x341);
> +		write_phy_reg(pi, 0x228, 0x42b);
> +		write_phy_reg(pi, 0x229, 0x42b);
> +		write_phy_reg(pi, 0x22a, 0x381);
> +		write_phy_reg(pi, 0x22b, 0x381);
> +		write_phy_reg(pi, 0x22c, 0x42b);
> +		write_phy_reg(pi, 0x22d, 0x42b);
> +		write_phy_reg(pi, 0x22e, 0x381);
> +		write_phy_reg(pi, 0x22f, 0x381);
> +	}
>  
> -			if (pi->sh->boardflags2 & BFL2_SINGLEANT_CCK)
> -				wlapi_bmac_mhf(pi->sh->physhim, MHF4,
> -					      MHF4_BPHY_TXCORE0,
> -					      MHF4_BPHY_TXCORE0, BRCM_BAND_ALL);
> -		}
> +	if (NREV_GE(pi->pubpi.phy_rev, 6)) {
> +
> +		if (pi->sh->boardflags2 & BFL2_SINGLEANT_CCK)
> +			wlapi_bmac_mhf(pi->sh->physhim, MHF4,
> +				       MHF4_BPHY_TXCORE0,
> +				       MHF4_BPHY_TXCORE0, BRCM_BAND_ALL);
> +	}
>  }
>  
>  void wlc_phy_workarounds_nphy_rev1(struct brcms_phy *pi)
> @@ -17043,102 +16931,101 @@ void wlc_phy_workarounds_nphy_rev1(struct brcms_phy *pi)
>  	s16 beta0, beta1, beta2;
>  	u16 regval;
>  
> -		if (pi->sh->boardflags2 & BFL2_SKWRKFEM_BRD ||
> -		    (pi->sh->boardtype == 0x8b)) {
> -			uint i;
> -			u8 war_dlys[] = { 1, 6, 6, 2, 4, 20, 1 };
> -			for (i = 0; i < ARRAY_SIZE(rfseq_rx2tx_dlys); i++)
> -				rfseq_rx2tx_dlys[i] = war_dlys[i];
> -		}
> +	if (pi->sh->boardflags2 & BFL2_SKWRKFEM_BRD ||
> +	    (pi->sh->boardtype == 0x8b)) {
> +		uint i;
> +		u8 war_dlys[] = { 1, 6, 6, 2, 4, 20, 1 };
> +		for (i = 0; i < ARRAY_SIZE(rfseq_rx2tx_dlys); i++)
> +			rfseq_rx2tx_dlys[i] = war_dlys[i];
> +	}
>  
> -		if (CHSPEC_IS5G(pi->radio_chanspec) && pi->phy_5g_pwrgain) {
> -			and_radio_reg(pi, RADIO_2055_CORE1_TX_RF_SPARE, 0xf7);
> -			and_radio_reg(pi, RADIO_2055_CORE2_TX_RF_SPARE, 0xf7);
> -		} else {
> -			or_radio_reg(pi, RADIO_2055_CORE1_TX_RF_SPARE, 0x8);
> -			or_radio_reg(pi, RADIO_2055_CORE2_TX_RF_SPARE, 0x8);
> -		}
> +	if (CHSPEC_IS5G(pi->radio_chanspec) && pi->phy_5g_pwrgain) {
> +		and_radio_reg(pi, RADIO_2055_CORE1_TX_RF_SPARE, 0xf7);
> +		and_radio_reg(pi, RADIO_2055_CORE2_TX_RF_SPARE, 0xf7);
> +	} else {
> +		or_radio_reg(pi, RADIO_2055_CORE1_TX_RF_SPARE, 0x8);
> +		or_radio_reg(pi, RADIO_2055_CORE2_TX_RF_SPARE, 0x8);
> +	}
>  
> -		regval = 0x000a;
> -		wlc_phy_table_write_nphy(pi, 8, 1, 0, 16, &regval);
> -		wlc_phy_table_write_nphy(pi, 8, 1, 0x10, 16, &regval);
> +	regval = 0x000a;
> +	wlc_phy_table_write_nphy(pi, 8, 1, 0, 16, &regval);
> +	wlc_phy_table_write_nphy(pi, 8, 1, 0x10, 16, &regval);
>  
> -		if (NREV_LT(pi->pubpi.phy_rev, 3)) {
> -			regval = 0xcdaa;
> -			wlc_phy_table_write_nphy(pi, 8, 1, 0x02, 16, &regval);
> -			wlc_phy_table_write_nphy(pi, 8, 1, 0x12, 16, &regval);
> -		}
> +	if (NREV_LT(pi->pubpi.phy_rev, 3)) {
> +		regval = 0xcdaa;
> +		wlc_phy_table_write_nphy(pi, 8, 1, 0x02, 16, &regval);
> +		wlc_phy_table_write_nphy(pi, 8, 1, 0x12, 16, &regval);
> +	}
>  
> -		if (NREV_LT(pi->pubpi.phy_rev, 2)) {
> -			regval = 0x0000;
> -			wlc_phy_table_write_nphy(pi, 8, 1, 0x08, 16, &regval);
> -			wlc_phy_table_write_nphy(pi, 8, 1, 0x18, 16, &regval);
> +	if (NREV_LT(pi->pubpi.phy_rev, 2)) {
> +		regval = 0x0000;
> +		wlc_phy_table_write_nphy(pi, 8, 1, 0x08, 16, &regval);
> +		wlc_phy_table_write_nphy(pi, 8, 1, 0x18, 16, &regval);
>  
> -			regval = 0x7aab;
> -			wlc_phy_table_write_nphy(pi, 8, 1, 0x07, 16, &regval);
> -			wlc_phy_table_write_nphy(pi, 8, 1, 0x17, 16, &regval);
> +		regval = 0x7aab;
> +		wlc_phy_table_write_nphy(pi, 8, 1, 0x07, 16, &regval);
> +		wlc_phy_table_write_nphy(pi, 8, 1, 0x17, 16, &regval);
>  
> -			regval = 0x0800;
> -			wlc_phy_table_write_nphy(pi, 8, 1, 0x06, 16, &regval);
> -			wlc_phy_table_write_nphy(pi, 8, 1, 0x16, 16, &regval);
> -		}
> +		regval = 0x0800;
> +		wlc_phy_table_write_nphy(pi, 8, 1, 0x06, 16, &regval);
> +		wlc_phy_table_write_nphy(pi, 8, 1, 0x16, 16, &regval);
> +	}
>  
> -		write_phy_reg(pi, 0xf8, 0x02d8);
> -		write_phy_reg(pi, 0xf9, 0x0301);
> -		write_phy_reg(pi, 0xfa, 0x02d8);
> -		write_phy_reg(pi, 0xfb, 0x0301);
> +	write_phy_reg(pi, 0xf8, 0x02d8);
> +	write_phy_reg(pi, 0xf9, 0x0301);
> +	write_phy_reg(pi, 0xfa, 0x02d8);
> +	write_phy_reg(pi, 0xfb, 0x0301);
>  
> -		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX, rfseq_rx2tx_events,
> -				       rfseq_rx2tx_dlys,
> -				       ARRAY_SIZE(rfseq_rx2tx_events));
> +	wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX, rfseq_rx2tx_events,
> +			       rfseq_rx2tx_dlys,
> +			       ARRAY_SIZE(rfseq_rx2tx_events));
>  
> -		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX, rfseq_tx2rx_events,
> -				       rfseq_tx2rx_dlys,
> -				       ARRAY_SIZE(rfseq_tx2rx_events));
> +	wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX, rfseq_tx2rx_events,
> +			       rfseq_tx2rx_dlys,
> +			       ARRAY_SIZE(rfseq_tx2rx_events));
>  
> -		wlc_phy_workarounds_nphy_gainctrl(pi);
> +	wlc_phy_workarounds_nphy_gainctrl(pi);
>  
> -		if (NREV_LT(pi->pubpi.phy_rev, 2)) {
> +	if (NREV_LT(pi->pubpi.phy_rev, 2)) {
>  
> -			if (read_phy_reg(pi, 0xa0) & NPHY_MLenable)
> -				wlapi_bmac_mhf(pi->sh->physhim, MHF3,
> -					       MHF3_NPHY_MLADV_WAR,
> -					       MHF3_NPHY_MLADV_WAR,
> -					       BRCM_BAND_ALL);
> +		if (read_phy_reg(pi, 0xa0) & NPHY_MLenable)
> +			wlapi_bmac_mhf(pi->sh->physhim, MHF3,
> +				       MHF3_NPHY_MLADV_WAR,
> +				       MHF3_NPHY_MLADV_WAR, BRCM_BAND_ALL);
>  
> -		} else if (NREV_IS(pi->pubpi.phy_rev, 2)) {
> -			write_phy_reg(pi, 0x1e3, 0x0);
> -			write_phy_reg(pi, 0x1e4, 0x0);
> -		}
> +	} else if (NREV_IS(pi->pubpi.phy_rev, 2)) {
> +		write_phy_reg(pi, 0x1e3, 0x0);
> +		write_phy_reg(pi, 0x1e4, 0x0);
> +	}
>  
> -		if (NREV_LT(pi->pubpi.phy_rev, 2))
> -			mod_phy_reg(pi, 0x90, (0x1 << 7), 0);
> -
> -		alpha0 = 293;
> -		alpha1 = 435;
> -		alpha2 = 261;
> -		beta0 = 366;
> -		beta1 = 205;
> -		beta2 = 32;
> -		write_phy_reg(pi, 0x145, alpha0);
> -		write_phy_reg(pi, 0x146, alpha1);
> -		write_phy_reg(pi, 0x147, alpha2);
> -		write_phy_reg(pi, 0x148, beta0);
> -		write_phy_reg(pi, 0x149, beta1);
> -		write_phy_reg(pi, 0x14a, beta2);
> -
> -		if (NREV_LT(pi->pubpi.phy_rev, 3)) {
> -			mod_phy_reg(pi, 0x142, (0xf << 12), 0);
> -
> -			write_phy_reg(pi, 0x192, 0xb5);
> -			write_phy_reg(pi, 0x193, 0xa4);
> -			write_phy_reg(pi, 0x194, 0x0);
> -		}
> +	if (NREV_LT(pi->pubpi.phy_rev, 2))
> +		mod_phy_reg(pi, 0x90, (0x1 << 7), 0);
> +
> +	alpha0 = 293;
> +	alpha1 = 435;
> +	alpha2 = 261;
> +	beta0 = 366;
> +	beta1 = 205;
> +	beta2 = 32;
> +	write_phy_reg(pi, 0x145, alpha0);
> +	write_phy_reg(pi, 0x146, alpha1);
> +	write_phy_reg(pi, 0x147, alpha2);
> +	write_phy_reg(pi, 0x148, beta0);
> +	write_phy_reg(pi, 0x149, beta1);
> +	write_phy_reg(pi, 0x14a, beta2);
> +
> +	if (NREV_LT(pi->pubpi.phy_rev, 3)) {
> +		mod_phy_reg(pi, 0x142, (0xf << 12), 0);
> +
> +		write_phy_reg(pi, 0x192, 0xb5);
> +		write_phy_reg(pi, 0x193, 0xa4);
> +		write_phy_reg(pi, 0x194, 0x0);
> +	}
>  
> -		if (NREV_IS(pi->pubpi.phy_rev, 2))
> -			mod_phy_reg(pi, 0x221,
> -				    NPHY_FORCESIG_DECODEGATEDCLKS,
> -				    NPHY_FORCESIG_DECODEGATEDCLKS);
> +	if (NREV_IS(pi->pubpi.phy_rev, 2))
> +		mod_phy_reg(pi, 0x221,
> +			    NPHY_FORCESIG_DECODEGATEDCLKS,
> +			    NPHY_FORCESIG_DECODEGATEDCLKS);
>  }
>  
>  static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
> 

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 07/26] brcmsmac: reduce stack size with KASAN
  2017-03-06  9:16   ` Arend Van Spriel
@ 2017-03-06 10:38     ` Arnd Bergmann
  2017-03-06 11:02       ` Arend Van Spriel
  0 siblings, 1 reply; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-06 10:38 UTC (permalink / raw)
  To: Arend Van Spriel
  Cc: kasan-dev, Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
	Networking, Linux Kernel Mailing List, linux-media,
	linux-wireless, kernel-build-reports, David S . Miller

On Mon, Mar 6, 2017 at 10:16 AM, Arend Van Spriel
<arend.vanspriel@broadcom.com> wrote:
> On 2-3-2017 17:38, Arnd Bergmann wrote:
>> The wlc_phy_table_write_nphy/wlc_phy_table_read_nphy functions always put an object
>> on the stack, which will each require a redzone with KASAN and lead to possible
>> stack overflow:
>>
>> drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c: In function 'wlc_phy_workarounds_nphy':
>> drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c:17135:1: warning: the frame size of 6312 bytes is larger than 1000 bytes [-Wframe-larger-than=]
>
> Looks like this warning text ended up in the wrong commit message. Got
> me confused for a sec :-p

What's wrong about the warning?

>> This marks the two functions as noinline_for_kasan, avoiding the problem entirely.
>
> Frankly I seriously dislike annotating code for the sake of some
> (dynamic) memory analyzer. To me the whole thing seems rather
> unnecessary. If the code passes the 2048 stack limit without KASAN it
> would seem the limit with KASAN should be such that no warning is given.
> I suspect that it is rather difficult to predict the additional size of
> the instrumentation code and on some systems there might be a real issue
> with increased stack usage.

The frame sizes don't normally change that much. There are a couple of
drivers like brcmsmac that repeatedly call an inline function which has
a local variable that it passes by reference to an extern function.

While normally those variables share a stack location, KASAN forces
each instance to its own location and adds (in this case) 80 bytes of
redzone around it to detect out-of-bounds access.

While most drivers are fine with a 1500 byte warning limit, increasing
the limit to 7kb would silence brcmsmac (unless more registers
are accessed from wlc_phy_workarounds_nphy) but also risk a
stack overflow to go unnoticed.

    Arnd

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 07/26] brcmsmac: reduce stack size with KASAN
  2017-03-06 10:38     ` Arnd Bergmann
@ 2017-03-06 11:02       ` Arend Van Spriel
  2017-03-06 11:16         ` Arnd Bergmann
  0 siblings, 1 reply; 67+ messages in thread
From: Arend Van Spriel @ 2017-03-06 11:02 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: kasan-dev, Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
	Networking, Linux Kernel Mailing List, linux-media,
	linux-wireless, kernel-build-reports, David S . Miller

On 6-3-2017 11:38, Arnd Bergmann wrote:
> On Mon, Mar 6, 2017 at 10:16 AM, Arend Van Spriel
> <arend.vanspriel@broadcom.com> wrote:
>> On 2-3-2017 17:38, Arnd Bergmann wrote:
>>> The wlc_phy_table_write_nphy/wlc_phy_table_read_nphy functions always put an object
>>> on the stack, which will each require a redzone with KASAN and lead to possible
>>> stack overflow:
>>>
>>> drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c: In function 'wlc_phy_workarounds_nphy':
>>> drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c:17135:1: warning: the frame size of 6312 bytes is larger than 1000 bytes [-Wframe-larger-than=]
>>
>> Looks like this warning text ended up in the wrong commit message. Got
>> me confused for a sec :-p
> 
> What's wrong about the warning?

The warning is about the function 'wlc_phy_workarounds_nphy' (see PATCH
9/26) and not about wlc_phy_table_write_nphy/wlc_phy_table_read_nphy
functions.

>>> This marks the two functions as noinline_for_kasan, avoiding the problem entirely.
>>
>> Frankly I seriously dislike annotating code for the sake of some
>> (dynamic) memory analyzer. To me the whole thing seems rather
>> unnecessary. If the code passes the 2048 stack limit without KASAN it
>> would seem the limit with KASAN should be such that no warning is given.
>> I suspect that it is rather difficult to predict the additional size of
>> the instrumentation code and on some systems there might be a real issue
>> with increased stack usage.
> 
> The frame sizes don't normally change that much. There are a couple of
> drivers like brcmsmac that repeatedly call an inline function which has
> a local variable that it passes by reference to an extern function.
> 
> While normally those variables share a stack location, KASAN forces
> each instance to its own location and adds (in this case) 80 bytes of
> redzone around it to detect out-of-bounds access.
> 
> While most drivers are fine with a 1500 byte warning limit, increasing
> the limit to 7kb would silence brcmsmac (unless more registers
> are accessed from wlc_phy_workarounds_nphy) but also risk a
> stack overflow to go unnoticed.

Given the amount of local variables maybe just tag the functions with
noinline instead.

Regards,
Arend

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 07/26] brcmsmac: reduce stack size with KASAN
  2017-03-06 11:02       ` Arend Van Spriel
@ 2017-03-06 11:16         ` Arnd Bergmann
  2017-03-06 11:18           ` Arnd Bergmann
  0 siblings, 1 reply; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-06 11:16 UTC (permalink / raw)
  To: Arend Van Spriel
  Cc: kasan-dev, Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
	Networking, Linux Kernel Mailing List, linux-media,
	linux-wireless, kernel-build-reports, David S . Miller

On Mon, Mar 6, 2017 at 12:02 PM, Arend Van Spriel
<arend.vanspriel@broadcom.com> wrote:
> On 6-3-2017 11:38, Arnd Bergmann wrote:
>> On Mon, Mar 6, 2017 at 10:16 AM, Arend Van Spriel
>> <arend.vanspriel@broadcom.com> wrote:
>>> On 2-3-2017 17:38, Arnd Bergmann wrote:
>>>> The wlc_phy_table_write_nphy/wlc_phy_table_read_nphy functions always put an object
>>>> on the stack, which will each require a redzone with KASAN and lead to possible
>>>> stack overflow:
>>>>
>>>> drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c: In function 'wlc_phy_workarounds_nphy':
>>>> drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c:17135:1: warning: the frame size of 6312 bytes is larger than 1000 bytes [-Wframe-larger-than=]
>>>
>>> Looks like this warning text ended up in the wrong commit message. Got
>>> me confused for a sec :-p
>>
>> What's wrong about the warning?
>
> The warning is about the function 'wlc_phy_workarounds_nphy' (see PATCH
> 9/26) and not about wlc_phy_table_write_nphy/wlc_phy_table_read_nphy
> functions.

The warning only shows up for wlc_phy_workarounds_nphy, and we have to
fix both issues to get the size down enough. If we split it up without
uninlining the register access functions, we end up with two or three smaller
functions that still exceed the limit.

>>>> This marks the two functions as noinline_for_kasan, avoiding the problem entirely.
>>>
>>> Frankly I seriously dislike annotating code for the sake of some
>>> (dynamic) memory analyzer. To me the whole thing seems rather
>>> unnecessary. If the code passes the 2048 stack limit without KASAN it
>>> would seem the limit with KASAN should be such that no warning is given.
>>> I suspect that it is rather difficult to predict the additional size of
>>> the instrumentation code and on some systems there might be a real issue
>>> with increased stack usage.
>>
>> The frame sizes don't normally change that much. There are a couple of
>> drivers like brcmsmac that repeatedly call an inline function which has
>> a local variable that it passes by reference to an extern function.
>>
>> While normally those variables share a stack location, KASAN forces
>> each instance to its own location and adds (in this case) 80 bytes of
>> redzone around it to detect out-of-bounds access.
>>
>> While most drivers are fine with a 1500 byte warning limit, increasing
>> the limit to 7kb would silence brcmsmac (unless more registers
>> are accessed from wlc_phy_workarounds_nphy) but also risk a
>> stack overflow to go unnoticed.
>
> Given the amount of local variables maybe just tag the functions with
> noinline instead.

But that would result in less efficient object code without KASAN,
as inlining these by default is a good idea when the stack variables
all get folded.

     Arnd

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 07/26] brcmsmac: reduce stack size with KASAN
  2017-03-06 11:16         ` Arnd Bergmann
@ 2017-03-06 11:18           ` Arnd Bergmann
  0 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-06 11:18 UTC (permalink / raw)
  To: Arend Van Spriel
  Cc: kasan-dev, Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
	Networking, Linux Kernel Mailing List, linux-media,
	linux-wireless, kernel-build-reports, David S . Miller

On Mon, Mar 6, 2017 at 12:16 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Mon, Mar 6, 2017 at 12:02 PM, Arend Van Spriel
> <arend.vanspriel@broadcom.com> wrote:
>> On 6-3-2017 11:38, Arnd Bergmann wrote:
>>> On Mon, Mar 6, 2017 at 10:16 AM, Arend Van Spriel
>>> <arend.vanspriel@broadcom.com> wrote:

>> Given the amount of local variables maybe just tag the functions with
>> noinline instead.
>
> But that would result in less efficient object code without KASAN,
> as inlining these by default is a good idea when the stack variables
> all get folded.

Note that David Laight alread suggested renaming noinline_for_kasan
to noinline_if_stackbloat, which makes it a little more obvious what
is going on. Would that address your concern as well?

    Arnd

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 08/26] brcmsmac: make some local variables 'static const' to reduce stack size
  2017-03-06  9:30   ` Arend Van Spriel
@ 2017-03-06 16:19     ` Kalle Valo
  2017-03-06 21:34       ` Arnd Bergmann
  0 siblings, 1 reply; 67+ messages in thread
From: Kalle Valo @ 2017-03-06 16:19 UTC (permalink / raw)
  To: Arend Van Spriel, Arnd Bergmann
  Cc: kasan-dev, Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
	netdev, linux-kernel, linux-media, linux-wireless,
	kernel-build-reports, David S . Miller

Arend Van Spriel <arend.vanspriel@broadcom.com> writes:

> On 2-3-2017 17:38, Arnd Bergmann wrote:
>> With KASAN and a couple of other patches applied, this driver is one
>> of the few remaining ones that actually use more than 2048 bytes of
>> kernel stack:
>> 
>> broadcom/brcm80211/brcmsmac/phy/phy_n.c: In function 'wlc_phy_workarounds_nphy_gainctrl':
>> broadcom/brcm80211/brcmsmac/phy/phy_n.c:16065:1: warning: the frame size of 3264 bytes is larger than 2048 bytes [-Wframe-larger-than=]
>> broadcom/brcm80211/brcmsmac/phy/phy_n.c: In function 'wlc_phy_workarounds_nphy':
>> broadcom/brcm80211/brcmsmac/phy/phy_n.c:17138:1: warning: the frame size of 2864 bytes is larger than 2048 bytes [-Wframe-larger-than=]
>> 
>> Here, I'm reducing the stack size by marking as many local variables as
>> 'static const' as I can without changing the actual code.
>
> Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>

Arnd, via which tree are you planning to submit these? I'm not sure
what I should do with the wireless drivers patches from this series.

-- 
Kalle Valo

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 10/26] brcmsmac: reindent split functions
  2017-03-06  9:33   ` Arend Van Spriel
@ 2017-03-06 16:24     ` Kalle Valo
  0 siblings, 0 replies; 67+ messages in thread
From: Kalle Valo @ 2017-03-06 16:24 UTC (permalink / raw)
  To: Arend Van Spriel
  Cc: Arnd Bergmann, kasan-dev, Andrey Ryabinin, Alexander Potapenko,
	Dmitry Vyukov, netdev, linux-kernel, linux-media, linux-wireless,
	kernel-build-reports, David S . Miller

Arend Van Spriel <arend.vanspriel@broadcom.com> writes:

> On 2-3-2017 17:38, Arnd Bergmann wrote:
>> In the previous commit I left the indentation alone to help reviewing
>> the patch, this one now runs the three new functions through 'indent -kr -8'
>> with some manual fixups to avoid silliness.
>> 
>> No changes other than whitespace are intended here.
>
> Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
>> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
>> ---
>>  .../broadcom/brcm80211/brcmsmac/phy/phy_n.c        | 1507 +++++++++-----------
>>  1 file changed, 697 insertions(+), 810 deletions(-)
>> 

Arend, please edit your quotes. Leaving 1000 lines of unnecessary quotes
in your reply makes my use of patchwork horrible:

https://patchwork.kernel.org/patch/9601155/

-- 
Kalle Valo

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 08/26] brcmsmac: make some local variables 'static const' to reduce stack size
  2017-03-06 16:19     ` Kalle Valo
@ 2017-03-06 21:34       ` Arnd Bergmann
  2017-03-07  9:44         ` Kalle Valo
  0 siblings, 1 reply; 67+ messages in thread
From: Arnd Bergmann @ 2017-03-06 21:34 UTC (permalink / raw)
  To: Kalle Valo
  Cc: Arend Van Spriel, kasan-dev, Andrey Ryabinin,
	Alexander Potapenko, Dmitry Vyukov, Networking,
	Linux Kernel Mailing List, linux-media, linux-wireless,
	kernel-build-reports, David S . Miller

On Mon, Mar 6, 2017 at 5:19 PM, Kalle Valo <kvalo@codeaurora.org> wrote:
> Arend Van Spriel <arend.vanspriel@broadcom.com> writes:
>
>> On 2-3-2017 17:38, Arnd Bergmann wrote:
>>> With KASAN and a couple of other patches applied, this driver is one
>>> of the few remaining ones that actually use more than 2048 bytes of
>>> kernel stack:
>>>
>>> broadcom/brcm80211/brcmsmac/phy/phy_n.c: In function 'wlc_phy_workarounds_nphy_gainctrl':
>>> broadcom/brcm80211/brcmsmac/phy/phy_n.c:16065:1: warning: the frame size of 3264 bytes is larger than 2048 bytes [-Wframe-larger-than=]
>>> broadcom/brcm80211/brcmsmac/phy/phy_n.c: In function 'wlc_phy_workarounds_nphy':
>>> broadcom/brcm80211/brcmsmac/phy/phy_n.c:17138:1: warning: the frame size of 2864 bytes is larger than 2048 bytes [-Wframe-larger-than=]
>>>
>>> Here, I'm reducing the stack size by marking as many local variables as
>>> 'static const' as I can without changing the actual code.
>>
>> Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
>
> Arnd, via which tree are you planning to submit these? I'm not sure
> what I should do with the wireless drivers patches from this series.

I'm not quite sure myself yet. I'd probably want the first few patches that
do most of the work get merged through Andrew's linux-mm tree once
we have come to agreement on them. The driver specific patches like
the brcmsmac ones depend on the introduction of noinline_for_kasan
or noinline_if_stackbloat and could either go in along with the first
set, or as a follow-up through the normal maintainer trees.

       Arnd

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 08/26] brcmsmac: make some local variables 'static const' to reduce stack size
  2017-03-06 21:34       ` Arnd Bergmann
@ 2017-03-07  9:44         ` Kalle Valo
  2017-03-07  9:55           ` Arend Van Spriel
  0 siblings, 1 reply; 67+ messages in thread
From: Kalle Valo @ 2017-03-07  9:44 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Arend Van Spriel, kasan-dev, Andrey Ryabinin,
	Alexander Potapenko, Dmitry Vyukov, Networking,
	Linux Kernel Mailing List, linux-media, linux-wireless,
	kernel-build-reports, David S . Miller

Arnd Bergmann <arnd@arndb.de> writes:

> On Mon, Mar 6, 2017 at 5:19 PM, Kalle Valo <kvalo@codeaurora.org> wrote:
>> Arend Van Spriel <arend.vanspriel@broadcom.com> writes:
>>
>>> On 2-3-2017 17:38, Arnd Bergmann wrote:
>>>> With KASAN and a couple of other patches applied, this driver is one
>>>> of the few remaining ones that actually use more than 2048 bytes of
>>>> kernel stack:
>>>>
>>>> broadcom/brcm80211/brcmsmac/phy/phy_n.c: In function
>>>> 'wlc_phy_workarounds_nphy_gainctrl':
>>>> broadcom/brcm80211/brcmsmac/phy/phy_n.c:16065:1: warning: the
>>>> frame size of 3264 bytes is larger than 2048 bytes
>>>> [-Wframe-larger-than=]
>>>> broadcom/brcm80211/brcmsmac/phy/phy_n.c: In function 'wlc_phy_workarounds_nphy':
>>>> broadcom/brcm80211/brcmsmac/phy/phy_n.c:17138:1: warning: the
>>>> frame size of 2864 bytes is larger than 2048 bytes
>>>> [-Wframe-larger-than=]
>>>>
>>>> Here, I'm reducing the stack size by marking as many local variables as
>>>> 'static const' as I can without changing the actual code.
>>>
>>> Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
>>
>> Arnd, via which tree are you planning to submit these? I'm not sure
>> what I should do with the wireless drivers patches from this series.
>
> I'm not quite sure myself yet. I'd probably want the first few patches that
> do most of the work get merged through Andrew's linux-mm tree once
> we have come to agreement on them. The driver specific patches like
> the brcmsmac ones depend on the introduction of noinline_for_kasan
> or noinline_if_stackbloat and could either go in along with the first
> set, or as a follow-up through the normal maintainer trees.

Either way is fine for me. Just mark clearly if you want the wireless
drivers patches to go through via my tree, otherwise I'll ignore them.

-- 
Kalle Valo

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 08/26] brcmsmac: make some local variables 'static const' to reduce stack size
  2017-03-07  9:44         ` Kalle Valo
@ 2017-03-07  9:55           ` Arend Van Spriel
  0 siblings, 0 replies; 67+ messages in thread
From: Arend Van Spriel @ 2017-03-07  9:55 UTC (permalink / raw)
  To: Kalle Valo, Arnd Bergmann
  Cc: kasan-dev, Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
	Networking, Linux Kernel Mailing List, linux-media,
	linux-wireless, kernel-build-reports, David S . Miller

On 7-3-2017 10:44, Kalle Valo wrote:
> Arnd Bergmann <arnd@arndb.de> writes:
> 
>> On Mon, Mar 6, 2017 at 5:19 PM, Kalle Valo <kvalo@codeaurora.org> wrote:
>>> Arend Van Spriel <arend.vanspriel@broadcom.com> writes:
>>>
>>>> On 2-3-2017 17:38, Arnd Bergmann wrote:
>>>>> With KASAN and a couple of other patches applied, this driver is one
>>>>> of the few remaining ones that actually use more than 2048 bytes of
>>>>> kernel stack:
>>>>>
>>>>> broadcom/brcm80211/brcmsmac/phy/phy_n.c: In function
>>>>> 'wlc_phy_workarounds_nphy_gainctrl':
>>>>> broadcom/brcm80211/brcmsmac/phy/phy_n.c:16065:1: warning: the
>>>>> frame size of 3264 bytes is larger than 2048 bytes
>>>>> [-Wframe-larger-than=]
>>>>> broadcom/brcm80211/brcmsmac/phy/phy_n.c: In function 'wlc_phy_workarounds_nphy':
>>>>> broadcom/brcm80211/brcmsmac/phy/phy_n.c:17138:1: warning: the
>>>>> frame size of 2864 bytes is larger than 2048 bytes
>>>>> [-Wframe-larger-than=]
>>>>>
>>>>> Here, I'm reducing the stack size by marking as many local variables as
>>>>> 'static const' as I can without changing the actual code.
>>>>
>>>> Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
>>>
>>> Arnd, via which tree are you planning to submit these? I'm not sure
>>> what I should do with the wireless drivers patches from this series.
>>
>> I'm not quite sure myself yet. I'd probably want the first few patches that
>> do most of the work get merged through Andrew's linux-mm tree once
>> we have come to agreement on them. The driver specific patches like
>> the brcmsmac ones depend on the introduction of noinline_for_kasan
>> or noinline_if_stackbloat and could either go in along with the first
>> set, or as a follow-up through the normal maintainer trees.
> 
> Either way is fine for me. Just mark clearly if you want the wireless
> drivers patches to go through via my tree, otherwise I'll ignore them.

That (dreaded) phy code does not get a lot of changes so I think it does
not matter which tree is will go through in terms of risk for conflicts.
So going through linux-mm is fine for me as well.

Regards,
Arend

^ permalink raw reply	[flat|nested] 67+ messages in thread

end of thread, other threads:[~2017-03-07 10:04 UTC | newest]

Thread overview: 67+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-02 16:38 [PATCH 00/26] bring back stack frame warning with KASAN Arnd Bergmann
2017-03-02 16:38 ` [PATCH 01/26] compiler: introduce noinline_for_kasan annotation Arnd Bergmann
2017-03-03 13:50   ` Andrey Ryabinin
2017-03-03 13:55     ` Alexander Potapenko
2017-03-03 14:30       ` Arnd Bergmann
2017-03-03 14:33         ` Alexander Potapenko
2017-03-03 14:51           ` Arnd Bergmann
2017-03-03 16:34     ` David Laight
2017-03-02 16:38 ` [PATCH 02/26] rewrite READ_ONCE/WRITE_ONCE Arnd Bergmann
2017-03-02 16:51   ` Christian Borntraeger
2017-03-02 17:55     ` Arnd Bergmann
2017-03-02 19:00       ` Christian Borntraeger
2017-03-02 21:45         ` Arnd Bergmann
2017-03-03  8:26           ` Christian Borntraeger
2017-03-03  9:54             ` Arnd Bergmann
2017-03-03 14:49             ` Peter Zijlstra
2017-03-03 14:57               ` Peter Zijlstra
2017-03-02 16:38 ` [PATCH 03/26] typecheck.h: avoid local variables in typecheck() macro Arnd Bergmann
2017-03-02 16:38 ` [PATCH 04/26] tty: kbd: reduce stack size with KASAN Arnd Bergmann
2017-03-02 16:38 ` [PATCH 05/26] netlink: mark nla_put_{u8,u16,u32} noinline_for_kasan Arnd Bergmann
2017-03-02 16:38 ` [PATCH 06/26] rocker: mark rocker_tlv_put_* functions as noinline_for_kasan Arnd Bergmann
2017-03-02 16:38 ` [PATCH 07/26] brcmsmac: reduce stack size with KASAN Arnd Bergmann
2017-03-06  9:16   ` Arend Van Spriel
2017-03-06 10:38     ` Arnd Bergmann
2017-03-06 11:02       ` Arend Van Spriel
2017-03-06 11:16         ` Arnd Bergmann
2017-03-06 11:18           ` Arnd Bergmann
2017-03-02 16:38 ` [PATCH 08/26] brcmsmac: make some local variables 'static const' to reduce stack size Arnd Bergmann
2017-03-06  9:30   ` Arend Van Spriel
2017-03-06 16:19     ` Kalle Valo
2017-03-06 21:34       ` Arnd Bergmann
2017-03-07  9:44         ` Kalle Valo
2017-03-07  9:55           ` Arend Van Spriel
2017-03-02 16:38 ` [PATCH 09/26] brcmsmac: split up wlc_phy_workarounds_nphy Arnd Bergmann
2017-03-06  9:31   ` Arend Van Spriel
2017-03-02 16:38 ` [PATCH 10/26] brcmsmac: reindent split functions Arnd Bergmann
2017-03-06  9:33   ` Arend Van Spriel
2017-03-06 16:24     ` Kalle Valo
2017-03-02 16:38 ` [PATCH 11/26] rtlwifi: reduce stack usage for KASAN Arnd Bergmann
2017-03-02 16:38 ` [PATCH 12/26] wl3501_cs: reduce stack size " Arnd Bergmann
2017-03-02 16:38 ` [PATCH 13/26] rtl8180: " Arnd Bergmann
2017-03-02 16:38 ` [PATCH 14/26] [media] dvb-frontends: reduce stack size in i2c access Arnd Bergmann
2017-03-02 16:38 ` [PATCH 15/26] [media] tuners: i2c: reduce stack usage for tuner_i2c_xfer_* Arnd Bergmann
2017-03-02 16:38 ` [PATCH 16/26] [media] i2c: adv7604: mark register access as noinline_for_kasan Arnd Bergmann
2017-03-02 16:38 ` [PATCH 17/26] [media] i2c: ks0127: reduce stack frame size for KASAN Arnd Bergmann
2017-03-02 16:38 ` [PATCH 18/26] [media] i2c: cx25840: avoid stack overflow with KASAN Arnd Bergmann
2017-03-02 16:38 ` [PATCH 19/26] [media] r820t: mark register functions as noinline_for_kasan Arnd Bergmann
2017-03-02 16:38 ` [PATCH 20/26] [media] em28xx: split up em28xx_dvb_init to reduce stack size Arnd Bergmann
2017-03-02 16:38 ` [PATCH 21/26] drm/bridge: ps8622: reduce stack size for KASAN Arnd Bergmann
2017-03-02 16:38 ` [PATCH 22/26] drm/i915/gvt: don't overflow the kernel stack with KASAN Arnd Bergmann
2017-03-02 16:38 ` [PATCH 23/26] mtd: cfi: reduce stack size " Arnd Bergmann
2017-03-02 16:38 ` [PATCH 24/26] ocfs2: " Arnd Bergmann
2017-03-02 17:46   ` Joe Perches
2017-03-02 22:22     ` Arnd Bergmann
2017-03-02 22:40       ` Joe Perches
2017-03-02 22:59         ` Arnd Bergmann
2017-03-02 23:58           ` Joe Perches
2017-03-02 16:38 ` [PATCH 25/26] isdn: eicon: mark divascapi incompatible with kasan Arnd Bergmann
2017-03-03 14:20   ` Andrey Ryabinin
2017-03-03 14:54     ` Arnd Bergmann
2017-03-03 15:22       ` Andrey Ryabinin
2017-03-03 15:37         ` Arnd Bergmann
2017-03-02 16:38 ` [PATCH 26/26] kasan: rework Kconfig settings Arnd Bergmann
2017-03-03 14:51   ` Andrey Ryabinin
2017-03-03 15:03     ` Arnd Bergmann
2017-03-03 12:25 ` [PATCH 00/26] bring back stack frame warning with KASAN Alexander Potapenko
2017-03-03 12:54   ` Arnd Bergmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).