放用户空间有两种情况,一种是IDT里直接写一个用户态的地址,另一种只是在用户态放一个任务(进程?线程?)来处理中断事件。
IDT里直接放一个用户态地址行不行?这个不好说,按说Interrupt Gate描述符上是有DPL的:
但这里写一个非0的值行不行,不好判断(但确实没见过有操作系统这么做),我个人理解是不能,如果当前在内核态,发生中断的话,DPL应该不符合跳转规定,然后产生一个异常。
那么剩下的一种就是:启动一个用户态任务来处理中断,抛开安全性不谈,这种方式是可行的。只不过,大部分中断服务程序都需要访问很多内核资源,比如开关中断指令(只能在内核中使用),读写寄存器(MMIO没映射到用户态)等等。
如果放开这些限制,会有一些问题:
比如:如果用户态的任务可以任意开关中断,或者操作硬件寄存器,那么这种操作系统的安全风险会很大,这跟DOS系统没什么区别。如果要堵住安全漏洞,就需要对用户态的任务做非常复杂的权限控制,代码效率会很差。
还有:因为CPU的原因用户态的代码不能直接操作某些硬件资源,那么就需要通过系统调用来支持,那么这些用户态的中断服务程序需要频繁的使用系统调用,比直接在内核里效率要差很多。
中断在用户态的好处也是有的:
中断服务程序崩溃不会波及内核。现在的中断服务程序一旦出了问题,必然是内核崩溃,蓝屏之类的。在用户态的话,中断服务程序可以更方便的重启。
我印象里,有些RTOS就是这么设计的(名字不记得了),好处肯定有,问题也会有很多。所以中断是可以在用户态处理的,只不过有些问题,而主流的桌面操作系统没有选择这样的设计模型。
如果未来CPU能提供更灵活的机制,那么用户态中断服务程序可能会有很多,就像现在用户态驱动程序一样,当然了,安全风险肯定也是有的。