Paging is implemented by the CPU hardware itself.
Paging could be implemented in software, but that would be too slow, because every single RAM memory access uses it!
Operating systems must setup and control paging by communicating to the CPU hardware. This is done mostly via:
  • the CR3 register, which tells the CPU where the page table is in RAM memory
  • writing the correct paging data structures to the RAM pointed to the CR3 register.
    Using RAM data structures is a common technique when lots of data must be transmitted to the CPU as it would cost too much to have such a large CPU register.
    The format of the configuration data structures is fixed _by the hardware_, but it is up to the OS to set up and manage those data structures on RAM correctly, and to tell the hardware where to find them (via cr3).
    Then some heavy caching is done to ensure that the RAM access will be fast, in particular using the TLB.
    Another notable example of RAM data structure used by the CPU is the IDT which sets up interrupt handlers.
    The OS makes it impossible for programs to change the paging setup directly without going through the OS:
  • CR3 cannot be modified in ring 3. The OS runs in ring 0. See also:
  • the page table structures are made invisible to the process using paging itself!
Processes can however make requests to the OS that cause the page tables to be modified, notably:
The kernel then decides if the request will be granted or not in a controlled manner.