在x86上发送用户模式中断

问题描述 投票:2回答:1

在Linux x86上,我可以发送由用户模式下运行的代码处理的中断(例如,由计时器或其他机制触发的中断吗?

假设答案是肯定的(并且几乎肯定是肯定的,请参见例如timer_create),是否仅在用户模式下传送此中断?,或者是否涉及到某些内核转换(例如,中断是最初由内核处理,然后将信号发送到用户进程)。

linux x86 signals interrupt
1个回答
4
投票

所有内核计时器接口在处理内核内部的计时器中断(或者通知该计时器或等待达到最后期限)之后,通过将signals传递给用户空间进程来工作。

在环3中运行中断处理程序或从仅由一个特定进程映射的用户空间虚拟地址中运行中断处理程序有很多障碍。 (即使您固定该内存以使其无法分页,它也仅在将CR3设置到该进程的页面表时才被映射。x86使用IDT(中断描述符表)中的虚拟地址,并且该页面必须被映射当中断触发时(我想您可能会遇到页面错误,您真的不想完全异步发生),这对于普通的内核中断处理程序来说不是问题;它始终将内核代码映射到相同的虚拟机所有用户空间页表中的地址。)一个允许将用户空间函数指针注册为0环中断处理程序的内核API会将密钥移交给该用户空间进程,实际上是使用内核特权运行的,因此这几乎是不合理的。


从技术上讲,x86的中断处理程序可以在第3环中运行,但是如果在第0环中触发该中断,则iret会出错,而不是返回被中断的内核代码。

必须专门编写一个中断处理程序才能返回iret,并保留所有寄存器。例如__attribute__((interrupt_handler)) https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html。同一核心上的任何其他过程都将受此过程的支配。

[其中的任何错误(例如破坏某些体系结构状态或弄脏SSE / AVX规则)都可能影响other

进程。(如果您能弄清楚如何让一个进程中的代码在CR3处于运行状态时运行)为另一个过程设置...)避免死锁也将是一个大问题;在内核中,在适当的中断处理程序(“上半部”)中可以执行的操作有很多限制,因为它可以在任何其他指令之间异步运行(除非您在该内核上禁用了中断)。


我认为让Linux做到这一点真的不合理;即使您以某种方式解决了所有(非常困难的)问题,甚至使处理程序在环3中运行,内核仍然必须相信它不会踩到任何其他进程的体系结构状态。

[有先例,例如X服务器获得运行in / out指令(通过iopl的权限)和/或访问/dev/mem的权限(从理论上讲,它可以让它从其他进程中窃取信息)。但这会更糟,并且使您可以轻松地从其他进程访问寄存器状态的快照。

© www.soinside.com 2019 - 2024. All rights reserved.