【7】net phy流程和Oops定位方式

本文详细解析了一个内核Oops问题,通过反汇编、GDB确认偏移及流程分析,定位到phy_attached_print函数中phy->drv为NULL的问题。在特定条件下,如链路linkdown或干扰,若phy_id不匹配驱动注册,将导致Oops。最新内核已通过判NULL修复此bug。

1、内核Oops了
遇到一个Oops的问题 ,发现phy_attached_print发送了Oops,死的原因是访问了NULL指针偏移0x88的地方

Oops的原始日志:

在这里插入图片描述
2、反汇编vmlinux

反汇编kernel后发现phy_attached_print+0x90的地址对应ffffff80084ad2b8,这句汇编的意思就是把X1+136(0x88)的值赋值给X2

从上面call trace也可以看到X1确实为NULL的,导致Oops的地址是0x88,和X1+0x88是对应起来的,那么现在的问题就是定位为什么X1变成了NULL
在这里插入图片描述
对应的C代码,函数phy_attached_print,从上下文分析phydev肯定不是空的,那么phy->drv的嫌疑就比较大了,至于是不是phy->drv为NULL,可以通过分析偏移确定。
在这里插入图片描述
3、gdb确认偏移
使用GDB工具print一下phydev->drv->name,看到name对应的偏移就是0x88,可以确认phy->drv是NULL
在这里插入图片描述
4、分析流程
看了看日志上下文也没有什么异常,为什么phydev→drv会为NULL,下面是net phy的driver的流程,可以看到

只要get_phy_id从reg获取的phy_id和调用 phy_drivers_register 注册的driver中的phy_id不匹配,换句话说就是reg中读取的phy_id没有对应的驱动注册,那么phy_attached_print就会Oops

(眨眼)net phy的流程如下
优快云上传附件非常不方便,见我的下载里面
在这里插入图片描述

5、打桩复现
既然流程分析清楚了,我们把broadcom BCM50612E phy_driver的phyid改成一个不合法的值,人为制造reg获取的phy_id和调用 phy_drivers_register 注册的driver中的phy_id不匹配的场景(从寄存器获取的phyid非法不好构造,但是我们可以修改代码中期望的phyid,只要两者不同就可以了)。

果然Oops了,并且Oops的地址和call trace的打印和前面的一致。说明某种情况下,比如收到干扰或者链路linkdown,如果从寄存器读取的phyid和代码中的phyid不匹配,就会出现Oops
在这里插入图片描述
6、kernel主线怎么修复?
既然这么明显一个bug,其他人应该早就遇到了,看了下最新的内核代码,果然这个bug已经修复了,修复方法竟然是判NULL,而不是reg获取的phy_id和调用 phy_drivers_register 注册的driver中的phy_id不匹配认为probe失败

内核的patch如下

patch 1、修复空指针

https://lore.kernel.org/patchwork/patch/824257/

patch 2、删除deadcode

https://lore.kernel.org/patchwork/patch/825029/
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

linjiasen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值