VM操作系统如何在不被主机操作系统/CPU终止的情况下发出特权操作码?

huangapple go评论59阅读模式
英文:

How does the VM OS issue privileged Opcodes without being terminated by the Host OS/CPU?

问题

My understanding is that the host Operating System upon booting associates with and locks certain CPU Opcodes/instructions so that only the host OS may use them. The CPU architecture, additionally, supports this.

If a program offends and tries to use these instructions, the CPU will trap and revert control back to the OS which will terminate the program. Hence a program uses Syscalls() to do these things.

When you Virtualized an OS, it wouldn't issue syscalls(), it would simply execute the privileged instruction. It stands to reason it would then be terminated by the Host OS.

How are Opcodes virtualized?

英文:

My understanding is that the host Operating System upon booting associates with and locks certain CPU Opcodes/instructions so that only the host OS may use them. The CPU architecture, additionally, supports this.

If a program offends and tries to use these instructions, the CPU will trap and revert control back to the OS which will terminate the program. Hence a program uses Syscalls() to do these things.

When you Virtualized an OS, it wouldn't issue syscalls(), it would simply execute the privileged instruction. It stands to reason it would then be terminated by the Host OS.

How are Opcodes virtualized?

答案1

得分: 2

除了终止,还有模拟和继续的另一选择。

在某些系统中,当硬件不支持但程序需要时,会模拟不对齐的加载和存储操作,类似的情况也适用于浮点指令和寄存器。因此,主机可以模拟这些操作,使其看起来像硬件执行了该指令一样。模拟意味着根据需要更改程序的状态(CPU寄存器或内存),然后在出错的指令之后继续执行程序。

处理页面错误的机制类似:加载、复制或以其他方式映射地址,然后继续执行程序,尽管对于这些情况,一旦页面可用,出错的指令就会重新启动。

在这些环境中,特权和缺失的指令发生错误(引发硬件异常)至关重要,以便主机可以以适当的语义进行模拟。硬件根据操作模式(用户模式、监管模式或其他模式)更改执行特权指令的行为。发生异常会自动切换到另一个模式,从异常中恢复会恢复原始模式。

硬件方案可以提高效率,例如,RISC-V定义了针对多个不同特权级别的特定指令和行为,以便某些特权操作可以在不引发下一层级异常的情况下允许执行。

英文:

There's another option besides termination, which is emulation and continue.

Some systems emulate misaligned loads & stores when the hardware doesn't support it but programs expect it; similar for floating point instructions & registers.  So, a host can emulate things to make it look like the hardware did execute that instruction.  Emulation means making changes to the program's state (cpu registers or memory as needed) and then resuming the program after the faulting instruction.

Similar mechanism for handling page faults: load, copy, or otherwise map the address and then continue the program — though for these, the faulting instruction is restarted once the page(s) are made available.

In those environments, it is critical that the privileged and missing instructions fault (take a hardware exception) so that the host can emulate with the proper semantics.  The hardware changes behavior for execution of privileged instructions based on the operating mode, whether user or supervisor (or other).  Taking an exception automatically switches to another mode, and resuming from the exception restores the original mode.

Hardware schemes can help with efficiency, for example, RISC V defines specific instructions and behaviors for multiple separate privilege levels, so that some privileged operations can be allowed without faulting to the next layer.

答案2

得分: 2

如果程序触发并尝试使用这些指令,CPU将会陷入,并将控制权恢复给操作系统。

是的,这是硬件的功能。

这将终止该程序。

好吧,不一定。此时完全由操作系统决定如何继续。的确,终止通常是默认行为,但还有其他选项可能性。

例如,在类Unix操作系统下,真正发生的是向进程发送一个信号(例如SIGILL、SIGSEGV、SIGBUS)。默认情况下,这将终止进程(可选择包含核心转储)。但是,如果程序之前为相关信号安装了信号处理程序,那么操作系统不会终止进程,而是将控制权传递给信号处理程序(在切换回非特权用户模式后)。操作系统还可以向信号处理程序提供CPU记录的关于故障的任何信息:故障指令的地址、错误代码等(在Unix中,这些信息传递给处理程序的可选第三个“context”参数)。然后,处理程序可以根据自己认为合适的方式进行操作,例如模拟特权指令并跳回到主要执行线程。

我认为一个常见的误解是,出于安全考虑,一个非特权进程尝试执行特权操作必须被终止,作为一种“死刑”惩罚。这并不完全正确。就安全性而言,必要的是不要执行特权操作。发生的任何事情更多地涉及到可用性。

终止进程当然是一个明智的默认选择。假设一个典型的非特权程序通常没有理由执行特权指令;程序员或编译器应该知道这不会起作用。操作系统可以跳过该指令,让进程继续运行,而不会有安全问题。但由于程序未按程序员预期的方式运行,让它继续下去只会使它变得越来越困惑。它可能会继续执行一些具有权限的操作,但用户不想要(输出错误结果、覆盖用户的数据,或者只是浪费CPU和内存)。因此,立即终止它是有道理的,以通知用户发生了问题并避免进一步的故障。这是对用户提供最大价值的行为方式。

但程序员可以通过安装信号处理程序(或其他系统上的等效方式)覆盖这一假设。这实际上告诉操作系统:“我知道我可能正在执行这些指令,并且它们会陷入;这正是我想要的。”这将是虚拟化的情况。或者,另一种情况是:“我实际上不打算执行这些指令,但如果我这样做,我希望能够恢复,或在退出之前进行清理。”如果这是程序员想要的,操作系统没有理由反对。

英文:

> If a program offends and tries to use these instructions, the CPU will trap and revert control back to the OS

Yes, that's what the hardware does.

> which will terminate the program.

Well, not necessarily. At this point it's completely up to the OS how to proceed. It's true that termination is usually the default behavior, but other options are possible.

For instance, under Unix-like operating systems, what really happens is that a signal is delivered to the process (e.g. SIGILL, SIGSEGV, SIGBUS). By default, this terminates the process (optionally with a core dump). But if the program previously installed a handler for the signal in question, then instead of terminating the process, the OS instead passes control to the signal handler (after switching back into unprivileged user mode). It can also make available to the handler whatever information about the fault was recorded by the CPU: address of faulting instruction, error codes, etc (on Unix this is passed in an optional third context argument to the handler). The handler can then do whatever it thinks is appropriate, such as emulating the privileged instruction and jumping back to the main line of execution.


I think it's a common misconception that it's necessary for security that an unprivileged process attempting a privileged operation must be terminated, as a sort of "death penalty" punishment. That's not really true. As far as security is concerned, all that's necessary is that the privileged operation doesn't take place. Whatever happens instead is more about usability.

Terminating the process is certainly a sensible default. The assumption is that a typical unprivileged program normally has no reason to execute a privileged instruction; the programmer or compiler ought to know that it's not going to work. The OS could just skip that instruction and let the process continue, and there'd be no security problem. But since the program is not behaving as the programmer presumably intended, letting it go on would simply let it get more and more confused. It may go on to do something that it has permission to do, but which the user doesn't want (output incorrect results, overwrite the user's data, or simply waste CPU and memory). So it makes sense to terminate it at once, to notify the user that something went wrong and avoid further malfunction. This is the behavior that gives the most value to the user.

But the programmer can override that assumption by installing a signal handler (or equivalent on other systems). This effectively tells the OS: "I am aware that I may be executing such instructions, and that they would trap; that's exactly what I want." That would be the situation for virtualization. Or, alternatively, "I don't actually intend to execute such instructions, but in case I do, I want to be able to recover, or to clean up before exiting." And if that's what the programmer wants, there's no reason for the OS to object.

huangapple
  • 本文由 发表于 2023年5月7日 23:36:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/76194843.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定