构建 Linux 内核源代码的
/drivers/staging/vt6655
部分时:
make M=drivers/staging/vt6655 C=2
sparse
抱怨drivers/staging/vt6655/card.c:302:45: warning: cast to restricted __le64
我熟悉:little endian、big endian、u64、le64_to_cpu、__force 等'....
但是,我找不到在不失去“代码完整性”的情况下修复此警告的解决方案。
这是包含有问题的转换的函数:
bool card_update_tsf(struct vnt_private *priv, unsigned char rx_rate, u64 qwBSSTimestamp)
{
u64 local_tsf;
u64 qwTSFOffset = 0;
local_tsf = vt6655_get_current_tsf(priv);
if (qwBSSTimestamp != local_tsf) {
qwTSFOffset = CARDqGetTSFOffset(rx_rate, qwBSSTimestamp,
local_tsf);
/* adjust TSF, HW's TSF add TSF Offset reg */
qwTSFOffset = (__force u64)le64_to_cpu(qwTSFOffset);
iowrite32((u32)qwTSFOffset, priv->port_offset + MAC_REG_TSFOFST);
iowrite32((u32)(qwTSFOffset >> 32), priv->port_offset + MAC_REG_TSFOFST + 4);
vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_TFTCTL, TFTCTL_TSFSYNCEN);
}
return true;
}
Sparse 是一个旨在通过静态分析发现 Linux 内核代码中潜在问题的工具。当 Sparse 警告“强制转换为受限制的
__le64
”时,通常表示特定于字节序的代码存在类型安全问题。
__le64
类型是为小端字节顺序的 64 位值定义的。当您执行到 __le64
的转换时,您应该确定该值采用该类型的正确字节顺序。该警告表明您正在将值转换为 __le64
,但未确保其采用小端格式,这可能会导致大端系统上的数据损坏。
有问题的线路是:
qwTSFOffset = (__force u64)le64_to_cpu(qwTSFOffset);
这里,
le64_to_cpu()
已经将 64 位小端值转换为 CPU 的本机端格式。如果 __force u64
在此调用后要保持 CPU 的本机字节序格式,则转换为 qwTSFOffset
是不必要且不正确的,这似乎是这种情况,因为您在本机中使用 iowrite32()
将其写入 IO 内存字节序。
要修复警告而不丢失“代码完整性”,您应该删除
__force
强制转换。你的代码应该是:
qwTSFOffset = le64_to_cpu(qwTSFOffset);
这是更正后的函数:
bool card_update_tsf(struct vnt_private *priv, unsigned char rx_rate, u64 qwBSSTimestamp)
{
u64 local_tsf;
u64 qwTSFOffset = 0;
local_tsf = vt6655_get_current_tsf(priv);
if (qwBSSTimestamp != local_tsf) {
qwTSFOffset = CARDqGetTSFOffset(rx_rate, qwBSSTimestamp, local_tsf);
// Convert little-endian TSF offset to CPU's endianness
qwTSFOffset = le64_to_cpu(qwTSFOffset);
// Write lower 32-bits of the TSF offset
iowrite32((u32)qwTSFOffset, priv->port_offset + MAC_REG_TSFOFST);
// Write upper 32-bits of the TSF offset
iowrite32((u32)(qwTSFOffset >> 32), priv->port_offset + MAC_REG_TSFOFST + 4);
// Enable TSF sync
vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_TFTCTL, TFTCTL_TSFSYNCEN);
}
return true;
}
此更改应该会删除稀疏警告。如果您打算将其作为补丁提交到 Linux 内核,请确保遵循内核的编码风格并根据内核的补丁提交流程进行提交。