为什么我能够在 Linux 内核模块内执行浮点运算?

2023-12-03

我在 x86 CentOS 6.3(内核 v2.6.32)系统上运行。

我将以下函数编译到一个简单的字符驱动程序模块中作为实验,以了解 Linux 内核对浮点运算的反应。

static unsigned floatstuff(void){
    float x = 3.14;
    x *= 2.5;
    return x;
}

...

printk(KERN_INFO "x: %u", x);

代码已编译(这不是预期的),所以我插入了模块并检查了日志dmesg。日志显示:x: 7.

这看起来很奇怪;我以为你不能在 Linux 内核中执行浮点运算——保存一些异常,例如kernel_fpu_begin()。模块是如何进行浮点运算的?

这是因为我使用的是 x86 处理器吗?


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

你不能safely: 无法使用kernel_fpu_begin() / kernel_fpu_end()并不意味着 FPU 指令会出错(至少在 x86 上不会)。

相反,它会默默地破坏用户空间的 FPU 状态。这不好;不要那样做。

编译器不知道什么kernel_fpu_begin()意味着,因此它无法检查/警告在 FPU 开始区域之外编译为 FPU 指令的代码。

可能有一种调试模式,内核会在外部禁用 SSE、x87 和 MMX 指令kernel_fpu_begin / end区域,但这会比较慢并且默认情况下不会这样做。

不过,这是可能的:设置CR0::TS = 1使 x87 指令出现故障,因此可以进行惰性 FPU 上下文切换,并且还有用于 SSE 和 AVX 的其他位。


many有缺陷的内核代码导致严重问题的方法。这只是众多之一。在 C 中,您几乎总是知道何时使用浮点(除非拼写错误导致1.常量或实际编译上下文中的某些内容)。


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

Linux 在每次进入/退出内核时都必须保存/恢复整数状态。所有代码都需要使用整数寄存器(除了以 FPU 计算结尾的巨大直线块)jmp代替ret (ret修改rsp).)

但内核代码通常会避免 FPU,因此 Linux 在系统调用进入时不保存 FPU 状态,仅在实际上下文切换到不同的上下文之前保存用户空间过程或kernel_fpu_begin。否则,返回到同一内核上的同一用户空间进程是很常见的,因此不需要恢复 FPU 状态,因为内核没有触及它。 (如果内核任务确实修改了 FPU 状态,这就是发生损坏的地方。我认为这是双向的:用户空间也可能损坏yourFPU 状态)。

整数状态相当小,只有 16 个 64 位寄存器 + RFLAGS 和段寄存器。即使没有 AVX,FPU 状态也会大两倍以上:8 个 80 位 x87 寄存器,以及 16 个 XMM 或 YMM,或 32 个 ZMM 寄存器(+ MXCSR 和 x87 状态 + 控制字)。还有MPXbnd0-4寄存器集中在“FPU”中。此时“FPU 状态”仅表示所有非整数寄存器。在我的天湖上,dmesg says x86/fpu: Enabled xstate features 0x1f, context size is 960 bytes, using 'compacted' format.

See 了解Linux内核中FPU的使用;现代 Linux 默认情况下不会为上下文切换执行惰性 FPU 上下文切换(仅适用于内核/用户转换)。 (但那篇文章解释了 Lazy 是什么。)

大多数进程使用 SSE 在编译器生成的代码中复制/清零小内存块,并且大多数库 string/memcpy/memset 实现使用 SSE/SSE2。此外,硬件支持的优化保存/恢复现在已经成为一件事(xsaveopt/ xrstor),因此,如果某些/所有 FP 寄存器实际上尚未使用,“急切的”FPU 保存/恢复实际上可能会做更少的工作。例如仅保存 YMM 寄存器的低 128b(如果它们被清零)vzeroupper所以CPU知道它们是干净的。 (并在保存格式中仅用一位来标记这一事实。)

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么我能够在 Linux 内核模块内执行浮点运算? 的相关文章

  • C++ 中的“int”默认是“signed long int”吗?

    Is int默认情况下signed long int in C 它是否依赖于平台和 或编译器 如果是这样 怎么办 EDIT 以下任何一项是否保证是重复的 signed short int signed int signed long int
  • C# - Visual Studio 中的 System.OutOfMemoryException

    我遇到问题 当我右键单击 Visual Studio 中的主窗体并转到 视图设计器 时 出现错误 它说 引发了 System OutOfMemoryException 类型的异常 堆栈跟踪 at System Reflection Asse
  • 无需登录即可在 Intranet 上获取 Web 应用程序的域\用户名

    我的 Intranet 上有一个 Web 应用程序 VS 2005 有几个页面不需要用户登录应用程序 反馈和默认页面 我正在尝试获取要显示和 或发送反馈的域名和用户名 有没有一种方法可以在不需要用户登录的情况下执行此操作 我试过了this
  • BufferBlock 连续

    我想使用以下方式实现消费者 生产者模式BufferBlock
  • 在异步请求中使用超时回调

    我之前问过这个问题 但我将用提出的解决方案来完成这个问题 并提出另一个问题 我正在使用这个类来进行异步网络请求 http msdn microsoft com en us library system net webrequest aspx
  • 如何在 ASP.NET Core 6.0 Web API 项目中启用 cors?

    在我的 ASP NET Core 6 0 Web API 项目中配置了 CORS 但预检请求收到 http 405 错误 换句话说 不允许使用 HTTP OPTION 看起来 cors 没有启用 我见过的例子config EnableCor
  • AcceptSocket 超时?

    是否有可能AcceptSocket on a TcpListener具有超时的对象 以便它偶尔被中断 TcpListener server new TcpListener localIP port server Start while sh
  • 应用新设置时如何防止 GraphicsDevice 被丢弃?

    我的游戏窗口允许手动调整大小 这意味着它可以像任何其他普通窗口一样通过拖动其边缘来调整大小 游戏还利用了RenderTarget2D rt2d 在主 Draw 方法中设置主渲染目标 GraphicsDevice SetRenderTarge
  • += 运算符在 C++ 中是如何实现的?

    这是我一直在思考的一个问题 但从未找到任何资源来说明这个问题的答案 事实上它不仅是为了 也适用于它的兄弟姐妹 即 等等 当然不是 考虑这个例子 int a 5 a 4 this will make a 9 现在考虑等效表达式 a a 4 T
  • 多个线程访问一个变量

    我在正在读的一本教科书中发现了这个问题 下面也给出了解决方案 我无法理解最小值怎么可能是 2 为什么一个线程不能读取 0 而所有其他线程都执行并写入 1 而无论是1还是2 最后写入的线程仍然必须完成自己的循环 int n 0 int mai
  • 原子的 C++ 内存屏障

    在这方面我是个新手 谁能提供以下内存屏障之间差异的简化解释 窗户MemoryBarrier 围栏 mm mfence 内联汇编asm volatile memory 内在的 ReadWriteBarrier 如果没有简单的解释 一些好文章或
  • 如何使用 C# 将表格粘贴到 Ms-Word 文档的末尾

    我有一个预制的 Word 模板 其中有一个表格 我想打开它 然后在文档末尾添加 粘贴 另一个表格 问题是它不会转到文档的末尾 而是将新表格粘贴到原始表格的第一个单元格中 任何帮助将不胜感激 previous code copied a ta
  • Code::Blocks 中的调试似乎不起作用 - 缺少调试符号

    我正在尝试在 Code Blocks 中调试程序 我跟着本指南 http wiki codeblocks org index php title Debugging with Code Blocks and 这个短视频 http www y
  • 亚马逊 Linux - 安装 openjdk-debuginfo?

    我试图使用jstack在 ec2 实例上amazon linux 所以我安装了openjdk devel包裹 sudo yum install java 1 7 0 openjdk devel x86 64 但是 jstack 引发了异常j
  • 按 Enter 继续

    这不起作用 string temp cout lt lt Press Enter to Continue cin gt gt temp cout lt lt Press Enter to Continue cin ignore 或更好 in
  • 检查另一种形式的线程是否仍在运行

    我有一个涉及两个窗体的 Windows 窗体应用程序 子表单用于将数据导出到 CSV 文件 并使用后台工作者写入文件 当这种情况发生时 我隐藏了表格 当后台工作程序运行时 父窗体仍然处于活动状态 因此即使后台工作程序正在写入文件 用户也可以
  • 使用方法的状态模式

    我正在尝试使用方法作为状态而不是类来基于状态模式的修改版本来实现一个简单的状态机 如下所示 private Action
  • 如何回忆上一个 bash 命令的参数?

    Bash 有没有办法回忆上一个命令的参数 我通常这样做vi file c其次是gcc file c Bash 有没有办法回忆上一个命令的参数 您可以使用 or 调用上一个命令的最后一个参数 Also Alt can be used to r
  • execlp() 系统调用输出错误

    这个非常简单的例子exec 系统调用 在这里 我试图打电话execlp 两次 但是 我没有得到例外的输出 它仅显示当前目录的第一次调用的输出 include
  • 线程安全的有限大小队列,不使用锁

    我正在尝试编写一个主题队列 但遇到死锁和其他多线程问题 我想用Interlocked CompareExchange避免lock用法 但这段代码并没有按预期工作 它只是擦除整个队列 我在这里做错了什么 public class FixedS

随机推荐

  • Jersey REST 服务上的用户身份验证

    我正在开发一个 REST 应用程序 它使用 Jersey 框架 我想知道如何控制用户身份验证 我查了很多地方 找到最接近的文章是这样的 http weblogs java net blog 2008 03 07 authentication
  • 当 RecyclerView 正在计算布局或尝试从 recyclerview 中删除项目时滚动时,无法调用此方法

    我正在尝试从 recyclerview 中删除我的项目 但我总是收到错误 java lang IllegalStateException 无法调用此方法 RecyclerView 正在计算布局或滚动 我正在使用notify datasetc
  • DataTable Wrapper 或如何将 UI 与业务逻辑解耦

    我正在使用 Web 表单 C Asp net 众所周知 在这个模型中 UI和业务逻辑经常是混合在一起的 如何有效地将它们分开呢 我想使用的例子是 我有一个 GridView 和一个 DataTable GridView 绑定到 DataTa
  • 引用类型作为参数

    所以我深入阅读 Jon Skeet 的 C 并遇到了一些误解 比如引用类型总是通过 ref 传递 所以我决定自己做一个小实验 正如您在下面的代码中看到的 我有一个简单的 Car 类 其中一个属性在调用构造函数时初始化为 500 我还有 Nu
  • 在多个图中添加单独的箭头

    我想在用 ggplot 和 faceting 生成的 2 个图中添加箭头 问题 如何避免两个图中的箭头重复 我想为每个图添加单独的箭头 这是一个例子 library ggplot2 data frame with fake data xdf
  • Ruby 三元运算符结构

    puts bool true false 是正确的 但是 bool puts true puts false 不是 有人可以向我解释这是为什么吗 边注 bool puts true puts false 效果也很好 当您不在方法调用上添加括
  • Rails:如何将 i18n 与 Rails 4 枚举一起使用

    Rails 4 活动记录枚举很棒 但是使用 i18n 进行翻译的正确模式是什么 从Rails 5开始 所有模型都将继承自ApplicationRecord class User lt ApplicationRecord enum statu
  • SVG 未在 Windows Phone 8 Phonegap 应用程序中显示

    似乎无法找到任何答案 使用 Phonegap 并使用 SVG 图像开发 HTML5 应用程序 从 Adob e Illustrator 的 另存为 中保存它们 然后像 HTML 中的普通图像一样使用它们 img src img the im
  • 组合框中的热跟踪列表项选择

    我有一个组合框 当用户仅通过鼠标悬停来更改选择时 我需要拦截选择的更改without点击 这是为了显示有关用户将鼠标悬停在其上的项目的补充信息 CBN SELCHANGE不会完成这项工作 因为只有当用户有actually通过单击组合框项目之
  • git stash pop 和 git stash apply 之间的区别

    我一直在使用git stash pop很长一段时间 我最近了解到git stash apply命令 当我尝试它时 它的工作原理似乎与git stash pop 有什么区别git stash pop and git stash apply g
  • 快速识别用户在编辑 NSTextField 时是否按下了箭头键

    我有很多 NSTextField 我想知道用户在编辑其中之一时是否按下了方向键之一 功能 override func keyDown theEvent NSEvent switch theEvent character case NSRig
  • 如何使用 AndEngine 通过滑动来投掷/投掷球?

    我在屏幕上有一个球精灵 当我触摸并滑动该精灵时 它必须沿特定的滑动方向移动 我给那个球添加了物理原理 我想做类似的事情扔纸 谁能帮我吗 提前致谢 您需要重写 Sprite 的 onAreaTouched 方法 如下所示 您可以从 pScen
  • 条件面板上的动画

    我想在我的条件面板上添加一些动画 我找到了这里提供的解决方案 闪亮条件面板的动画 过渡 我真的很喜欢这个解决方案 但我有一个问题 检查以下示例 library shiny library shinyjs library shinydashb
  • 如何获取当前日期或/和时间(以秒为单位)

    如何使用 Javascript 获取当前日期或 和时间 以秒为单位 var seconds new Date getTime 1000 将为您提供自 1970 年 1 月 1 日午夜以来的秒数 参考
  • Apache2、PHP:创建自动ntlm登录页面

    我有 Apache2 和 PyAuthenNTLM2 模块 请参阅https github com Legrandin PyAuthenNTLM2 该 Apache 模块将 Windows 用户名放入 SERVER REMOTE USER
  • Outlook.com HTML 电子邮件中条件注释的可靠解决方案

    我在这里和其他地方看到了设置条件评论以与 Outlook com 一起使用的推荐方法 但由于下面详细介绍的另一个已知问题 我收到了空白电子邮件 参考下面的两个代码示例 我想看看是否有人有解决此问题的可靠方法 第一个例子 上面的代码会导致 O
  • Python 字节字符串在字典中打印不正确

    考虑一个列表包含字节数据 即 x03 x00 x32 temp b for c in field data temp c print x ord c 上面的代码正确地将所有字节连接到 temp 字节字符串文字 中 但是当我将其添加到字典元素
  • 点点参数的范围

    我对点 点 点参数的范围有疑问 考虑以下函数 foo foo lt function x require classInt intvl classIntervals x return intvl 该函数非常适合以下调用 x runif 10
  • Java File.renameTo(File) 不起作用

    我正在尝试列出目录的内容 并重命名某些文件 public void run String dirName try File parDir new File dirName File dirContents parDir listFiles
  • 为什么我能够在 Linux 内核模块内执行浮点运算?

    我在 x86 CentOS 6 3 内核 v2 6 32 系统上运行 我将以下函数编译到一个简单的字符驱动程序模块中作为实验 以了解 Linux 内核对浮点运算的反应 static unsigned floatstuff void floa