Permalink
Show file tree
Hide file tree
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
memremap: Add zone device access protection
Device managed memory exposes itself to the kernel direct map which
allows stray pointers to access these device memories.
Stray pointers to normal memory may result in a crash or other
undesirable behavior which, while unfortunate, are usually recoverable
with a reboot. Stray access, specifically stray writes, to areas such
as non-volatile memory are permanent in nature and thus are more likely
to result in permanent user data loss vs stray access to other memory
areas.
Furthermore, reads to poison can cause fatal errors which are difficult
to recover from.
Set up an infrastructure for extra device access protection. Then
implement the new protection using the new Protection Keys Supervisor
(PKS) on architectures which support it.
To enable this extra protection kernel code specifies a new flag
(PGMAP_PROT_ENABLED) in (struct dev_pagemap)->flags to indicate that
these pages have additional protection.
Kernel code which then intends to access this memory can do so through
the dev_mk_readwrite() and dev_mk_noaccess() calls.
All changes in the protections must be through the dev_mk_*() calls.
They are optimized to be low overhead especially if device protection is
not in use. Furthermore, They are nestable by the use of a per task
reference count. This reference count is critical to allows a thread to
nest calls to disable protection such that the first call to re-enable
protection does not 'break' the last access of the pmem device memory.
In addition, the reference count must be preserved across an exception.
Use the reserved space in extended_pt_regs to store this reference
count.
The following shows how this works through an exception:
...
// ref == 0
dev_mk_readwrite() // ref += 1 ==> disable protection
irq()
// enable protection
// ref = 0
_handler()
dev_mk_readwrite() // ref += 1
dev_mk_noaccess() // ref -= 1
// WARN_ON(ref != 0)
// disable protection
do_pmem_thing() // all good here
dev_mk_noaccess() // ref -= 1 ==> 0 ==> enable protection
...
Nested exceptions operate the same way with each exception storing the
interrupted exception state all the way down.
NOTE That the reference counting for device access should be done at
this level to allow dev_mk_[readwrite|noaccess]() to interoperate
with the kmap calls.
More specifically, dax_iomap_actor() must enable device access while
dax_copy_from_iter() is running. dax_copy_from_iter() can (depending on
the underlying calls) call kmap_atomic(). While the code in
dax_iomap_actor() could be modified to interleave calls to pks_mk_*() it
is much better to allow this to be generally safe by placing the
reference counting in the lower level dev_mk_*() calls.
Finally the pkey value is never free'ed as this optimizes the
implementation to be either on or off using a static branch conditional
in the fast paths.
Signed-off-by: Ira Weiny <ira.weiny@intel.com>
---
Changes from internal V3
Add to list of ARCH_ENABLE_SUPERVISOR_PKEYS enablers- Loading branch information
Showing
9 changed files
with
172 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters