• Arnd Bergmann's avatar
    hns: avoid stack overflow with CONFIG_KASAN · b3f2d07f
    Arnd Bergmann authored
    The use of ACCESS_ONCE() looks like a micro-optimization to force gcc to use
    an indexed load for the register address, but it has an absolutely detrimental
    effect on builds with gcc-5 and CONFIG_KASAN=y, leading to a very likely
    kernel stack overflow aside from very complex object code:
    
    hisilicon/hns/hns_dsaf_gmac.c: In function 'hns_gmac_update_stats':
    hisilicon/hns/hns_dsaf_gmac.c:419:1: error: the frame size of 2912 bytes is larger than 1024 bytes [-Werror=frame-larger-than=]
    hisilicon/hns/hns_dsaf_ppe.c: In function 'hns_ppe_reset_common':
    hisilicon/hns/hns_dsaf_ppe.c:390:1: error: the frame size of 1184 bytes is larger than 1024 bytes [-Werror=frame-larger-than=]
    hisilicon/hns/hns_dsaf_ppe.c: In function 'hns_ppe_get_regs':
    hisilicon/hns/hns_dsaf_ppe.c:621:1: error: the frame size of 3632 bytes is larger than 1024 bytes [-Werror=frame-larger-than=]
    hisilicon/hns/hns_dsaf_rcb.c: In function 'hns_rcb_get_common_regs':
    hisilicon/hns/hns_dsaf_rcb.c:970:1: error: the frame size of 2784 bytes is larger than 1024 bytes [-Werror=frame-larger-than=]
    hisilicon/hns/hns_dsaf_gmac.c: In function 'hns_gmac_get_regs':
    hisilicon/hns/hns_dsaf_gmac.c:641:1: error: the frame size of 5728 bytes is larger than 1024 bytes [-Werror=frame-larger-than=]
    hisilicon/hns/hns_dsaf_rcb.c: In function 'hns_rcb_get_ring_regs':
    hisilicon/hns/hns_dsaf_rcb.c:1021:1: error: the frame size of 2208 bytes is larger than 1024 bytes [-Werror=frame-larger-than=]
    hisilicon/hns/hns_dsaf_main.c: In function 'hns_dsaf_comm_init':
    hisilicon/hns/hns_dsaf_main.c:1209:1: error: the frame size of 1904 bytes is larger than 1024 bytes [-Werror=frame-larger-than=]
    hisilicon/hns/hns_dsaf_xgmac.c: In function 'hns_xgmac_get_regs':
    hisilicon/hns/hns_dsaf_xgmac.c:748:1: error: the frame size of 4704 bytes is larger than 1024 bytes [-Werror=frame-larger-than=]
    hisilicon/hns/hns_dsaf_main.c: In function 'hns_dsaf_update_stats':
    hisilicon/hns/hns_dsaf_main.c:2420:1: error: the frame size of 1088 bytes is larger than 1024 bytes [-Werror=frame-larger-than=]
    hisilicon/hns/hns_dsaf_main.c: In function 'hns_dsaf_get_regs':
    hisilicon/hns/hns_dsaf_main.c:2753:1: error: the frame size of 10768 bytes is larger than 1024 bytes [-Werror=frame-larger-than=]
    
    This does not seem to happen any more with gcc-7, but removing the ACCESS_ONCE
    seems safe anyway and it avoids a serious issue for some people. I have verified
    that with gcc-5.3.1, the object code we get is better in the new version
    both with and without CONFIG_KASAN, as we no longer allocate a 1344 byte
    stack frame for hns_dsaf_get_regs() but otherwise have practically identical
    object code.
    
    With gcc-7.0.0, removing ACCESS_ONCE has no effect, the object code is already
    good either way.
    
    This patch is probably not urgent to get into 4.11 as only KASAN=y builds
    with certain compilers are affected, but I still think it makes sense to
    backport into older kernels.
    
    Cc: stable@vger.kernel.org
    Fixes: 511e6bc0 ("net: add Hisilicon Network Subsystem DSAF support")
    Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    b3f2d07f
hns_dsaf_reg.h 39.8 KB