科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件Linux2.6对新型CPU快速系统调用的支持 (1)

Linux2.6对新型CPU快速系统调用的支持 (1)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

文章分析了在 Linux 2.6 中引入的对 Intel CPU 快速系统调用指令 SYSENTER/SYSEXIT 支持的实现。

作者:赛迪网技术社区 来源:赛迪网技术社区 2007年11月2日

关键字: Linux

  • 评论
  • 分享微博
  • 分享邮件
 

文章分析了在 Linux 2.6 中引入的对 Intel CPU 快速系统调用指令 SYSENTER/SYSEXIT 支持的实现。Linux 驱动及内核开发者通过了解快速系统调用指令的机制,可以在自己的代码中通过利用这一机制,提高系统性能,并避开由快速系统调用方式带来的一些局限(如系统调用中嵌套系统调用)。

前言

在 Linux 2.4 内核中,用户态 Ring3 代码请求内核态 Ring0 代码完成某些功能是通过系统调用完成的,而系统调用的是通过软中断指令(int 0x80)实现的。在 x86 保护模式中,处理 INT 中断指令时,CPU 首先从中断描述表 IDT 取出对应的门描述符,判断门描述符的种类,然后检查门描述符的级别 DPL 和 INT 指令调用者的级别 CPL,当 CPL<=DPL 也就是说 INT 调用者级别高于描述符指定级别时,才能成功调用,最后再根据描述符的内容,进行压栈、跳转、权限级别提升。内核代码执行完毕之后,调用 IRET 指令返回,IRET 指令恢复用户栈,并跳转会低级别的代码。

其实,在发生系统调用,由 Ring3 进入 Ring0 的这个过程浪费了不少的 CPU 周期,例如,系统调用必然需要由 Ring3 进入 Ring0(由内核调用 INT 指令的方式除外,这多半属于 Hacker 的内核模块所为),权限提升之前和之后的级别是固定的,CPL 肯定是 3,而 INT 80 的 DPL 肯定也是 3,这样 CPU 检查门描述符的 DPL 和调用者的 CPL 就是完全没必要。正是由于如此,Intel x86 CPU 从 PII 300(Family 6,Model 3,Stepping 3)之后,开始支持新的系统调用指令 sysenter/sysexit。sysenter 指令用于由 Ring3 进入 Ring0,SYSEXIT 指令用于由 Ring0 返回 Ring3。由于没有特权级别检查的处理,也没有压栈的操作,所以执行速度比 INT n/IRET 快了不少。

不同系统调用方式的性能比较:

下面是一些来自互联网的有关 sysenter/sysexit 指令和 INT n/IRET 指令在 Intel Pentium CPU 上的性能对比:

表1:系统调用性能测试 测试硬件:Intel? Pentium? III CPU, 450 MHz Processor Family: 6 Model: 7 Stepping: 2

用户模式花费的时间     核心模式花费的时间 
基于sysenter/sysexit指令的系统调用   9.833 microseconds     6.833 microseconds 
基于中断 INT n 指令的系统调用        17.500 microseconds    7.000 microseconds

数据来源:[1]

Linux2.6对新型CPU快速系统调用的支持 (1)

数据来源:[2]

表2:各种 CPU 上 INT 0x80 和 SYSENTER 执行速度的比较

CPU                        Int0x80          sysenter 
Athlon XP 1600+            277              169 
800MHz mode 1 athlon       279              170 
2.8GHz p4 northwood ht     1152             442

上述数据为对 100000 次 getppid() 系统调用所花费的 CPU 时钟周期取的平均值数据来源[3]。

自这种技术推出之后,人们一直在考虑在 Linux 中加入对这种指令的支持,在 Kernel.org 的邮件列表中,主题为 "Intel P6 vs P7 system call performance" 的大量邮件讨论了采用这种指令的必要性,邮件中列举的理由主要是 Intel 在 Pentium 4 的设计上存在问题,造成 Pentium 4 使用中断方式执行的系统调用比 Pentium 3 以及 AMD Athlon 所耗费的 CPU 时钟周期多上 5~10 倍。因此,在 Pentium 4 平台上,通过 sysenter/sysexit 指令来执行系统调用已经是刻不容缓的需求。

sysenter/sysexit 系统调用的机制:

在 Intel 的软件开发者手册第二、三卷(Vol.2B,Vol.3)中,4.8.7 节是关于 sysenter/sysexit 指令的详细描述。手册中说明,sysenter 指令可用于特权级 3 的用户代码调用特权级 0 的系统内核代码,而 SYSEXIT 指令则用于特权级 0 的系统代码返回用户空间中。sysenter 指令可以在 3,2,1 这三个特权级别调用(Linux 中只用到了特权级 3),而 SYSEXIT 指令只能从特权级 0 调用。

执行 sysenter 指令的系统必须满足两个条件:1.目标 Ring 0 代码段必须是平坦模式(Flat Mode)的 4GB 的可读可执行的非一致代码段。2.目标 RING0 堆栈段必须是平坦模式(Flat Mode)的 4GB 的可读可写向上扩展的栈段。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章