我可以在内核代码中使用vpush/vpop吗?

3

我尝试在ko模块中添加一些汇编代码,简单来说:

asm volatile("vpush {d8}")

编译时发生错误:

Error: selected processor does not support ARM mode `vpush {d8}'

这是预期的吗?谢谢。
2个回答

3
一般来说,在内核开发中不使用浮点数。并非所有硬件都支持浮点运算,某些平台可能具有先进的电源功能,并且可以随时打开和关闭浮点单元。处理所有这些问题相当麻烦,你总是可以找到另一种解决方法来解决你的问题。
罗伯特·洛夫的《Linux内核开发》
引用如下: 不易使用浮点数 ... 在内核中使用浮点数需要手动保存和恢复浮点寄存器,还有其他可能的琐事。简短的答案是:不要这样做! 除了极少数情况外,内核中没有浮点运算。
更多信息请参见:https://dev59.com/uWYr5IYBdhLWcg3wLnVA#13886805 这是因为你的编译器调用未指定任何符合上述规范的mfpu指令,所以你会收到该错误消息。

2
请注意,只要编译支持(一些加密模块使用它),内核模式NEON是允许的,但仍然必须明确地包装在kernel_neon_begin()kernel_neon_end()中(这可能非常昂贵)。 - Notlikethat
@auselen,vpush不是浮点操作,实际上它是协处理器操作,对吗?那么内核不允许在协处理器上进行操作吗? - Bill Randerson
@BillRanderson,我认为将FPU称为协处理器在后期ARM架构中过于笼统。内核当然允许协处理器操作,但vpush {d8}看起来更像是一种通用的FP操作,而不是一些内核维护。 - auselen
@BillRanderson 浮点操作是协处理器操作(FPU在概念上仍然是协处理器)——这里的一般考虑因素确实也适用于其他实现定义的协处理器(例如iWMMX);它们必须被启动,访问被启用,任何当前状态都被保存等。 - Notlikethat
@Notlikethat,我只是想在内核中进行实验,通过mcr禁用FPU,然后发出一个VFP指令,看看我的机器会发生什么,你们能给出任何建议吗?我认为“mcr”只能在内核中完成,对吗? - Bill Randerson
@Bill 如果你只是想玩一下,那么只需在汇编中添加一个适当的.fpu...指令即可让它编译通过,然后欣赏机器在内核模式下发生未定义指令异常时的熊熊大火 - 请确保你的文件系统已同步(或可替换);) - Notlikethat

1

Kernel mode NEON (或vfp) 的主要缺点是寄存器状态必须保存/恢复,因为上下文切换可能随时发生。即使使用协处理器,挑战在于使任何用户可见的状态在其运行时看起来都相同。这就是这个问题的指导思想。

更近期的内核中,在浮点模拟里有一个 Kconfig KERNEL_MODE_NEON。支持 kernel mode NEON 受到限制,并且文档可以在 Documentation/arm/kernel_mode_neon.txt 找到。为了使 kernel_neon_begin()kernel_neon_end() 的寄存器保存/恢复工作,同时它们在使用时也禁用了抢占;否则调度程序必须知道某些内核模式已经改变了NEON/VFP状态并将其记录在某个地方。

你可以查看 KERNEL_MODE_NEON 提交,它对不同的GCC版本有限制,当使用-mpfu=neon编译时,可以在任何地方发出NEON代码;因此,任何对NEON编译单元的外部调用都应该用kernel_neon_begin()kernel_neon_end()包装起来。它应该存在于3.11内核中。


不应该使用可能会引发异常的NEON指令。 - artless noise

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接