Commit 28e21eac authored by Changbin Du's avatar Changbin Du Committed by Jonathan Corbet

Documentation: x86: convert protection-keys.txt to reST

This converts the plain text documentation to reStructuredText format and
add it to Sphinx TOC tree. No essential content change.
Signed-off-by: default avatarChangbin Du <changbin.du@gmail.com>
Reviewed-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
Signed-off-by: default avatarJonathan Corbet <corbet@lwn.net>
parent 2f6eae47
...@@ -18,3 +18,4 @@ x86-specific Documentation ...@@ -18,3 +18,4 @@ x86-specific Documentation
tlb tlb
mtrr mtrr
pat pat
protection-keys
.. SPDX-License-Identifier: GPL-2.0
======================
Memory Protection Keys
======================
Memory Protection Keys for Userspace (PKU aka PKEYs) is a feature Memory Protection Keys for Userspace (PKU aka PKEYs) is a feature
which is found on Intel's Skylake "Scalable Processor" Server CPUs. which is found on Intel's Skylake "Scalable Processor" Server CPUs.
It will be avalable in future non-server parts. It will be avalable in future non-server parts.
...@@ -23,9 +29,10 @@ even though there is theoretically space in the PAE PTEs. These ...@@ -23,9 +29,10 @@ even though there is theoretically space in the PAE PTEs. These
permissions are enforced on data access only and have no effect on permissions are enforced on data access only and have no effect on
instruction fetches. instruction fetches.
=========================== Syscalls =========================== Syscalls
========
There are 3 system calls which directly interact with pkeys: There are 3 system calls which directly interact with pkeys::
int pkey_alloc(unsigned long flags, unsigned long init_access_rights) int pkey_alloc(unsigned long flags, unsigned long init_access_rights)
int pkey_free(int pkey); int pkey_free(int pkey);
...@@ -37,6 +44,7 @@ pkey_alloc(). An application calls the WRPKRU instruction ...@@ -37,6 +44,7 @@ pkey_alloc(). An application calls the WRPKRU instruction
directly in order to change access permissions to memory covered directly in order to change access permissions to memory covered
with a key. In this example WRPKRU is wrapped by a C function with a key. In this example WRPKRU is wrapped by a C function
called pkey_set(). called pkey_set().
::
int real_prot = PROT_READ|PROT_WRITE; int real_prot = PROT_READ|PROT_WRITE;
pkey = pkey_alloc(0, PKEY_DISABLE_WRITE); pkey = pkey_alloc(0, PKEY_DISABLE_WRITE);
...@@ -45,43 +53,44 @@ called pkey_set(). ...@@ -45,43 +53,44 @@ called pkey_set().
... application runs here ... application runs here
Now, if the application needs to update the data at 'ptr', it can Now, if the application needs to update the data at 'ptr', it can
gain access, do the update, then remove its write access: gain access, do the update, then remove its write access::
pkey_set(pkey, 0); // clear PKEY_DISABLE_WRITE pkey_set(pkey, 0); // clear PKEY_DISABLE_WRITE
*ptr = foo; // assign something *ptr = foo; // assign something
pkey_set(pkey, PKEY_DISABLE_WRITE); // set PKEY_DISABLE_WRITE again pkey_set(pkey, PKEY_DISABLE_WRITE); // set PKEY_DISABLE_WRITE again
Now when it frees the memory, it will also free the pkey since it Now when it frees the memory, it will also free the pkey since it
is no longer in use: is no longer in use::
munmap(ptr, PAGE_SIZE); munmap(ptr, PAGE_SIZE);
pkey_free(pkey); pkey_free(pkey);
(Note: pkey_set() is a wrapper for the RDPKRU and WRPKRU instructions. .. note:: pkey_set() is a wrapper for the RDPKRU and WRPKRU instructions.
An example implementation can be found in An example implementation can be found in
tools/testing/selftests/x86/protection_keys.c) tools/testing/selftests/x86/protection_keys.c.
=========================== Behavior =========================== Behavior
========
The kernel attempts to make protection keys consistent with the The kernel attempts to make protection keys consistent with the
behavior of a plain mprotect(). For instance if you do this: behavior of a plain mprotect(). For instance if you do this::
mprotect(ptr, size, PROT_NONE); mprotect(ptr, size, PROT_NONE);
something(ptr); something(ptr);
you can expect the same effects with protection keys when doing this: you can expect the same effects with protection keys when doing this::
pkey = pkey_alloc(0, PKEY_DISABLE_WRITE | PKEY_DISABLE_READ); pkey = pkey_alloc(0, PKEY_DISABLE_WRITE | PKEY_DISABLE_READ);
pkey_mprotect(ptr, size, PROT_READ|PROT_WRITE, pkey); pkey_mprotect(ptr, size, PROT_READ|PROT_WRITE, pkey);
something(ptr); something(ptr);
That should be true whether something() is a direct access to 'ptr' That should be true whether something() is a direct access to 'ptr'
like: like::
*ptr = foo; *ptr = foo;
or when the kernel does the access on the application's behalf like or when the kernel does the access on the application's behalf like
with a read(): with a read()::
read(fd, ptr, 1); read(fd, ptr, 1);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment