呼叫门,中断门,陷阱门之间的区别?

时间:2010-08-06 15:09:11

标签: x86 operating-system cpu interrupt processor

我正在研究英特尔保护模式。我发现Call Gate,Interrupt Gate,Trap Gate几乎是一样的。事实上,除了Call Gate有参数计数器的字段,并且这3个门具有不同的类型字段,它们在所有其他字段中是相同的。

关于它们的功能,它们都用于将代码控制转移到某些代码段中的某些过程中。

我很想知道,因为这3个门都包含跨权限边界调用所需的信息。为什么我们需要3种呢?不是一个就够好吗?

感谢您的时间和回应。

更新1

相关问题:When to use Interrupt Gate or Trap Gate?

更新2

今天我提出了这个想法:

执行不同的目的,不同的门,以及不同的CPU行为细节。如IF标志处理。

3 个答案:

答案 0 :(得分:59)

门(呼叫,中断,任务或陷阱)用于跨段传输控制执行。根据目的地类型和使用的指令,权限级别检查会有所不同。

呼叫门使用CALL和JMP指令。调用门将控制权从较低权限代码转移到较高权限代码。门DPL用于确定哪些特权级别可以访问门。呼叫门(或者可能已经)可能逐渐被放弃,转而采用SYSENTER / SYSEXIT机制,这种机制更快。

任务门用于硬件多任务支持。硬件任务切换可以自动发生(CALL / JMP到任务门描述符),或者在NT标志置位时通过中断或IRET发生。它与中断或陷阱门的工作方式相同。据我所知,任务门都没有使用,因为内核通常需要在任务切换时完成额外的工作。

中断&陷阱门与任务门一起被称为中断描述符表。它们的工作方式与调用门相同,除了参数传输,从一个权限堆栈到另一个权限堆栈。一个区别是中断门清除EFLAGS中的IF位,而陷阱门则没有。这使它们成为服务硬件中断的理想选择。陷阱广泛用于硬件辅助虚拟化。

有关详细信息,请参阅您感兴趣的处理器上的“英特尔体系结构手册”。

更新

回答评论:

将中断与陷阱区分开的原因有很多。一个是范围的差异:中断门指向内核空间(毕竟,它是管理硬件的内核),而陷阱在用户空间中调用。响应硬件事件调用中断处理程序,而响应CPU指令执行陷阱。

对于一个简单(但不切实际)的例子来更好地理解为什么中断和陷阱门对待EFLAGS的方式不同,考虑一下如果我们在单处理器系统上为硬件事件编写中断处理程序会发生什么,我们无法清除IF在我们服务的时候。当我们忙于服务第一个中断时,第二个中断可能会到达。然后,在IH执行期间,处理器会在某个随机点调用我们的中断处理程序。这可能导致数据损坏,死锁或其他不良魔法。实际上,中断禁用是确保将一系列内核语句视为关键部分的机制之一。

上面的例子假设可屏蔽中断。无论如何,你不会想忽视NMI。

今天也基本上无关紧要。今天,fast and slow interrupt handlers(搜索“快速和慢速处理程序”)之间几乎没有区别,中断处理程序可以嵌套方式执行,SMP处理器强制要求本地中断禁用与自旋锁等等。

现在,陷阱门确实用于服务软件中断,异常等。处理器中的页面错误或除零异常可能通过陷阱门处理。使用陷阱门控制程序执行的最简单示例是INT 3指令,该指令用于在调试器中实现断点。在进行虚拟化时,会发生的事情是虚拟机管理程序在环0中运行,而客户机内核通常在环1中 - 特权代码会因一般异常故障而失败。 Witchel和Rosenblum开发了binary translation,它基本上重写了模拟其效果的指令。发现关键指令并用陷阱替换。然后,当陷阱执行时,控制权交给VMM /管理程序,VMM /管理程序负责模拟环0中的关键指令。

使用硬件辅助虚拟化,陷阱和模拟技术在使用上受到限制(因为它非常昂贵,特别是当它是动态的时),但二进制翻译的实践是still widely used

有关详细信息,我建议您查看:

  • Linux设备驱动程序,第三版(可用online
  • 对于二进制翻译,QEMU是一个很好的开始。
  • 关于陷阱和模拟,请在软件/硬件技术之间查看a comparison

希望这有帮助!

答案 1 :(得分:19)

架构与设计

从保护的角度来看,x86架构基于分层环,根据该环,处理器提供的所有执行空间被分成四个hierarchical protection domains,每个{{3}}都有自己的特权级别。此设计假定大多数时间代码将在权限最少的域中执行,有时将请求来自更高权限的安全域的服务,并且此服务将抢占较少特权的活动到堆栈上,然后以这样的方式恢复它对于权限较低的代码,整个抢占将是不可见的。

分层保护域的设计表明控件不能在不同安全域之间任意传递。

门是x86体系结构的一个特性,用于从较少特权的代码段到更多特权代码段的控制转移,但反之亦然。此外,控制权将通过的权限较低的段中的点可以是任意的,但是在更严格的段中指向要传递控制的位置是严格指定的。仅通过IRET指令允许向后控制传递到较少特权的段。在这方面,英特尔软件开发人员手册声称:

  

较低权限段中的代码模块只能通过称为门的严格控制和受保护的接口访问在较高权限段上运行的模块。尝试访问更高权限的段而不通过保护门且没有足够的访问权限会导致生成一般保护异常(#GP)。

换句话说,门是具有所需访问权限和目标地址的特权域入口点。以这种方式,所有门都是相似的并且用于几乎相同的目的,并且所有门描述符包含DPL字段,处理器用来控制访问权限。但请注意,只有当呼叫源是软件CALLJMPINT指令时,处理器才会检查门的DPL,并在源的时候绕过此检查。呼叫是硬件。

门的类型

尽管所有门都相似,但它们之间存在一些差异,因为最初的英特尔工程师认为不同的门将用于不同的目的。

任务门

任务门只能存储在IDT和GDT中,并由INT指令调用。这是一种非常特殊的门,与其他门明显不同。

最初,英特尔工程师认为,通过为任务切换提供基于CPU的功能,他们将彻底改变多任务处理。他们引入了TSS(任务状态段),它保存任务的寄存器状态,并可用于硬件任务切换。触发硬件任务切换有两种方法:使用TSS本身和使用任务门。要进行硬件任务切换,您可以使用CALLJMP指令。如果我正确理解,任务门引入的主要原因是能够触发硬件任务切换以响应中断到达,因为硬件任务切换不能由JMP触发TSS选择器。

实际上,没有人使用它或硬件上下文切换。实际上,从性能的角度来看,这个功能并不是最佳的,并且使用起来不方便。例如,考虑到TSS只能存储在GDT中的帐户和GDT的长度不能超过8192,从硬件的角度来看,我们不能有超过8k的任务。

陷阱之门

Trap Gate只能存储在IDT中,并由INT指令调用。它可以被认为是一种基本类型的门。它只是将控制权传递给更具特权的段中的陷阱门描述符中指定的特定地址,仅此而已。 陷阱门主动用于不同目的,可能包括:

  • 系统调用实现(例如Linux使用INT 0x80,Windows使用INT 0x2E用于此目的)
  • 异常处理实现(我们没有任何理由在异常的情况下禁用中断)。
  • 在具有APIC的机器上实现中断处理(我们可以更好地控制内核堆栈)。

中断门

中断门只能存储在IDT中,并由INT指令调用。它与陷阱门相同,但另外中断门控调用还通过自动清除EFLAGS寄存器中的IF标志来禁止将来接受中断。

中断门主动用于中断处理实现,尤其是在基于PIC的机器上。原因是需要控制堆栈深度。 PIC没有中断源优先级功能。因此默认情况下,PIC仅禁用处理器中已处理的中断。但是另一个中断仍然可以到达中间并抢占中断处理。因此在同一时刻内核堆栈上可以有15个中断处理程序。结果,内核开发人员强制要求显着增加内核堆栈大小,这会导致内存损失或准备好面对零星的内核堆栈溢出。中断门可以保证在同一时间内只有一个处理程序可以在内核堆栈上。

致电门

Call Gate可以存储在GDL和LDT中,并由CALLJMP指令调用。与陷阱门类似,但另外可以将多个参数从用户模式任务堆栈传递到内核模式任务堆栈。传递的参数数量在调用门描述符中指定。

呼叫门从未流行过。原因很简单:

  • 它们可以被陷阱门(Occam' Razor)取代。
  • 他们不便携。其他处理器没有这样的功能,这意味着在移植操作系统时支持系统调用的调用门是一个负担,因为必须重写这些调用。
  • 由于可以在堆栈之间传递的参数数量有限,因此它们不太灵活。
  • 从绩效的角度来看,他们并不是最优的。

20世纪90年代末,英特尔和AMD推出了系统调用的附加说明:SYSENTER / SYSEXIT(英特尔)和SYSCALL / SYSRET(AMD)。与呼叫门相反,新指令提供了性能优势并且已被采用。

摘要

我不同意Michael Foukarakis。抱歉,除了影响IF标志外,中断和陷阱之间没有任何区别。

  • 理论上,每种类型的门都可以作为指向具有任何级别权限的段的接口。在实践中,在现代操作系统中仅使用中断和陷阱门,在IDT中用于系统调用,中断和异常处理,因此它们全部用作内核入口点。

  • 可以使用INT指令在软件中调用任何类型的门(包括中断,陷阱和任务)。唯一可以禁止用户模式代码访问特定门的功能是DPL。例如,当操作系统构建IDT时,无论特定门的类型如何,将使用将用于硬件事件处理的门的内核设置DPL为0并且根据对此门的访问将仅允许来自内核空间(在大多数特权域运行),但是当它为系统调用设置门时,它将DPL设置为3以允许从任何代码访问该门。结果,用户模式任务能够使用DPL = 3的门进行系统调用,但是例如在尝试调用键盘中断处理程序时会捕获一般保护错误。

  • IDT中的任何类型的门都可以由硬件调用。只有在想要实现某些同步的情况下,人们才会使用中断门来处理此硬件事件。例如,确保内核堆栈溢出是不可能的。例如,我已成功使用陷阱门用于基于APIC的系统上的硬件中断处理。

  • 类似地,IDT中的任何类型的门都可以在软件中调用。使用陷阱门进行系统调用和异常的原因很简单。没有任何理由禁用中断。中断禁用是一件坏事,因为它会增加中断处理延迟并增加中断丢失的可能性。由于这一点,没有人不会在没有任何严重理由的情况下禁用它们。

  • 中断处理程序通常以严格的可重入方式编写。这样,中断处理程序通常不共享数据,并且可以透明地相互抢占。即使我们需要在中断处理程序中相互排除对数据的并发访问,我们也可以通过使用cli和sti指令来保护对共享数据的访问。没有任何理由将整个中断处理程序视为关键部分。没有任何理由使用中断门,除非希望防止基于PIC的系统上可能的内核堆栈溢出。

陷阱门是内核接口的默认解决方案。如果有一些严重的原因,可以使用中断门代替陷阱门。

答案 2 :(得分:8)

中断门是特殊的,因为IF标志会自动清除。调用门是特殊的,因为它不会通过中断向量激活。任务门是特殊的,因为它会自动保存处理器状态。四个不同的行为,有四个名称是方便的。