栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

为什么我可以在Linux内核模块中执行浮点运算?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

为什么我可以在Linux内核模块中执行浮点运算?

我以为您不能在Linux内核中执行浮点运算

您不能 放心 :不使用

kernel_fpu_begin()
/
kernel_fpu_end()
并不表示FPU指令会出错(至少不是在x86上)。

相反,它将以静默方式破坏用户空间的FPU状态。这是不好的; 不要那样做

编译器不知道是什么

kernel_fpu_begin()
意思,因此它无法检查/警告有关在FPU开始区域之外编译为FPU指令的代码。

可能存在一种调试模式,其中内核确实在

kernel_fpu_begin
/
end
区域之外禁用SSE,x87和MMX指令,但这会比较慢,并且默认情况下不会执行此操作。

但是,这是可能的:设置

CR0::TS = 1
会使x87指令出错,因此可以进行懒惰的FPU上下文切换,并且SSE和AVX还有其他位。


有问题的内核代码有 很多
方法可以引起严重的问题。这只是众多之一。在C语言中,您几乎总是知道何时使用浮点数(除非输入错误会导致

1.
常量或实际编译的上下文中的东西)。


FP架构状态为何与整数不同?

Linux必须在每次进入/退出内核时保存/恢复整数状态。所有代码都需要使用整数寄存器(FPU计算的巨型直线块以a

jmp
而不是a
ret
ret
修饰
rsp
)结尾)。

但是内核代码通常会避免使用FPU,因此Linux会将FPU状态保留为从系统调用进入时未保存的状态,仅在实际上下文切换到其他 用户空间
进程之前保存

kernel_fpu_begin
。否则,通常会在相同的内核上返回相同的用户空间进程,因此无需恢复FPU状态,因为内核没有碰到它。(这就是如果一个内核任务实际上做了修改FPU状态腐败会发生,我认为这是双向的:用户空间也可能会破坏
你的 FPU状态)。

整数状态非常小,只有16个64位寄存器+
RFLAGS和段寄存器。即使没有AVX,FPU状态也要大两倍:8个80位x87寄存器,16个XMM或YMM或32个ZMM寄存器(+
MXCSR和x87状态+控制字)。MPX

bnd0-4
寄存器也与“ FPU”集中在一起。此时,“
FPU状态”仅表示所有非整数寄存器。在我的Skylake上
dmesg
x86/fpu: Enabled xstate features 0x1f,context size is 960 bytes, using 'compacted' format.

请参阅了解Linux内核中FPU的用法。现代Linux默认情况下不对上下文切换执行惰性FPU上下文切换(仅用于内核/用户转换)。(但是那篇文章解释了什么是懒惰。)

大多数进程使用SSE复制/归零编译器生成的代码中的小块内存,大多数库字符串/ memcpy / memset实现使用SSE /
SSE2。而且,硬件支持的优化保存/恢复现在已经成为

xsaveopt
现实(/
xrstor),因此,如果尚未实际使用某些/所有FP寄存器,“急切”的FPU保存/恢复实际上可能会减少工作量。例如,如果将它们清零,则仅保存YMM寄存器的低128b,
vzeroupper
以便CPU知道它们是干净的。(并以保存格式中的一位来标记该事实。)

通过“紧急”上下文切换,FPU指令始终保持启用状态,因此不良的内核代码可以随时破坏它们。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/374902.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号