11

这与 这个问题有关

我不是 Linux 设备驱动程序或内核模块方面的专家,但我一直在阅读 Rubini & Corbet 的“Linux 设备驱动程序”[O'Reilly] 和一些在线资源,但我一直无法找到关于这个具体问题的任何事情。

何时允许内核或驱动程序模块使用浮点寄存器?
如果是这样,谁负责保存和恢复其内容?
(假设 x86-64 架构)

如果我理解正确,每当 KM 运行时,它都在使用已从某个应用程序线程抢占的硬件上下文(或硬件线程或寄存器集——无论您想调用什么)。如果您在 c 中编写 KM,编译器将正确确保通用寄存器正确保存和恢复(就像在应用程序中一样),但浮点寄存器不会自动发生这种情况。就此而言,许多 KM 甚至不能假设处理器具有任何浮点能力。

我猜想使用浮点的KM必须小心保存和恢复浮点状态是否正确?是否有这样做的标准内核函数?

是否在任何地方都说明了此编码约定?
对于非 SMP 驱动程序,它们是否不同?
对于较旧的非抢占式内核和较新的抢占式内核,它们是否不同?

4

2 回答 2

11

Linus 的回答提供了这个非常清晰的引用作为指导:

换句话说:规则是你真的不应该在内核中使用 FP。

于 2009-09-17T08:30:14.077 回答
8

kernel_fpu_begin()简短的回答:如果这个用法被/包围,内核代码可以使用浮点kernel_fpu_end()。这些函数处理保存和恢复 fpu 上下文。此外,它们调用preempt_disable()/ preempt_enable(),这意味着这些函数之间的代码中没有休眠、页面错误等。谷歌函数名称以获取更多信息。

如果我理解正确,每当 KM 运行时,它都在使用已从某个应用程序线程抢占的硬件上下文(或硬件线程或寄存器集——无论您想调用什么)。

不,内核模块也可以在用户上下文中运行(例如,当用户空间在 KM 提供的设备上调用系统调用时)。然而,它与浮动问题无关。

如果您在 c 中编写 KM,编译器将正确确保通用寄存器正确保存和恢复(就像在应用程序中一样),但浮点寄存器不会自动发生这种情况。

那不是因为编译器,而是因为内核上下文切换代码。

于 2009-01-10T16:55:12.207 回答