Skip to content

Commit 7e0370f

Browse files
hackpascaltrini
authored andcommitted
miiphy: define mii_devs with LIST_HEAD()
When enabling net console and console multiplexing, a boot crash was observed using mtk_eth driver with stdin/stdout set to "serial,nc" in persistent environment: > CPU: MediaTek MT7981 > Model: OpenWrt One > DRAM: 1 GiB > Core: 35 devices, 15 uclasses, devicetree: separate > spi-nand: spi_nand spi_nand@0: Winbond SPI NAND was found. > spi-nand: spi_nand spi_nand@0: 128 MiB, block size: 128 KiB, page size: 2048, OOB size: 64 > Loading Environment from UBI... SF: Detected w25q128 with page size 256 Bytes, erase size 4 KiB, total 16 MiB > mtd: partition "ubi" extends beyond the end of device "spi-nand0" -- size truncated to 0x7f00000 > Read 126976 bytes from volume ubootenv to 000000007f7bf0c0 > Read 126976 bytes from volume ubootenv2 to 000000007f7de100 > OK > "Synchronous Abort" handler, esr 0x96000004, far 0xeafffffeea000018 > elr: 0000000041e63cd4 lr : 0000000041e1b844 (reloc) > elr: 000000007ff9ecd4 lr : 000000007ff56844 > x0 : eafffffeea000018 x1 : 000000007fb552e0 > x2 : 00000000000000fe x3 : 0000000000000000 The cause is that "serial,nc" forced the console subsystem to initialize the ethernet driver before ethernet subsystem initialization (console_init_r() is called before initr_net()). During the mtk_eth driver initialization, mdio_register() will be called, and miiphy_get_dev_by_name() will then be called. The miiphy_get_dev_by_name() will check the list "mii_devs" to see if the passed device name exists. However the mii_devs is defined without initialization: > static struct list_head mii_devs; and the actual initialization is done in the following chain: initr_net -> eth_initialize -> eth_common_init -> miiphy_init Since initr_net() hasn't be called, iterating over the mii_devs will access to physical address 0 (mii_devs.next == NULL) and will cause the crash. The fix is to define mii_devs using: > static LIST_HEAD(mii_devs); As the "current_mii" is defined as a static variable, it will always be NULL in board_r stage and initializing it will NULL is unnecessary. So the entire miiphy_init() can be remove. Signed-off-by: Weijie Gao <[email protected]>
1 parent e34aa29 commit 7e0370f

File tree

3 files changed

+1
-18
lines changed

3 files changed

+1
-18
lines changed

common/miiphyutil.c

+1-11
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
#define debug(fmt, args...)
3131
#endif /* MII_DEBUG */
3232

33-
static struct list_head mii_devs;
33+
static LIST_HEAD(mii_devs);
3434
static struct mii_dev *current_mii;
3535

3636
/*
@@ -55,16 +55,6 @@ struct mii_dev *miiphy_get_dev_by_name(const char *devname)
5555
return NULL;
5656
}
5757

58-
/*****************************************************************************
59-
*
60-
* Initialize global data. Need to be called before any other miiphy routine.
61-
*/
62-
void miiphy_init(void)
63-
{
64-
INIT_LIST_HEAD(&mii_devs);
65-
current_mii = NULL;
66-
}
67-
6858
struct mii_dev *mdio_alloc(void)
6959
{
7060
struct mii_dev *bus;

include/miiphy.h

-2
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ int miiphy_is_1000base_x(const char *devname, unsigned char addr);
3333
int miiphy_link(const char *devname, unsigned char addr);
3434
#endif
3535

36-
void miiphy_init(void);
37-
3836
int miiphy_set_current_dev(const char *devname);
3937
const char *miiphy_get_current_dev(void);
4038
struct mii_dev *mdio_get_current_dev(void);

net/eth_common.c

-5
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,6 @@ int eth_env_set_enetaddr_by_index(const char *base_name, int index,
3131
void eth_common_init(void)
3232
{
3333
bootstage_mark(BOOTSTAGE_ID_NET_ETH_START);
34-
#if CONFIG_IS_ENABLED(ETH)
35-
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
36-
miiphy_init();
37-
#endif
38-
#endif
3934
}
4035

4136
int eth_mac_skip(int index)

0 commit comments

Comments
 (0)