How does the CPU knows which physical address is mapped to which virtual address?
The MMU accesses a table that describes how translate virtual addresses to physical addresses. (It doesn't need to translate physical addresses to virtual addresses, and this would be impossible in general since the same physical address can be accessed via multiple virtual addresses or can be unmapped.) The layout of this table depends on the CPU architecture, but the general principle is always the same: there's a CPU register which contains the physical address of a table, which contains the physical addresses of further tables, and so on (for 2 to 4 levels total on existing architectures) until a level of tables that contains the physical addresses where the data is located. At each level, which element of the table to use is determined by some of the bits in the virtual address.
The MMU doesn't know about operating system processes as such. When the CPU switches to executing a different process, i.e. when a context switch occurs, it is the job of the operating system's context switching code to update the MMU tables as necessary. In practice, I think all Unix systems keep a copy of the tables in memory for each process, and just update the MMU register to point to the top-level table for the current process.
There is actually a part of the MMU that cares about operating system processes: the TLB. Looking up entries in the MMU table is rather costly since it involves multiple memory accesses. The TLB is a cache of these lookups. On a context switch, the operating system must invalidate the TLB (i.e. remove all cache entries), since the mapping will be different for the new process. Many architectures allow the OS to put an indicator in each MMU table entry to say “this entry belongs to process N”. A TLB entry is then skipped if the process number that it contains is not the current process number. A CPU register contains the current process number and the context switch code updates it. This mechanism means that the TLB can contain information about multiple processes at once, which improves performance when switching back and forth between these processes. Because there are often fewer bits available to store N than needed to store all OS process IDs, N is not the process ID, but a number generated by the OS for this purpose and that changes over time, if it's used at all.
In Linux, the kernel maintains a three-level page table (regardless of the CPU’s capabilities). The top level is the page global directory, and each process has its own directory, pgd
in mm_struct
. Thus each process can have its own mappings, so address 12345 in different processes points to different physical addresses.
CPUs aren’t really aware of processes, but they do tend to have features to support them. On x86-style CPUs, there are various task-related features, but they actually tend to be ignored. Since process scheduling is managed by the kernel, it can keep track of page table changes itself, and update whatever CPU state is required to switch to a new process’s page table when it switches tasks. On x86 PCs, that involves updating the CR3 control register which points to the page directory.
The Page Table Management chapter in Mel Gorman’s Understanding the Linux Virtual Memory Manager book gives a good overview.