上下文切换:如果新进程将其虚拟内存映射到与前一个进程相同的物理地址,内存保护是如何实现的?

Context Switch: if the new process has its virtual memory mapped to same physical address as the previous one, how is memory protection implemented?

我知道在上下文切换时不会刷新缓存。因此,如果新进程要求一个页面映射到与前一个进程相同的物理地址(并且前一个进程现在交换到磁盘),前一个进程的内容仍将被缓存。当新进程试图从物理映射的缓存中访问其内存部分时,它们不会被新进程访问吗?

if the new process has its virtual memory mapped to same physical address as the previous one.

对于大多数现代操作系统,您问题的答案是 Paging

假设您有一个具有 4GB 可寻址内存的 OS,但系统上安装的物理内存仅为 2GB。进一步假设一个需要 1.5GB 内存的进程处于活动状态,因此它看起来如下所示。

因为有足够的物理内存,所以本进程完整的虚拟地址space映射到物理内存

现在假设一个需要 1.5GB 内存的新进程进入系统。由于两个进程都没有足够的物理内存,因此第一个进程的地址 space 可能会映射到磁盘(调出),因为第二个进程主动需要其 space 的全部 1.5GB。 所以现在的情况是这样的。

请注意,从第一个过程的角度来看,一切都和以前一样, 一旦它变为活动状态并使用其虚拟 space,OS 将在其存储在磁盘上的内存 space 中分页到物理内存。

I know a cache is not flushed at context switch. So if the new process has demanded a page that maps to the same physical address as the previous process (and the prev process is now swapped to disk), the contents of the previous process would still be cached of memory protection.

你的前提不完全正确,你从哪里读到缓存不会被刷新?

在上下文切换时使缓存无效的问题取决于多种因素,其中一些不受 OS 控制。

一些 OS 实现会刷新缓存(见下文)和不刷新缓存的实现,需要硬件的特殊支持。无论哪种方式,任何有价值的 OS 都将确保不会向任何进程提供无效数据。

以下是一些非常好的 OS 书籍中的相关文字。

来自Understanding the Linux Kernel

Table 2-11. Architecture-independent TLB-invalidating methods

Method name -- flush_tlb
Description -- Flushes all TLB entries of the non-global pages owned by the current process Typically used when -- Performing a process switch

If the CPU switches to another process that is using the same set of page tables as the kernel thread that is being replaced, the kernel invokes _ _flush_tlb() to invalidate all non-global TLB entries of the CPU.

来自Modern Operating Systems

The presence of caching and the MMU can have a major impact on performance. In a multiprogramming system, when switching from one program to another, sometimes called a context switch, it may be necessary to flush all modified blocks from the cache and change the mapping registers in the MMU.

和来自 Operating System - three easy pieces

One approach is to simply flush the TLB on context switches, thus emptying it before running the next process. On a software-based system, this can be accomplished with an explicit (and privileged) hardware instruction; with a hardware-managed TLB, the flush could be enacted when the page-table base register is changed (note the OS must change the PTBR on a context switch anyhow). In either case, the flush operation simply sets all valid bits to 0, essentially clearing the contents of the TLB. By flushing the TLB on each context switch, we now have a working solution, as a process will never accidentally encounter the wrong translations in the TLB.

On the other hand To reduce this overhead, some systems add hardware support to enable sharing of the TLB across context switches. In particular, some hardware systems provide an address space identifier (ASID) field in the TLB. You can think of the ASID as a process identifier (PID), but usually it has fewer bits (e.g., 8 bits for the ASID versus 32 bits for a PID). If we take our example TLB from above and add ASIDs, it is clear processes can readily share the TLB: only the ASID field is needed to differentiate otherwise identical translations.