Documentation/arch/x86/pti.rst

Source file repositories/reference/linux-study-clean/Documentation/arch/x86/pti.rst

File Facts

System
Linux kernel
Corpus path
Documentation/arch/x86/pti.rst
Extension
.rst
Size
9030 bytes
Lines
194
Domain
Support Tooling And Documentation
Bucket
Documentation
Inferred role
Support Tooling And Documentation: documentation
Status
atlas-only

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

.. SPDX-License-Identifier: GPL-2.0

==========================
Page Table Isolation (PTI)
==========================

Overview
========

Page Table Isolation (pti, previously known as KAISER [1]_) is a
countermeasure against attacks on the shared user/kernel address
space such as the "Meltdown" approach [2]_.

To mitigate this class of attacks, we create an independent set of
page tables for use only when running userspace applications.  When
the kernel is entered via syscalls, interrupts or exceptions, the
page tables are switched to the full "kernel" copy.  When the system
switches back to user mode, the user copy is used again.

The userspace page tables contain only a minimal amount of kernel
data: only what is needed to enter/exit the kernel such as the
entry/exit functions themselves and the interrupt descriptor table
(IDT).  There are a few strictly unnecessary things that get mapped
such as the first C function when entering an interrupt (see
comments in pti.c).

This approach helps to ensure that side-channel attacks leveraging
the paging structures do not function when PTI is enabled.  It can be
enabled by setting CONFIG_MITIGATION_PAGE_TABLE_ISOLATION=y at compile
time.  Once enabled at compile-time, it can be disabled at boot with
the 'nopti' or 'pti=' kernel parameters (see kernel-parameters.txt).

Page Table Management
=====================

When PTI is enabled, the kernel manages two sets of page tables.
The first set is very similar to the single set which is present in
kernels without PTI.  This includes a complete mapping of userspace
that the kernel can use for things like copy_to_user().

Although _complete_, the user portion of the kernel page tables is
crippled by setting the NX bit in the top level.  This ensures
that any missed kernel->user CR3 switch will immediately crash
userspace upon executing its first instruction.

The userspace page tables map only the kernel data needed to enter
and exit the kernel.  This data is entirely contained in the 'struct
cpu_entry_area' structure which is placed in the fixmap which gives
each CPU's copy of the area a compile-time-fixed virtual address.

For new userspace mappings, the kernel makes the entries in its
page tables like normal.  The only difference is when the kernel
makes entries in the top (PGD) level.  In addition to setting the
entry in the main kernel PGD, a copy of the entry is made in the
userspace page tables' PGD.

This sharing at the PGD level also inherently shares all the lower
layers of the page tables.  This leaves a single, shared set of
userspace page tables to manage.  One PTE to lock, one set of
accessed bits, dirty bits, etc...

Overhead
========

Protection against side-channel attacks is important.  But,
this protection comes at a cost:

1. Increased Memory Use

  a. Each process now needs an order-1 PGD instead of order-0.

Annotation

Implementation Notes