为什么系统调用使用不同的堆栈? [英] Why do system calls use a different stack?

查看:91
本文介绍了为什么系统调用使用不同的堆栈?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里有一个关于的问题系统调用期间发生的细节.

然而,让我惊讶的是 TSS 为不同的特权维护不同的堆栈.也就是说,在用户模式和系统模式下运行的代码使用不同的堆栈上下文.

However, one thing surprises me that the TSS maintains different stacks for different priviliges. That is, codes running in user mode and system mode are using different stack context.

既然系统调用实际上是一个函数调用,为什么我们不能只重用用户堆栈并为此创建一个新的堆栈框架?

Since system call is actually a function call, why couldn't we just reuse the user stack and just create a new stack frame for that?

推荐答案

因为系统调用实际上是一个函数调用

Since system call is actually a function call

如果系统调用是函数调用,就不会用不同的名称调用它,是吗?这是完全不同的两件事.内核空间和用户空间是两个独立的世界,为了简单和安全,您希望尽可能将它们分开.内核操作必须对用户程序透明,并且内核数据必须仅对内核可见.系统调用不仅仅是一个函数调用,内核所做的工作需要对用户程序保持不可见.

If a syscall was a function call it wouldn't be called with a different name, would it? Those are two completely different things. Kernel space and user space are two separate worlds, and you want to keep them separate as much as possible, both for simplicity and for security. Kernel operations must be transparent to user programs, and kernel data must remain visible to the kernel only. A syscall is not just a function call, the work done by the kernel needs to stay invisible to the user program.

使用单独堆栈的最简单原因是它们实际上属于两个不同的程序:一个是用户空间程序,另一个是操作系统.这些堆栈具有不同的大小和偏移量,因此单独管理要简单得多.想象一下,如果用户程序在耗尽所有可用堆栈的叶函数中进行系统调用会发生什么:内核要么无法执行它并崩溃,要么必须检测到这一点并通过分配更多空间来避免崩溃在当前堆栈的顶部.这比将两个堆栈分开要复杂得多,而且要保持它对用户程序透明会更困难(也就是说,除非您随后恢复这些更改,否则情况会更加复杂).

The simplest reason for using separate stacks is that they actually belong to two different programs: one is the user space program, the other is the operating system. These stacks have different sizes and offsets, and therefore are much simpler to be managed separately. Imagine what would happen if the user program were to make a syscall in a leaf function that has exhausted all the available stack: the kernel would either fail to execute it and crash, or it would have to detect this and avoid crashing by allocating more space on top of the current stack. This is much more complicated than keeping the two stacks separate, and it would be harder to keep it transparent to the user program (that is, unless you then revert those changes, which is complicating the situation even more).

除上述之外,将系统调用视为简单的函数调用,从而使内核使用与调用程序相同的堆栈,会在程序的堆栈上留下大量内核数据(基本上每个局部变量由内核函数在处理系统调用时使用).这是不应该发生的副作用,因为它会将大量内核数据和地址暴露给用户空间,这也是一个安全问题.如果内核要使用与发出系统调用的用户程序相同的堆栈,则每个内核函数都需要清除"系统调用.返回之前使用的所有局部变量(甚至清除堆栈上保存的返回地址),这会使整个操作系统慢很多,而且仍然对用户程序透明.

In addition to the above, treating a syscall like a simple function call, thus making the kernel use the same stack as the calling program, would leave a lot of kernel data on the stack of the program (basically every single local variable used by kernel functions while processing the syscall). This is a side effect that should not happen, as it would expose a lot of kernel data and addresses to userspace, which is also a security problem. If the kernel were to use the same stack as the user program that issued the syscall, every single kernel function would need to "clean out" all the local variables used before returning (and even clean out the saved return addresses on the stack), which would make the entire operating system a lot slower, and would also still not be transparent to the user program.

这篇关于为什么系统调用使用不同的堆栈?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆