License cleanup: add SPDX GPL-2.0 license identifier to files with no license
Many source files in the tree are missing licensing information, which
makes it harder for compliance tools to determine the correct license.
By default all files without license information are under the default
license of the kernel, which is GPL version 2.
Update the files which contain no license information with the 'GPL-2.0'
SPDX license identifier. The SPDX identifier is a legally binding
shorthand, which can be used instead of the full boiler plate text.
This patch is based on work done by Thomas Gleixner and Kate Stewart and
Philippe Ombredanne.
How this work was done:
Patches were generated and checked against linux-4.14-rc6 for a subset of
the use cases:
- file had no licensing information it it.
- file was a */uapi/* one with no licensing information in it,
- file was a */uapi/* one with existing licensing information,
Further patches will be generated in subsequent months to fix up cases
where non-standard license headers were used, and references to license
had to be inferred by heuristics based on keywords.
The analysis to determine which SPDX License Identifier to be applied to
a file was done in a spreadsheet of side by side results from of the
output of two independent scanners (ScanCode & Windriver) producing SPDX
tag:value files created by Philippe Ombredanne. Philippe prepared the
base worksheet, and did an initial spot review of a few 1000 files.
The 4.13 kernel was the starting point of the analysis with 60,537 files
assessed. Kate Stewart did a file by file comparison of the scanner
results in the spreadsheet to determine which SPDX license identifier(s)
to be applied to the file. She confirmed any determination that was not
immediately clear with lawyers working with the Linux Foundation.
Criteria used to select files for SPDX license identifier tagging was:
- Files considered eligible had to be source code files.
- Make and config files were included as candidates if they contained >5
lines of source
- File already had some variant of a license header in it (even if <5
lines).
All documentation files were explicitly excluded.
The following heuristics were used to determine which SPDX license
identifiers to apply.
- when both scanners couldn't find any license traces, file was
considered to have no license information in it, and the top level
COPYING file license applied.
For non */uapi/* files that summary was:
SPDX license identifier # files
---------------------------------------------------|-------
GPL-2.0 11139
and resulted in the first patch in this series.
If that file was a */uapi/* path one, it was "GPL-2.0 WITH
Linux-syscall-note" otherwise it was "GPL-2.0". Results of that was:
SPDX license identifier # files
---------------------------------------------------|-------
GPL-2.0 WITH Linux-syscall-note 930
and resulted in the second patch in this series.
- if a file had some form of licensing information in it, and was one
of the */uapi/* ones, it was denoted with the Linux-syscall-note if
any GPL family license was found in the file or had no licensing in
it (per prior point). Results summary:
SPDX license identifier # files
---------------------------------------------------|------
GPL-2.0 WITH Linux-syscall-note 270
GPL-2.0+ WITH Linux-syscall-note 169
((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) 21
((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) 17
LGPL-2.1+ WITH Linux-syscall-note 15
GPL-1.0+ WITH Linux-syscall-note 14
((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) 5
LGPL-2.0+ WITH Linux-syscall-note 4
LGPL-2.1 WITH Linux-syscall-note 3
((GPL-2.0 WITH Linux-syscall-note) OR MIT) 3
((GPL-2.0 WITH Linux-syscall-note) AND MIT) 1
and that resulted in the third patch in this series.
- when the two scanners agreed on the detected license(s), that became
the concluded license(s).
- when there was disagreement between the two scanners (one detected a
license but the other didn't, or they both detected different
licenses) a manual inspection of the file occurred.
- In most cases a manual inspection of the information in the file
resulted in a clear resolution of the license that should apply (and
which scanner probably needed to revisit its heuristics).
- When it was not immediately clear, the license identifier was
confirmed with lawyers working with the Linux Foundation.
- If there was any question as to the appropriate license identifier,
the file was flagged for further research and to be revisited later
in time.
In total, over 70 hours of logged manual review was done on the
spreadsheet to determine the SPDX license identifiers to apply to the
source files by Kate, Philippe, Thomas and, in some cases, confirmation
by lawyers working with the Linux Foundation.
Kate also obtained a third independent scan of the 4.13 code base from
FOSSology, and compared selected files where the other two scanners
disagreed against that SPDX file, to see if there was new insights. The
Windriver scanner is based on an older version of FOSSology in part, so
they are related.
Thomas did random spot checks in about 500 files from the spreadsheets
for the uapi headers and agreed with SPDX license identifier in the
files he inspected. For the non-uapi files Thomas did random spot checks
in about 15000 files.
In initial set of patches against 4.14-rc6, 3 files were found to have
copy/paste license identifier errors, and have been fixed to reflect the
correct identifier.
Additionally Philippe spent 10 hours this week doing a detailed manual
inspection and review of the 12,461 patched files from the initial patch
version early this week with:
- a full scancode scan run, collecting the matched texts, detected
license ids and scores
- reviewing anything where there was a license detected (about 500+
files) to ensure that the applied SPDX license was correct
- reviewing anything where there was no detection but the patch license
was not GPL-2.0 WITH Linux-syscall-note to ensure that the applied
SPDX license was correct
This produced a worksheet with 20 files needing minor correction. This
worksheet was then exported into 3 different .csv files for the
different types of files to be modified.
These .csv files were then reviewed by Greg. Thomas wrote a script to
parse the csv files and add the proper SPDX tag to the file, in the
format that the file expected. This script was further refined by Greg
based on the output to detect more types of files automatically and to
distinguish between header and source .c files (which need different
comment types.) Finally Greg ran the script using the .csv files to
generate the patches.
Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org>
Reviewed-by: Philippe Ombredanne <pombredanne@nexb.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-11-01 14:07:57 +00:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
2009-02-09 02:46:18 +00:00
|
|
|
#ifndef _ASM_X86_PGTABLE_DEFS_H
|
|
|
|
#define _ASM_X86_PGTABLE_DEFS_H
|
|
|
|
|
|
|
|
#include <linux/const.h>
|
2017-07-17 21:10:07 +00:00
|
|
|
#include <linux/mem_encrypt.h>
|
|
|
|
|
2009-02-13 12:24:19 +00:00
|
|
|
#include <asm/page_types.h>
|
2009-02-09 02:46:18 +00:00
|
|
|
|
2015-02-11 23:26:41 +00:00
|
|
|
#define FIRST_USER_ADDRESS 0UL
|
2009-02-09 02:46:18 +00:00
|
|
|
|
|
|
|
#define _PAGE_BIT_PRESENT 0 /* is present */
|
|
|
|
#define _PAGE_BIT_RW 1 /* writeable */
|
|
|
|
#define _PAGE_BIT_USER 2 /* userspace addressable */
|
|
|
|
#define _PAGE_BIT_PWT 3 /* page write through */
|
|
|
|
#define _PAGE_BIT_PCD 4 /* page cache disabled */
|
|
|
|
#define _PAGE_BIT_ACCESSED 5 /* was accessed (raised by CPU) */
|
|
|
|
#define _PAGE_BIT_DIRTY 6 /* was written to (raised by CPU) */
|
|
|
|
#define _PAGE_BIT_PSE 7 /* 4 MB (or 2MB) page */
|
|
|
|
#define _PAGE_BIT_PAT 7 /* on 4KB pages */
|
|
|
|
#define _PAGE_BIT_GLOBAL 8 /* Global TLB entry PPro+ */
|
2014-06-04 23:06:30 +00:00
|
|
|
#define _PAGE_BIT_SOFTW1 9 /* available for programmer */
|
|
|
|
#define _PAGE_BIT_SOFTW2 10 /* " */
|
|
|
|
#define _PAGE_BIT_SOFTW3 11 /* " */
|
2009-02-09 02:46:18 +00:00
|
|
|
#define _PAGE_BIT_PAT_LARGE 12 /* On 2MB or 1GB pages */
|
2016-02-12 21:02:05 +00:00
|
|
|
#define _PAGE_BIT_SOFTW4 58 /* available for programmer */
|
|
|
|
#define _PAGE_BIT_PKEY_BIT0 59 /* Protection Keys, bit 1/4 */
|
|
|
|
#define _PAGE_BIT_PKEY_BIT1 60 /* Protection Keys, bit 2/4 */
|
|
|
|
#define _PAGE_BIT_PKEY_BIT2 61 /* Protection Keys, bit 3/4 */
|
|
|
|
#define _PAGE_BIT_PKEY_BIT3 62 /* Protection Keys, bit 4/4 */
|
|
|
|
#define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */
|
|
|
|
|
2014-06-04 23:06:30 +00:00
|
|
|
#define _PAGE_BIT_SPECIAL _PAGE_BIT_SOFTW1
|
|
|
|
#define _PAGE_BIT_CPA_TEST _PAGE_BIT_SOFTW1
|
2020-04-07 03:05:33 +00:00
|
|
|
#define _PAGE_BIT_UFFD_WP _PAGE_BIT_SOFTW2 /* userfaultfd wrprotected */
|
2014-06-04 23:06:30 +00:00
|
|
|
#define _PAGE_BIT_SOFT_DIRTY _PAGE_BIT_SOFTW3 /* software dirty tracking */
|
2016-02-12 21:02:05 +00:00
|
|
|
#define _PAGE_BIT_DEVMAP _PAGE_BIT_SOFTW4
|
2009-02-09 02:46:18 +00:00
|
|
|
|
|
|
|
/* If _PAGE_BIT_PRESENT is clear, we use these: */
|
|
|
|
/* - if the user mapped it with PROT_NONE; pte_present gives true */
|
|
|
|
#define _PAGE_BIT_PROTNONE _PAGE_BIT_GLOBAL
|
|
|
|
|
|
|
|
#define _PAGE_PRESENT (_AT(pteval_t, 1) << _PAGE_BIT_PRESENT)
|
|
|
|
#define _PAGE_RW (_AT(pteval_t, 1) << _PAGE_BIT_RW)
|
|
|
|
#define _PAGE_USER (_AT(pteval_t, 1) << _PAGE_BIT_USER)
|
|
|
|
#define _PAGE_PWT (_AT(pteval_t, 1) << _PAGE_BIT_PWT)
|
|
|
|
#define _PAGE_PCD (_AT(pteval_t, 1) << _PAGE_BIT_PCD)
|
|
|
|
#define _PAGE_ACCESSED (_AT(pteval_t, 1) << _PAGE_BIT_ACCESSED)
|
|
|
|
#define _PAGE_DIRTY (_AT(pteval_t, 1) << _PAGE_BIT_DIRTY)
|
|
|
|
#define _PAGE_PSE (_AT(pteval_t, 1) << _PAGE_BIT_PSE)
|
|
|
|
#define _PAGE_GLOBAL (_AT(pteval_t, 1) << _PAGE_BIT_GLOBAL)
|
2014-06-04 23:06:30 +00:00
|
|
|
#define _PAGE_SOFTW1 (_AT(pteval_t, 1) << _PAGE_BIT_SOFTW1)
|
2014-01-07 17:03:06 +00:00
|
|
|
#define _PAGE_SOFTW2 (_AT(pteval_t, 1) << _PAGE_BIT_SOFTW2)
|
2018-07-18 09:40:58 +00:00
|
|
|
#define _PAGE_SOFTW3 (_AT(pteval_t, 1) << _PAGE_BIT_SOFTW3)
|
2009-02-09 02:46:18 +00:00
|
|
|
#define _PAGE_PAT (_AT(pteval_t, 1) << _PAGE_BIT_PAT)
|
|
|
|
#define _PAGE_PAT_LARGE (_AT(pteval_t, 1) << _PAGE_BIT_PAT_LARGE)
|
|
|
|
#define _PAGE_SPECIAL (_AT(pteval_t, 1) << _PAGE_BIT_SPECIAL)
|
|
|
|
#define _PAGE_CPA_TEST (_AT(pteval_t, 1) << _PAGE_BIT_CPA_TEST)
|
2016-02-12 21:02:05 +00:00
|
|
|
#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
|
|
|
|
#define _PAGE_PKEY_BIT0 (_AT(pteval_t, 1) << _PAGE_BIT_PKEY_BIT0)
|
|
|
|
#define _PAGE_PKEY_BIT1 (_AT(pteval_t, 1) << _PAGE_BIT_PKEY_BIT1)
|
|
|
|
#define _PAGE_PKEY_BIT2 (_AT(pteval_t, 1) << _PAGE_BIT_PKEY_BIT2)
|
|
|
|
#define _PAGE_PKEY_BIT3 (_AT(pteval_t, 1) << _PAGE_BIT_PKEY_BIT3)
|
|
|
|
#else
|
|
|
|
#define _PAGE_PKEY_BIT0 (_AT(pteval_t, 0))
|
|
|
|
#define _PAGE_PKEY_BIT1 (_AT(pteval_t, 0))
|
|
|
|
#define _PAGE_PKEY_BIT2 (_AT(pteval_t, 0))
|
|
|
|
#define _PAGE_PKEY_BIT3 (_AT(pteval_t, 0))
|
|
|
|
#endif
|
2009-02-09 02:46:18 +00:00
|
|
|
|
2016-02-12 21:02:14 +00:00
|
|
|
#define _PAGE_PKEY_MASK (_PAGE_PKEY_BIT0 | \
|
|
|
|
_PAGE_PKEY_BIT1 | \
|
|
|
|
_PAGE_PKEY_BIT2 | \
|
|
|
|
_PAGE_PKEY_BIT3)
|
|
|
|
|
2016-07-08 00:19:12 +00:00
|
|
|
#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
|
|
|
|
#define _PAGE_KNL_ERRATUM_MASK (_PAGE_DIRTY | _PAGE_ACCESSED)
|
|
|
|
#else
|
|
|
|
#define _PAGE_KNL_ERRATUM_MASK 0
|
|
|
|
#endif
|
|
|
|
|
mm: soft-dirty bits for user memory changes tracking
The soft-dirty is a bit on a PTE which helps to track which pages a task
writes to. In order to do this tracking one should
1. Clear soft-dirty bits from PTEs ("echo 4 > /proc/PID/clear_refs)
2. Wait some time.
3. Read soft-dirty bits (55'th in /proc/PID/pagemap2 entries)
To do this tracking, the writable bit is cleared from PTEs when the
soft-dirty bit is. Thus, after this, when the task tries to modify a
page at some virtual address the #PF occurs and the kernel sets the
soft-dirty bit on the respective PTE.
Note, that although all the task's address space is marked as r/o after
the soft-dirty bits clear, the #PF-s that occur after that are processed
fast. This is so, since the pages are still mapped to physical memory,
and thus all the kernel does is finds this fact out and puts back
writable, dirty and soft-dirty bits on the PTE.
Another thing to note, is that when mremap moves PTEs they are marked
with soft-dirty as well, since from the user perspective mremap modifies
the virtual memory at mremap's new address.
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Cc: Matt Mackall <mpm@selenic.com>
Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
Cc: Glauber Costa <glommer@parallels.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: KOSAKI Motohiro <kosaki.motohiro@gmail.com>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-07-03 22:01:20 +00:00
|
|
|
#ifdef CONFIG_MEM_SOFT_DIRTY
|
2013-08-13 23:00:51 +00:00
|
|
|
#define _PAGE_SOFT_DIRTY (_AT(pteval_t, 1) << _PAGE_BIT_SOFT_DIRTY)
|
mm: soft-dirty bits for user memory changes tracking
The soft-dirty is a bit on a PTE which helps to track which pages a task
writes to. In order to do this tracking one should
1. Clear soft-dirty bits from PTEs ("echo 4 > /proc/PID/clear_refs)
2. Wait some time.
3. Read soft-dirty bits (55'th in /proc/PID/pagemap2 entries)
To do this tracking, the writable bit is cleared from PTEs when the
soft-dirty bit is. Thus, after this, when the task tries to modify a
page at some virtual address the #PF occurs and the kernel sets the
soft-dirty bit on the respective PTE.
Note, that although all the task's address space is marked as r/o after
the soft-dirty bits clear, the #PF-s that occur after that are processed
fast. This is so, since the pages are still mapped to physical memory,
and thus all the kernel does is finds this fact out and puts back
writable, dirty and soft-dirty bits on the PTE.
Another thing to note, is that when mremap moves PTEs they are marked
with soft-dirty as well, since from the user perspective mremap modifies
the virtual memory at mremap's new address.
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Cc: Matt Mackall <mpm@selenic.com>
Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
Cc: Glauber Costa <glommer@parallels.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: KOSAKI Motohiro <kosaki.motohiro@gmail.com>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-07-03 22:01:20 +00:00
|
|
|
#else
|
|
|
|
#define _PAGE_SOFT_DIRTY (_AT(pteval_t, 0))
|
|
|
|
#endif
|
|
|
|
|
2013-08-13 23:00:49 +00:00
|
|
|
/*
|
|
|
|
* Tracking soft dirty bit when a page goes to a swap is tricky.
|
|
|
|
* We need a bit which can be stored in pte _and_ not conflict
|
2017-09-08 23:10:46 +00:00
|
|
|
* with swap entry format. On x86 bits 1-4 are *not* involved
|
|
|
|
* into swap entry computation, but bit 7 is used for thp migration,
|
|
|
|
* so we borrow bit 1 for soft dirty tracking.
|
2013-09-11 21:22:47 +00:00
|
|
|
*
|
|
|
|
* Please note that this bit must be treated as swap dirty page
|
2017-09-08 23:10:46 +00:00
|
|
|
* mark if and only if the PTE/PMD has present bit clear!
|
2013-08-13 23:00:49 +00:00
|
|
|
*/
|
|
|
|
#ifdef CONFIG_MEM_SOFT_DIRTY
|
2017-09-08 23:10:46 +00:00
|
|
|
#define _PAGE_SWP_SOFT_DIRTY _PAGE_RW
|
2013-08-13 23:00:49 +00:00
|
|
|
#else
|
|
|
|
#define _PAGE_SWP_SOFT_DIRTY (_AT(pteval_t, 0))
|
|
|
|
#endif
|
|
|
|
|
2020-04-07 03:05:33 +00:00
|
|
|
#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP
|
|
|
|
#define _PAGE_UFFD_WP (_AT(pteval_t, 1) << _PAGE_BIT_UFFD_WP)
|
|
|
|
#define _PAGE_SWP_UFFD_WP _PAGE_USER
|
|
|
|
#else
|
|
|
|
#define _PAGE_UFFD_WP (_AT(pteval_t, 0))
|
|
|
|
#define _PAGE_SWP_UFFD_WP (_AT(pteval_t, 0))
|
|
|
|
#endif
|
|
|
|
|
2009-02-09 02:46:18 +00:00
|
|
|
#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
|
|
|
|
#define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_NX)
|
2016-01-16 00:56:37 +00:00
|
|
|
#define _PAGE_DEVMAP (_AT(u64, 1) << _PAGE_BIT_DEVMAP)
|
2009-02-09 02:46:18 +00:00
|
|
|
#else
|
|
|
|
#define _PAGE_NX (_AT(pteval_t, 0))
|
2016-01-16 00:56:37 +00:00
|
|
|
#define _PAGE_DEVMAP (_AT(pteval_t, 0))
|
2009-02-09 02:46:18 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#define _PAGE_PROTNONE (_AT(pteval_t, 1) << _PAGE_BIT_PROTNONE)
|
|
|
|
|
2016-02-12 21:02:10 +00:00
|
|
|
/*
|
|
|
|
* Set of bits not changed in pte_modify. The pte's
|
|
|
|
* protection key is treated like _PAGE_RW, for
|
|
|
|
* instance, and is *not* included in this mask since
|
|
|
|
* pte_modify() does modify it.
|
|
|
|
*/
|
2009-02-09 02:46:18 +00:00
|
|
|
#define _PAGE_CHG_MASK (PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT | \
|
2014-01-30 23:46:10 +00:00
|
|
|
_PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY | \
|
2020-04-07 03:05:33 +00:00
|
|
|
_PAGE_SOFT_DIRTY | _PAGE_DEVMAP | _PAGE_ENC | \
|
|
|
|
_PAGE_UFFD_WP)
|
2015-02-12 22:58:32 +00:00
|
|
|
#define _HPAGE_CHG_MASK (_PAGE_CHG_MASK | _PAGE_PSE)
|
2009-02-09 02:46:18 +00:00
|
|
|
|
2014-11-03 13:01:47 +00:00
|
|
|
/*
|
|
|
|
* The cache modes defined here are used to translate between pure SW usage
|
|
|
|
* and the HW defined cache mode bits and/or PAT entries.
|
|
|
|
*
|
|
|
|
* The resulting bits for PWT, PCD and PAT should be chosen in a way
|
|
|
|
* to have the WB mode at index 0 (all bits clear). This is the default
|
|
|
|
* right now and likely would break too much if changed.
|
|
|
|
*/
|
|
|
|
#ifndef __ASSEMBLY__
|
|
|
|
enum page_cache_mode {
|
2019-11-20 16:38:39 +00:00
|
|
|
_PAGE_CACHE_MODE_WB = 0,
|
|
|
|
_PAGE_CACHE_MODE_WC = 1,
|
2014-11-03 13:01:47 +00:00
|
|
|
_PAGE_CACHE_MODE_UC_MINUS = 2,
|
2019-11-20 16:38:39 +00:00
|
|
|
_PAGE_CACHE_MODE_UC = 3,
|
|
|
|
_PAGE_CACHE_MODE_WT = 4,
|
|
|
|
_PAGE_CACHE_MODE_WP = 5,
|
|
|
|
|
|
|
|
_PAGE_CACHE_MODE_NUM = 8
|
2014-11-03 13:01:47 +00:00
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2019-11-20 16:38:39 +00:00
|
|
|
#define _PAGE_ENC (_AT(pteval_t, sme_me_mask))
|
2014-11-03 13:01:47 +00:00
|
|
|
|
2019-11-20 16:38:39 +00:00
|
|
|
#define _PAGE_CACHE_MASK (_PAGE_PWT | _PAGE_PCD | _PAGE_PAT)
|
2009-02-09 02:46:18 +00:00
|
|
|
|
2019-11-20 16:38:39 +00:00
|
|
|
#define _PAGE_NOCACHE (cachemode2protval(_PAGE_CACHE_MODE_UC))
|
|
|
|
#define _PAGE_CACHE_WP (cachemode2protval(_PAGE_CACHE_MODE_WP))
|
2017-07-17 21:10:07 +00:00
|
|
|
|
2019-11-20 16:38:39 +00:00
|
|
|
#define __PP _PAGE_PRESENT
|
|
|
|
#define __RW _PAGE_RW
|
|
|
|
#define _USR _PAGE_USER
|
|
|
|
#define ___A _PAGE_ACCESSED
|
|
|
|
#define ___D _PAGE_DIRTY
|
|
|
|
#define ___G _PAGE_GLOBAL
|
|
|
|
#define __NX _PAGE_NX
|
|
|
|
|
|
|
|
#define _ENC _PAGE_ENC
|
|
|
|
#define __WP _PAGE_CACHE_WP
|
|
|
|
#define __NC _PAGE_NOCACHE
|
|
|
|
#define _PSE _PAGE_PSE
|
|
|
|
|
|
|
|
#define pgprot_val(x) ((x).pgprot)
|
|
|
|
#define __pgprot(x) ((pgprot_t) { (x) } )
|
|
|
|
#define __pg(x) __pgprot(x)
|
|
|
|
|
|
|
|
#define _PAGE_PAT_LARGE (_AT(pteval_t, 1) << _PAGE_BIT_PAT_LARGE)
|
|
|
|
|
|
|
|
#define PAGE_NONE __pg( 0| 0| 0|___A| 0| 0| 0|___G)
|
|
|
|
#define PAGE_SHARED __pg(__PP|__RW|_USR|___A|__NX| 0| 0| 0)
|
|
|
|
#define PAGE_SHARED_EXEC __pg(__PP|__RW|_USR|___A| 0| 0| 0| 0)
|
|
|
|
#define PAGE_COPY_NOEXEC __pg(__PP| 0|_USR|___A|__NX| 0| 0| 0)
|
|
|
|
#define PAGE_COPY_EXEC __pg(__PP| 0|_USR|___A| 0| 0| 0| 0)
|
|
|
|
#define PAGE_COPY __pg(__PP| 0|_USR|___A|__NX| 0| 0| 0)
|
|
|
|
#define PAGE_READONLY __pg(__PP| 0|_USR|___A|__NX| 0| 0| 0)
|
|
|
|
#define PAGE_READONLY_EXEC __pg(__PP| 0|_USR|___A| 0| 0| 0| 0)
|
|
|
|
|
|
|
|
#define __PAGE_KERNEL (__PP|__RW| 0|___A|__NX|___D| 0|___G)
|
|
|
|
#define __PAGE_KERNEL_EXEC (__PP|__RW| 0|___A| 0|___D| 0|___G)
|
|
|
|
#define _KERNPG_TABLE_NOENC (__PP|__RW| 0|___A| 0|___D| 0| 0)
|
|
|
|
#define _KERNPG_TABLE (__PP|__RW| 0|___A| 0|___D| 0| 0| _ENC)
|
|
|
|
#define _PAGE_TABLE_NOENC (__PP|__RW|_USR|___A| 0|___D| 0| 0)
|
|
|
|
#define _PAGE_TABLE (__PP|__RW|_USR|___A| 0|___D| 0| 0| _ENC)
|
|
|
|
#define __PAGE_KERNEL_RO (__PP| 0| 0|___A|__NX|___D| 0|___G)
|
2020-06-26 03:30:40 +00:00
|
|
|
#define __PAGE_KERNEL_ROX (__PP| 0| 0|___A| 0|___D| 0|___G)
|
2019-11-20 16:38:39 +00:00
|
|
|
#define __PAGE_KERNEL_NOCACHE (__PP|__RW| 0|___A|__NX|___D| 0|___G| __NC)
|
|
|
|
#define __PAGE_KERNEL_VVAR (__PP| 0|_USR|___A|__NX|___D| 0|___G)
|
|
|
|
#define __PAGE_KERNEL_LARGE (__PP|__RW| 0|___A|__NX|___D|_PSE|___G)
|
|
|
|
#define __PAGE_KERNEL_LARGE_EXEC (__PP|__RW| 0|___A| 0|___D|_PSE|___G)
|
|
|
|
#define __PAGE_KERNEL_WP (__PP|__RW| 0|___A|__NX|___D| 0|___G| __WP)
|
|
|
|
|
|
|
|
|
|
|
|
#define __PAGE_KERNEL_IO __PAGE_KERNEL
|
|
|
|
#define __PAGE_KERNEL_IO_NOCACHE __PAGE_KERNEL_NOCACHE
|
2017-07-17 21:10:07 +00:00
|
|
|
|
|
|
|
|
2019-11-20 16:38:39 +00:00
|
|
|
#ifndef __ASSEMBLY__
|
2017-07-17 21:10:09 +00:00
|
|
|
|
2019-11-20 16:38:39 +00:00
|
|
|
#define __PAGE_KERNEL_ENC (__PAGE_KERNEL | _ENC)
|
|
|
|
#define __PAGE_KERNEL_ENC_WP (__PAGE_KERNEL_WP | _ENC)
|
|
|
|
#define __PAGE_KERNEL_NOENC (__PAGE_KERNEL | 0)
|
|
|
|
#define __PAGE_KERNEL_NOENC_WP (__PAGE_KERNEL_WP | 0)
|
2017-07-17 21:10:09 +00:00
|
|
|
|
2019-11-20 16:38:39 +00:00
|
|
|
#define __pgprot_mask(x) __pgprot((x) & __default_kernel_pte_mask)
|
2018-04-06 20:55:06 +00:00
|
|
|
|
2019-11-20 16:38:39 +00:00
|
|
|
#define PAGE_KERNEL __pgprot_mask(__PAGE_KERNEL | _ENC)
|
|
|
|
#define PAGE_KERNEL_NOENC __pgprot_mask(__PAGE_KERNEL | 0)
|
|
|
|
#define PAGE_KERNEL_RO __pgprot_mask(__PAGE_KERNEL_RO | _ENC)
|
|
|
|
#define PAGE_KERNEL_EXEC __pgprot_mask(__PAGE_KERNEL_EXEC | _ENC)
|
|
|
|
#define PAGE_KERNEL_EXEC_NOENC __pgprot_mask(__PAGE_KERNEL_EXEC | 0)
|
2020-06-26 03:30:40 +00:00
|
|
|
#define PAGE_KERNEL_ROX __pgprot_mask(__PAGE_KERNEL_ROX | _ENC)
|
2019-11-20 16:38:39 +00:00
|
|
|
#define PAGE_KERNEL_NOCACHE __pgprot_mask(__PAGE_KERNEL_NOCACHE | _ENC)
|
|
|
|
#define PAGE_KERNEL_LARGE __pgprot_mask(__PAGE_KERNEL_LARGE | _ENC)
|
|
|
|
#define PAGE_KERNEL_LARGE_EXEC __pgprot_mask(__PAGE_KERNEL_LARGE_EXEC | _ENC)
|
|
|
|
#define PAGE_KERNEL_VVAR __pgprot_mask(__PAGE_KERNEL_VVAR | _ENC)
|
2018-04-06 20:55:06 +00:00
|
|
|
|
2019-11-20 16:38:39 +00:00
|
|
|
#define PAGE_KERNEL_IO __pgprot_mask(__PAGE_KERNEL_IO)
|
|
|
|
#define PAGE_KERNEL_IO_NOCACHE __pgprot_mask(__PAGE_KERNEL_IO_NOCACHE)
|
2017-07-17 21:10:07 +00:00
|
|
|
|
|
|
|
#endif /* __ASSEMBLY__ */
|
2009-02-09 02:46:18 +00:00
|
|
|
|
|
|
|
/* xwr */
|
|
|
|
#define __P000 PAGE_NONE
|
|
|
|
#define __P001 PAGE_READONLY
|
|
|
|
#define __P010 PAGE_COPY
|
|
|
|
#define __P011 PAGE_COPY
|
|
|
|
#define __P100 PAGE_READONLY_EXEC
|
|
|
|
#define __P101 PAGE_READONLY_EXEC
|
|
|
|
#define __P110 PAGE_COPY_EXEC
|
|
|
|
#define __P111 PAGE_COPY_EXEC
|
|
|
|
|
|
|
|
#define __S000 PAGE_NONE
|
|
|
|
#define __S001 PAGE_READONLY
|
|
|
|
#define __S010 PAGE_SHARED
|
|
|
|
#define __S011 PAGE_SHARED
|
|
|
|
#define __S100 PAGE_READONLY_EXEC
|
|
|
|
#define __S101 PAGE_READONLY_EXEC
|
|
|
|
#define __S110 PAGE_SHARED_EXEC
|
|
|
|
#define __S111 PAGE_SHARED_EXEC
|
|
|
|
|
|
|
|
/*
|
|
|
|
* early identity mapping pte attrib macros.
|
|
|
|
*/
|
|
|
|
#ifdef CONFIG_X86_64
|
|
|
|
#define __PAGE_KERNEL_IDENT_LARGE_EXEC __PAGE_KERNEL_LARGE_EXEC
|
|
|
|
#else
|
|
|
|
#define PTE_IDENT_ATTR 0x003 /* PRESENT+RW */
|
2014-03-13 23:01:27 +00:00
|
|
|
#define PDE_IDENT_ATTR 0x063 /* PRESENT+RW+DIRTY+ACCESSED */
|
2009-02-09 02:46:18 +00:00
|
|
|
#define PGD_IDENT_ATTR 0x001 /* PRESENT (no other attributes) */
|
|
|
|
#endif
|
|
|
|
|
2009-02-11 18:20:05 +00:00
|
|
|
#ifdef CONFIG_X86_32
|
2012-10-02 17:01:25 +00:00
|
|
|
# include <asm/pgtable_32_types.h>
|
2009-02-11 18:20:05 +00:00
|
|
|
#else
|
2012-10-02 17:01:25 +00:00
|
|
|
# include <asm/pgtable_64_types.h>
|
2009-02-11 18:20:05 +00:00
|
|
|
#endif
|
|
|
|
|
2009-02-09 02:46:18 +00:00
|
|
|
#ifndef __ASSEMBLY__
|
|
|
|
|
2009-02-11 18:20:05 +00:00
|
|
|
#include <linux/types.h>
|
|
|
|
|
2015-09-17 18:24:16 +00:00
|
|
|
/* Extracts the PFN from a (pte|pmd|pud|pgd)val_t of a 4KB page */
|
2009-02-13 19:01:54 +00:00
|
|
|
#define PTE_PFN_MASK ((pteval_t)PHYSICAL_PAGE_MASK)
|
|
|
|
|
2016-02-12 21:02:10 +00:00
|
|
|
/*
|
|
|
|
* Extracts the flags from a (pte|pmd|pud|pgd)val_t
|
|
|
|
* This includes the protection key value.
|
|
|
|
*/
|
2009-02-13 19:01:54 +00:00
|
|
|
#define PTE_FLAGS_MASK (~PTE_PFN_MASK)
|
|
|
|
|
2009-02-11 18:20:05 +00:00
|
|
|
typedef struct pgprot { pgprotval_t pgprot; } pgprot_t;
|
|
|
|
|
|
|
|
typedef struct { pgdval_t pgd; } pgd_t;
|
|
|
|
|
2020-06-02 04:51:32 +00:00
|
|
|
static inline pgprot_t pgprot_nx(pgprot_t prot)
|
|
|
|
{
|
|
|
|
return __pgprot(pgprot_val(prot) | _PAGE_NX);
|
|
|
|
}
|
|
|
|
#define pgprot_nx pgprot_nx
|
|
|
|
|
2018-07-18 09:40:58 +00:00
|
|
|
#ifdef CONFIG_X86_PAE
|
|
|
|
|
|
|
|
/*
|
|
|
|
* PHYSICAL_PAGE_MASK might be non-constant when SME is compiled in, so we can't
|
|
|
|
* use it here.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define PGD_PAE_PAGE_MASK ((signed long)PAGE_MASK)
|
|
|
|
#define PGD_PAE_PHYS_MASK (((1ULL << __PHYSICAL_MASK_SHIFT)-1) & PGD_PAE_PAGE_MASK)
|
|
|
|
|
|
|
|
/*
|
|
|
|
* PAE allows Base Address, P, PWT, PCD and AVL bits to be set in PGD entries.
|
|
|
|
* All other bits are Reserved MBZ
|
|
|
|
*/
|
|
|
|
#define PGD_ALLOWED_BITS (PGD_PAE_PHYS_MASK | _PAGE_PRESENT | \
|
|
|
|
_PAGE_PWT | _PAGE_PCD | \
|
|
|
|
_PAGE_SOFTW1 | _PAGE_SOFTW2 | _PAGE_SOFTW3)
|
|
|
|
|
|
|
|
#else
|
|
|
|
/* No need to mask any bits for !PAE */
|
|
|
|
#define PGD_ALLOWED_BITS (~0ULL)
|
|
|
|
#endif
|
|
|
|
|
2009-02-11 18:20:05 +00:00
|
|
|
static inline pgd_t native_make_pgd(pgdval_t val)
|
|
|
|
{
|
2018-07-18 09:40:58 +00:00
|
|
|
return (pgd_t) { val & PGD_ALLOWED_BITS };
|
2009-02-11 18:20:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline pgdval_t native_pgd_val(pgd_t pgd)
|
|
|
|
{
|
2018-07-18 09:40:58 +00:00
|
|
|
return pgd.pgd & PGD_ALLOWED_BITS;
|
2009-02-11 18:20:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline pgdval_t pgd_flags(pgd_t pgd)
|
|
|
|
{
|
|
|
|
return native_pgd_val(pgd) & PTE_FLAGS_MASK;
|
|
|
|
}
|
|
|
|
|
2017-03-13 14:33:04 +00:00
|
|
|
#if CONFIG_PGTABLE_LEVELS > 4
|
2017-03-30 08:07:29 +00:00
|
|
|
typedef struct { p4dval_t p4d; } p4d_t;
|
2017-03-13 14:33:04 +00:00
|
|
|
|
2017-03-30 08:07:29 +00:00
|
|
|
static inline p4d_t native_make_p4d(pudval_t val)
|
|
|
|
{
|
|
|
|
return (p4d_t) { val };
|
|
|
|
}
|
2017-03-13 14:33:04 +00:00
|
|
|
|
2017-03-30 08:07:29 +00:00
|
|
|
static inline p4dval_t native_p4d_val(p4d_t p4d)
|
|
|
|
{
|
|
|
|
return p4d.p4d;
|
|
|
|
}
|
2017-03-13 14:33:04 +00:00
|
|
|
#else
|
2017-03-17 18:55:15 +00:00
|
|
|
#include <asm-generic/pgtable-nop4d.h>
|
2017-03-09 14:24:05 +00:00
|
|
|
|
2017-07-17 21:10:31 +00:00
|
|
|
static inline p4d_t native_make_p4d(pudval_t val)
|
|
|
|
{
|
|
|
|
return (p4d_t) { .pgd = native_make_pgd((pgdval_t)val) };
|
|
|
|
}
|
|
|
|
|
2017-03-13 14:33:04 +00:00
|
|
|
static inline p4dval_t native_p4d_val(p4d_t p4d)
|
|
|
|
{
|
2017-03-17 18:55:15 +00:00
|
|
|
return native_pgd_val(p4d.pgd);
|
2017-03-13 14:33:04 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if CONFIG_PGTABLE_LEVELS > 3
|
2009-02-11 18:20:05 +00:00
|
|
|
typedef struct { pudval_t pud; } pud_t;
|
|
|
|
|
|
|
|
static inline pud_t native_make_pud(pmdval_t val)
|
|
|
|
{
|
|
|
|
return (pud_t) { val };
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline pudval_t native_pud_val(pud_t pud)
|
|
|
|
{
|
|
|
|
return pud.pud;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
#include <asm-generic/pgtable-nopud.h>
|
|
|
|
|
2018-02-19 14:48:11 +00:00
|
|
|
static inline pud_t native_make_pud(pudval_t val)
|
|
|
|
{
|
|
|
|
return (pud_t) { .p4d.pgd = native_make_pgd(val) };
|
|
|
|
}
|
|
|
|
|
2009-02-11 18:20:05 +00:00
|
|
|
static inline pudval_t native_pud_val(pud_t pud)
|
|
|
|
{
|
2017-03-17 18:55:15 +00:00
|
|
|
return native_pgd_val(pud.p4d.pgd);
|
2009-02-11 18:20:05 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-04-14 22:46:14 +00:00
|
|
|
#if CONFIG_PGTABLE_LEVELS > 2
|
2009-02-11 18:20:05 +00:00
|
|
|
typedef struct { pmdval_t pmd; } pmd_t;
|
|
|
|
|
|
|
|
static inline pmd_t native_make_pmd(pmdval_t val)
|
|
|
|
{
|
|
|
|
return (pmd_t) { val };
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline pmdval_t native_pmd_val(pmd_t pmd)
|
|
|
|
{
|
|
|
|
return pmd.pmd;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
#include <asm-generic/pgtable-nopmd.h>
|
|
|
|
|
2018-02-19 14:48:11 +00:00
|
|
|
static inline pmd_t native_make_pmd(pmdval_t val)
|
|
|
|
{
|
|
|
|
return (pmd_t) { .pud.p4d.pgd = native_make_pgd(val) };
|
|
|
|
}
|
|
|
|
|
2009-02-11 18:20:05 +00:00
|
|
|
static inline pmdval_t native_pmd_val(pmd_t pmd)
|
|
|
|
{
|
2017-03-17 18:55:15 +00:00
|
|
|
return native_pgd_val(pmd.pud.p4d.pgd);
|
2009-02-11 18:20:05 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2017-03-13 14:33:04 +00:00
|
|
|
static inline p4dval_t p4d_pfn_mask(p4d_t p4d)
|
|
|
|
{
|
|
|
|
/* No 512 GiB huge pages yet */
|
|
|
|
return PTE_PFN_MASK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline p4dval_t p4d_flags_mask(p4d_t p4d)
|
|
|
|
{
|
|
|
|
return ~p4d_pfn_mask(p4d);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline p4dval_t p4d_flags(p4d_t p4d)
|
|
|
|
{
|
|
|
|
return native_p4d_val(p4d) & p4d_flags_mask(p4d);
|
|
|
|
}
|
|
|
|
|
2015-09-17 18:24:16 +00:00
|
|
|
static inline pudval_t pud_pfn_mask(pud_t pud)
|
|
|
|
{
|
|
|
|
if (native_pud_val(pud) & _PAGE_PSE)
|
2015-11-30 10:10:33 +00:00
|
|
|
return PHYSICAL_PUD_PAGE_MASK;
|
2015-09-17 18:24:16 +00:00
|
|
|
else
|
|
|
|
return PTE_PFN_MASK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline pudval_t pud_flags_mask(pud_t pud)
|
|
|
|
{
|
2015-11-30 10:10:33 +00:00
|
|
|
return ~pud_pfn_mask(pud);
|
2015-09-17 18:24:16 +00:00
|
|
|
}
|
|
|
|
|
2009-02-11 18:20:05 +00:00
|
|
|
static inline pudval_t pud_flags(pud_t pud)
|
|
|
|
{
|
2015-09-17 18:24:17 +00:00
|
|
|
return native_pud_val(pud) & pud_flags_mask(pud);
|
2009-02-11 18:20:05 +00:00
|
|
|
}
|
|
|
|
|
2015-09-17 18:24:16 +00:00
|
|
|
static inline pmdval_t pmd_pfn_mask(pmd_t pmd)
|
|
|
|
{
|
|
|
|
if (native_pmd_val(pmd) & _PAGE_PSE)
|
2015-11-30 10:10:33 +00:00
|
|
|
return PHYSICAL_PMD_PAGE_MASK;
|
2015-09-17 18:24:16 +00:00
|
|
|
else
|
|
|
|
return PTE_PFN_MASK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline pmdval_t pmd_flags_mask(pmd_t pmd)
|
|
|
|
{
|
2015-11-30 10:10:33 +00:00
|
|
|
return ~pmd_pfn_mask(pmd);
|
2015-09-17 18:24:16 +00:00
|
|
|
}
|
|
|
|
|
2009-02-11 18:20:05 +00:00
|
|
|
static inline pmdval_t pmd_flags(pmd_t pmd)
|
|
|
|
{
|
2015-09-17 18:24:17 +00:00
|
|
|
return native_pmd_val(pmd) & pmd_flags_mask(pmd);
|
2009-02-11 18:20:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline pte_t native_make_pte(pteval_t val)
|
|
|
|
{
|
|
|
|
return (pte_t) { .pte = val };
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline pteval_t native_pte_val(pte_t pte)
|
|
|
|
{
|
|
|
|
return pte.pte;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline pteval_t pte_flags(pte_t pte)
|
|
|
|
{
|
|
|
|
return native_pte_val(pte) & PTE_FLAGS_MASK;
|
|
|
|
}
|
|
|
|
|
2014-11-03 13:01:47 +00:00
|
|
|
#define __pte2cm_idx(cb) \
|
|
|
|
((((cb) >> (_PAGE_BIT_PAT - 2)) & 4) | \
|
|
|
|
(((cb) >> (_PAGE_BIT_PCD - 1)) & 2) | \
|
|
|
|
(((cb) >> _PAGE_BIT_PWT) & 1))
|
2014-11-03 13:02:03 +00:00
|
|
|
#define __cm_idx2pte(i) \
|
|
|
|
((((i) & 4) << (_PAGE_BIT_PAT - 2)) | \
|
|
|
|
(((i) & 2) << (_PAGE_BIT_PCD - 1)) | \
|
|
|
|
(((i) & 1) << _PAGE_BIT_PWT))
|
2014-11-03 13:01:47 +00:00
|
|
|
|
2020-04-08 15:27:45 +00:00
|
|
|
unsigned long cachemode2protval(enum page_cache_mode pcm);
|
|
|
|
|
2020-04-22 16:53:08 +00:00
|
|
|
static inline pgprotval_t protval_4k_2_large(pgprotval_t val)
|
2014-11-03 13:01:47 +00:00
|
|
|
{
|
2020-04-08 15:27:44 +00:00
|
|
|
return (val & ~(_PAGE_PAT | _PAGE_PAT_LARGE)) |
|
2014-11-03 13:01:47 +00:00
|
|
|
((val & _PAGE_PAT) << (_PAGE_BIT_PAT_LARGE - _PAGE_BIT_PAT));
|
|
|
|
}
|
2020-04-08 15:27:44 +00:00
|
|
|
static inline pgprot_t pgprot_4k_2_large(pgprot_t pgprot)
|
2014-11-03 13:01:47 +00:00
|
|
|
{
|
2020-04-08 15:27:44 +00:00
|
|
|
return __pgprot(protval_4k_2_large(pgprot_val(pgprot)));
|
2014-11-03 13:01:47 +00:00
|
|
|
}
|
2020-04-22 16:53:08 +00:00
|
|
|
static inline pgprotval_t protval_large_2_4k(pgprotval_t val)
|
2014-11-03 13:01:47 +00:00
|
|
|
{
|
2020-04-08 15:27:44 +00:00
|
|
|
return (val & ~(_PAGE_PAT | _PAGE_PAT_LARGE)) |
|
|
|
|
((val & _PAGE_PAT_LARGE) >>
|
|
|
|
(_PAGE_BIT_PAT_LARGE - _PAGE_BIT_PAT));
|
2014-11-03 13:01:47 +00:00
|
|
|
}
|
|
|
|
static inline pgprot_t pgprot_large_2_4k(pgprot_t pgprot)
|
|
|
|
{
|
2020-04-08 15:27:44 +00:00
|
|
|
return __pgprot(protval_large_2_4k(pgprot_val(pgprot)));
|
2014-11-03 13:01:47 +00:00
|
|
|
}
|
|
|
|
|
2009-02-11 18:20:05 +00:00
|
|
|
|
|
|
|
typedef struct page *pgtable_t;
|
|
|
|
|
2009-02-09 02:46:18 +00:00
|
|
|
extern pteval_t __supported_pte_mask;
|
2018-04-06 20:55:06 +00:00
|
|
|
extern pteval_t __default_kernel_pte_mask;
|
2009-09-21 20:40:42 +00:00
|
|
|
extern void set_nx(void);
|
2009-02-11 18:20:05 +00:00
|
|
|
extern int nx_enabled;
|
2009-02-09 02:46:18 +00:00
|
|
|
|
|
|
|
#define pgprot_writecombine pgprot_writecombine
|
|
|
|
extern pgprot_t pgprot_writecombine(pgprot_t prot);
|
|
|
|
|
2015-06-04 16:55:18 +00:00
|
|
|
#define pgprot_writethrough pgprot_writethrough
|
|
|
|
extern pgprot_t pgprot_writethrough(pgprot_t prot);
|
|
|
|
|
2009-02-09 02:46:18 +00:00
|
|
|
/* Indicate that x86 has its own track and untrack pfn vma functions */
|
|
|
|
#define __HAVE_PFNMAP_TRACKING
|
|
|
|
|
|
|
|
#define __HAVE_PHYS_MEM_ACCESS_PROT
|
|
|
|
struct file;
|
|
|
|
pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
|
|
|
|
unsigned long size, pgprot_t vma_prot);
|
|
|
|
|
|
|
|
/* Install a pte for a particular vaddr in kernel space. */
|
|
|
|
void set_pte_vaddr(unsigned long vaddr, pte_t pte);
|
|
|
|
|
|
|
|
#ifdef CONFIG_X86_32
|
2012-08-21 20:22:38 +00:00
|
|
|
extern void native_pagetable_init(void);
|
2009-02-09 02:46:18 +00:00
|
|
|
#else
|
2012-08-21 20:22:39 +00:00
|
|
|
#define native_pagetable_init paging_init
|
2009-02-09 02:46:18 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
struct seq_file;
|
|
|
|
extern void arch_report_meminfo(struct seq_file *m);
|
|
|
|
|
2013-01-22 21:24:31 +00:00
|
|
|
enum pg_level {
|
2009-02-09 02:46:18 +00:00
|
|
|
PG_LEVEL_NONE,
|
|
|
|
PG_LEVEL_4K,
|
|
|
|
PG_LEVEL_2M,
|
|
|
|
PG_LEVEL_1G,
|
2017-03-13 14:33:04 +00:00
|
|
|
PG_LEVEL_512G,
|
2009-02-09 02:46:18 +00:00
|
|
|
PG_LEVEL_NUM
|
|
|
|
};
|
|
|
|
|
|
|
|
#ifdef CONFIG_PROC_FS
|
|
|
|
extern void update_page_count(int level, unsigned long pages);
|
|
|
|
#else
|
|
|
|
static inline void update_page_count(int level, unsigned long pages) { }
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Helper function that returns the kernel pagetable entry controlling
|
|
|
|
* the virtual address 'address'. NULL means no pagetable entry present.
|
|
|
|
* NOTE: the return type is pte_t but if the pmd is PSE then we return it
|
|
|
|
* as a pte too.
|
|
|
|
*/
|
|
|
|
extern pte_t *lookup_address(unsigned long address, unsigned int *level);
|
2013-12-06 21:13:04 +00:00
|
|
|
extern pte_t *lookup_address_in_pgd(pgd_t *pgd, unsigned long address,
|
|
|
|
unsigned int *level);
|
2020-01-08 20:24:39 +00:00
|
|
|
|
|
|
|
struct mm_struct;
|
|
|
|
extern pte_t *lookup_address_in_mm(struct mm_struct *mm, unsigned long address,
|
|
|
|
unsigned int *level);
|
2014-11-28 10:53:56 +00:00
|
|
|
extern pmd_t *lookup_pmd_address(unsigned long address);
|
x86, mm: Create slow_virt_to_phys()
This is necessary because __pa() does not work on some kinds of
memory, like vmalloc() or the alloc_remap() areas on 32-bit
NUMA systems. We have some functions to do conversions _like_
this in the vmalloc() code (like vmalloc_to_page()), but they
do not work on sizes other than 4k pages. We would potentially
need to be able to handle all the page sizes that we use for
the kernel linear mapping (4k, 2M, 1G).
In practice, on 32-bit NUMA systems, the percpu areas get stuck
in the alloc_remap() area. Any __pa() call on them will break
and basically return garbage.
This patch introduces a new function slow_virt_to_phys(), which
walks the kernel page tables on x86 and should do precisely
the same logical thing as __pa(), but actually work on a wider
range of memory. It should work on the normal linear mapping,
vmalloc(), kmap(), etc...
Signed-off-by: Dave Hansen <dave@linux.vnet.ibm.com>
Link: http://lkml.kernel.org/r/20130122212433.4D1FCA62@kernel.stglabs.ibm.com
Acked-by: Rik van Riel <riel@redhat.com>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
2013-01-22 21:24:33 +00:00
|
|
|
extern phys_addr_t slow_virt_to_phys(void *__address);
|
2018-11-29 17:12:23 +00:00
|
|
|
extern int __init kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn,
|
|
|
|
unsigned long address,
|
|
|
|
unsigned numpages,
|
|
|
|
unsigned long page_flags);
|
|
|
|
extern int __init kernel_unmap_pages_in_pgd(pgd_t *pgd, unsigned long address,
|
|
|
|
unsigned long numpages);
|
2009-02-09 02:46:18 +00:00
|
|
|
#endif /* !__ASSEMBLY__ */
|
|
|
|
|
|
|
|
#endif /* _ASM_X86_PGTABLE_DEFS_H */
|