Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1321954 > unrolled thread
| Started by | Dave Hansen <dave@sr71.net> |
|---|---|
| First post | 2016-01-29 19:20 +0100 |
| Last post | 2016-02-09 16:20 +0100 |
| Articles | 11 on this page of 31 — 3 participants |
Back to article view | Back to linux.kernel
[PATCH 00/31] x86: Memory Protection Keys (v9) Dave Hansen <dave@sr71.net> - 2016-01-29 19:20 +0100
[PATCH 21/31] x86, pkeys: dump PKRU with other kernel registers Dave Hansen <dave@sr71.net> - 2016-01-29 19:20 +0100
[PATCH 26/31] x86, pkeys: add arch_validate_pkey() Dave Hansen <dave@sr71.net> - 2016-01-29 19:20 +0100
[PATCH 29/31] x86, pkeys: allow kernel to modify user pkey rights register Dave Hansen <dave@sr71.net> - 2016-01-29 19:20 +0100
[PATCH 03/31] x86, pkeys: Add Kconfig option Dave Hansen <dave@sr71.net> - 2016-01-29 19:20 +0100
[PATCH 09/31] x86, pkeys: store protection in high VMA flags Dave Hansen <dave@sr71.net> - 2016-01-29 19:20 +0100
[PATCH 05/31] x86, pkeys: define new CR4 bit Dave Hansen <dave@sr71.net> - 2016-01-29 19:30 +0100
[PATCH 23/31] x86, pkeys: add Kconfig prompt to existing config option Dave Hansen <dave@sr71.net> - 2016-01-29 19:30 +0100
[PATCH 12/31] signals, pkeys: notify userspace about protection key faults Dave Hansen <dave@sr71.net> - 2016-01-29 19:30 +0100
[PATCH 24/31] x86, pkeys: actually enable Memory Protection Keys in CPU Dave Hansen <dave@sr71.net> - 2016-01-29 19:30 +0100
[PATCH 15/31] mm: factor out VMA fault permission checking Dave Hansen <dave@sr71.net> - 2016-01-29 19:30 +0100
[PATCH 20/31] x86, pkeys: differentiate instruction fetches Dave Hansen <dave@sr71.net> - 2016-01-29 19:30 +0100
[PATCH 18/31] mm: do not enforce PKEY permissions on "foreign" mm access Dave Hansen <dave@sr71.net> - 2016-01-29 19:30 +0100
[PATCH 08/31] x86, pkeys: new page fault error code bit: PF_PK Dave Hansen <dave@sr71.net> - 2016-01-29 19:30 +0100
[PATCH 14/31] x86, pkeys: add functions to fetch PKRU Dave Hansen <dave@sr71.net> - 2016-01-29 19:30 +0100
[PATCH 04/31] x86, pkeys: cpuid bit definition Dave Hansen <dave@sr71.net> - 2016-01-29 19:30 +0100
[PATCH 10/31] x86, pkeys: arch-specific protection bits Dave Hansen <dave@sr71.net> - 2016-01-29 19:30 +0100
[PATCH 13/31] x86, pkeys: fill in pkey field in siginfo Dave Hansen <dave@sr71.net> - 2016-01-29 19:30 +0100
[PATCH 25/31] mm, multi-arch: pass a protection key in to calc_vm_flag_bits() Dave Hansen <dave@sr71.net> - 2016-01-29 19:30 +0100
[PATCH 17/31] x86, pkeys: check VMAs and PTEs for protection keys Dave Hansen <dave@sr71.net> - 2016-01-29 19:30 +0100
[PATCH 07/31] x86, pkeys: PTE bits for storing protection key Dave Hansen <dave@sr71.net> - 2016-01-29 19:30 +0100
[PATCH 02/31] x86, fpu: add placeholder for Processor Trace XSAVE state Dave Hansen <dave@sr71.net> - 2016-01-29 19:30 +0100
[PATCH 16/31] x86, mm: simplify get_user_pages() PTE bit handling Dave Hansen <dave@sr71.net> - 2016-01-29 19:30 +0100
[PATCH 11/31] x86, pkeys: pass VMA down in to fault signal generation code Dave Hansen <dave@sr71.net> - 2016-01-29 19:30 +0100
[PATCH 22/31] x86, pkeys: dump pkey from VMA in /proc/pid/smaps Dave Hansen <dave@sr71.net> - 2016-01-29 19:30 +0100
Re: [PATCH 22/31] x86, pkeys: dump pkey from VMA in /proc/pid/smaps Vlastimil Babka <vbabka@suse.cz> - 2016-02-02 17:20 +0100
Re: [PATCH 22/31] x86, pkeys: dump pkey from VMA in /proc/pid/smaps Dave Hansen <dave@sr71.net> - 2016-02-02 20:10 +0100
[PATCH 06/31] x86, pkeys: add PKRU xsave fields and data structure(s) Dave Hansen <dave@sr71.net> - 2016-01-29 19:30 +0100
Re: [PATCH 01/31] mm, gup: introduce concept of "foreign" get_user_pages() Ingo Molnar <mingo@kernel.org> - 2016-02-09 13:50 +0100
Re: [PATCH 01/31] mm, gup: introduce concept of "foreign" get_user_pages() Ingo Molnar <mingo@kernel.org> - 2016-02-09 14:10 +0100
Re: [PATCH 01/31] mm, gup: introduce concept of "foreign" get_user_pages() Dave Hansen <dave@sr71.net> - 2016-02-09 16:20 +0100
Page 2 of 2 — ← Prev page 1 [2]
| From | Dave Hansen <dave@sr71.net> |
|---|---|
| Date | 2016-01-29 19:30 +0100 |
| Subject | [PATCH 07/31] x86, pkeys: PTE bits for storing protection key |
| Message-ID | <qWlXZ-79P-55@gated-at.bofh.it> |
| In reply to | #1321954 |
From: Dave Hansen <dave.hansen@linux.intel.com> Previous documentation has referred to these 4 bits as "ignored". That means that software could have made use of them. But, as far as I know, the kernel never used them. They are still ignored when protection keys is not enabled, so they could theoretically still get used for software purposes. We also implement "empty" versions so that code that references to them can be optimized away by the compiler when the config option is not enabled. Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Reviewed-by: Thomas Gleixner <tglx@linutronix.de> --- b/arch/x86/include/asm/pgtable_types.h | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff -puN arch/x86/include/asm/pgtable_types.h~pkeys-04-ptebits arch/x86/include/asm/pgtable_types.h --- a/arch/x86/include/asm/pgtable_types.h~pkeys-04-ptebits 2016-01-28 15:52:19.366358352 -0800 +++ b/arch/x86/include/asm/pgtable_types.h 2016-01-28 15:52:19.369358489 -0800 @@ -20,13 +20,18 @@ #define _PAGE_BIT_SOFTW2 10 /* " */ #define _PAGE_BIT_SOFTW3 11 /* " */ #define _PAGE_BIT_PAT_LARGE 12 /* On 2MB or 1GB pages */ +#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 */ + #define _PAGE_BIT_SPECIAL _PAGE_BIT_SOFTW1 #define _PAGE_BIT_CPA_TEST _PAGE_BIT_SOFTW1 #define _PAGE_BIT_HIDDEN _PAGE_BIT_SOFTW3 /* hidden by kmemcheck */ #define _PAGE_BIT_SOFT_DIRTY _PAGE_BIT_SOFTW3 /* software dirty tracking */ -#define _PAGE_BIT_SOFTW4 58 /* available for programmer */ -#define _PAGE_BIT_DEVMAP _PAGE_BIT_SOFTW4 -#define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */ +#define _PAGE_BIT_DEVMAP _PAGE_BIT_SOFTW4 /* If _PAGE_BIT_PRESENT is clear, we use these: */ /* - if the user mapped it with PROT_NONE; pte_present gives true */ @@ -47,6 +52,17 @@ #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) +#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 #define __HAVE_ARCH_PTE_SPECIAL #ifdef CONFIG_KMEMCHECK _
[toc] | [prev] | [next] | [standalone]
| From | Dave Hansen <dave@sr71.net> |
|---|---|
| Date | 2016-01-29 19:30 +0100 |
| Subject | [PATCH 02/31] x86, fpu: add placeholder for Processor Trace XSAVE state |
| Message-ID | <qWlY0-79P-59@gated-at.bofh.it> |
| In reply to | #1321954 |
From: Dave Hansen <dave.hansen@linux.intel.com>
There is an XSAVE state component for Intel Processor Trace (PT).
But, we do not currently use it.
We add a placeholder in the code for it so it is not a mystery and
also so we do not need an explicit enum initialization for Protection
Keys in a moment.
Why don't we use it?
We might end up using this at _some_ point in the future. But,
this is a "system" state which requires using the currently
unsupported XSAVES feature. Unlike all the other XSAVE states,
PT state is also not directly tied to a thread. You might
context-switch between threads, but not want to change any of the
PT state. Or, you might switch between threads, and *do* want to
change PT state, all depending on what is being traced.
We currently just manually set some MSRs to do this PT context
switching, and it is unclear whether replacing our direct MSR use
with XSAVE will be a net win or loss, both in code complexity and
performance.
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: yu-cheng.yu@intel.com
Cc: fenghua.yu@intel.com
---
b/arch/x86/include/asm/fpu/types.h | 1 +
b/arch/x86/kernel/fpu/xstate.c | 10 ++++++++--
2 files changed, 9 insertions(+), 2 deletions(-)
diff -puN arch/x86/include/asm/fpu/types.h~pt-xstate-bit arch/x86/include/asm/fpu/types.h
--- a/arch/x86/include/asm/fpu/types.h~pt-xstate-bit 2016-01-28 15:52:17.216259779 -0800
+++ b/arch/x86/include/asm/fpu/types.h 2016-01-28 15:52:17.220259963 -0800
@@ -108,6 +108,7 @@ enum xfeature {
XFEATURE_OPMASK,
XFEATURE_ZMM_Hi256,
XFEATURE_Hi16_ZMM,
+ XFEATURE_PT_UNIMPLEMENTED_SO_FAR,
XFEATURE_MAX,
};
diff -puN arch/x86/kernel/fpu/xstate.c~pt-xstate-bit arch/x86/kernel/fpu/xstate.c
--- a/arch/x86/kernel/fpu/xstate.c~pt-xstate-bit 2016-01-28 15:52:17.217259825 -0800
+++ b/arch/x86/kernel/fpu/xstate.c 2016-01-28 15:52:17.221260009 -0800
@@ -13,6 +13,11 @@
#include <asm/tlbflush.h>
+/*
+ * Although we spell it out in here, the Processor Trace
+ * xfeature is completely unused. We use other mechanisms
+ * to save/restore PT state in Linux.
+ */
static const char *xfeature_names[] =
{
"x87 floating point registers" ,
@@ -23,7 +28,7 @@ static const char *xfeature_names[] =
"AVX-512 opmask" ,
"AVX-512 Hi256" ,
"AVX-512 ZMM_Hi256" ,
- "unknown xstate feature" ,
+ "Processor Trace (unused)" ,
};
/*
@@ -470,7 +475,8 @@ static void check_xstate_against_struct(
* numbers.
*/
if ((nr < XFEATURE_YMM) ||
- (nr >= XFEATURE_MAX)) {
+ (nr >= XFEATURE_MAX) ||
+ (nr == XFEATURE_PT_UNIMPLEMENTED_SO_FAR)) {
WARN_ONCE(1, "no structure for xstate: %d\n", nr);
XSTATE_WARN_ON(1);
}
_
[toc] | [prev] | [next] | [standalone]
| From | Dave Hansen <dave@sr71.net> |
|---|---|
| Date | 2016-01-29 19:30 +0100 |
| Subject | [PATCH 16/31] x86, mm: simplify get_user_pages() PTE bit handling |
| Message-ID | <qWlY0-79P-61@gated-at.bofh.it> |
| In reply to | #1321954 |
From: Dave Hansen <dave.hansen@linux.intel.com>
The current get_user_pages() code is a wee bit more complicated
than it needs to be for pte bit checking. Currently, it establishes
a mask of required pte _PAGE_* bits and ensures that the pte it
goes after has all those bits.
This consolidates the three identical copies of this code.
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
---
b/arch/x86/mm/gup.c | 38 ++++++++++++++++++++++----------------
1 file changed, 22 insertions(+), 16 deletions(-)
diff -puN arch/x86/mm/gup.c~pkeys-12-gup-swizzle arch/x86/mm/gup.c
--- a/arch/x86/mm/gup.c~pkeys-12-gup-swizzle 2016-01-28 15:52:23.267537203 -0800
+++ b/arch/x86/mm/gup.c 2016-01-28 15:52:23.270537340 -0800
@@ -75,6 +75,24 @@ static void undo_dev_pagemap(int *nr, in
}
/*
+ * 'pteval' can come from a pte, pmd or pud. We only check
+ * _PAGE_PRESENT, _PAGE_USER, and _PAGE_RW in here which are the
+ * same value on all 3 types.
+ */
+static inline int pte_allows_gup(unsigned long pteval, int write)
+{
+ unsigned long need_pte_bits = _PAGE_PRESENT|_PAGE_USER;
+
+ if (write)
+ need_pte_bits |= _PAGE_RW;
+
+ if ((pteval & need_pte_bits) != need_pte_bits)
+ return 0;
+
+ return 1;
+}
+
+/*
* The performance critical leaf functions are made noinline otherwise gcc
* inlines everything into a single function which results in too much
* register pressure.
@@ -83,14 +101,9 @@ static noinline int gup_pte_range(pmd_t
unsigned long end, int write, struct page **pages, int *nr)
{
struct dev_pagemap *pgmap = NULL;
- unsigned long mask;
int nr_start = *nr;
pte_t *ptep;
- mask = _PAGE_PRESENT|_PAGE_USER;
- if (write)
- mask |= _PAGE_RW;
-
ptep = pte_offset_map(&pmd, addr);
do {
pte_t pte = gup_get_pte(ptep);
@@ -110,7 +123,8 @@ static noinline int gup_pte_range(pmd_t
pte_unmap(ptep);
return 0;
}
- } else if ((pte_flags(pte) & (mask | _PAGE_SPECIAL)) != mask) {
+ } else if (!pte_allows_gup(pte_val(pte), write) ||
+ pte_special(pte)) {
pte_unmap(ptep);
return 0;
}
@@ -164,14 +178,10 @@ static int __gup_device_huge_pmd(pmd_t p
static noinline int gup_huge_pmd(pmd_t pmd, unsigned long addr,
unsigned long end, int write, struct page **pages, int *nr)
{
- unsigned long mask;
struct page *head, *page;
int refs;
- mask = _PAGE_PRESENT|_PAGE_USER;
- if (write)
- mask |= _PAGE_RW;
- if ((pmd_flags(pmd) & mask) != mask)
+ if (!pte_allows_gup(pmd_val(pmd), write))
return 0;
VM_BUG_ON(!pfn_valid(pmd_pfn(pmd)));
@@ -231,14 +241,10 @@ static int gup_pmd_range(pud_t pud, unsi
static noinline int gup_huge_pud(pud_t pud, unsigned long addr,
unsigned long end, int write, struct page **pages, int *nr)
{
- unsigned long mask;
struct page *head, *page;
int refs;
- mask = _PAGE_PRESENT|_PAGE_USER;
- if (write)
- mask |= _PAGE_RW;
- if ((pud_flags(pud) & mask) != mask)
+ if (!pte_allows_gup(pud_val(pud), write))
return 0;
/* hugepages are never "special" */
VM_BUG_ON(pud_flags(pud) & _PAGE_SPECIAL);
_
[toc] | [prev] | [next] | [standalone]
| From | Dave Hansen <dave@sr71.net> |
|---|---|
| Date | 2016-01-29 19:30 +0100 |
| Subject | [PATCH 11/31] x86, pkeys: pass VMA down in to fault signal generation code |
| Message-ID | <qWlY0-79P-63@gated-at.bofh.it> |
| In reply to | #1321954 |
From: Dave Hansen <dave.hansen@linux.intel.com>
During a page fault, we look up the VMA to ensure that the fault
is in a region with a valid mapping. But, in the top-level page
fault code we don't need the VMA for much else. Once we have
decided that an access is bad, we are going to send a signal no
matter what and do not need the VMA any more. So we do not pass
it down in to the signal generation code.
But, for protection keys, we need the VMA. It tells us *which*
protection key we violated if we get a PF_PK. So, we need to
pass the VMA down and fill in siginfo->si_pkey.
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
---
b/arch/x86/mm/fault.c | 50 ++++++++++++++++++++++++++++----------------------
1 file changed, 28 insertions(+), 22 deletions(-)
diff -puN arch/x86/mm/fault.c~pkeys-08-pass-down-vma arch/x86/mm/fault.c
--- a/arch/x86/mm/fault.c~pkeys-08-pass-down-vma 2016-01-28 15:52:21.132439318 -0800
+++ b/arch/x86/mm/fault.c 2016-01-28 15:52:21.136439502 -0800
@@ -171,7 +171,8 @@ is_prefetch(struct pt_regs *regs, unsign
static void
force_sig_info_fault(int si_signo, int si_code, unsigned long address,
- struct task_struct *tsk, int fault)
+ struct task_struct *tsk, struct vm_area_struct *vma,
+ int fault)
{
unsigned lsb = 0;
siginfo_t info;
@@ -656,6 +657,8 @@ no_context(struct pt_regs *regs, unsigne
struct task_struct *tsk = current;
unsigned long flags;
int sig;
+ /* No context means no VMA to pass down */
+ struct vm_area_struct *vma = NULL;
/* Are we prepared to handle this kernel fault? */
if (fixup_exception(regs)) {
@@ -679,7 +682,8 @@ no_context(struct pt_regs *regs, unsigne
tsk->thread.cr2 = address;
/* XXX: hwpoison faults will set the wrong code. */
- force_sig_info_fault(signal, si_code, address, tsk, 0);
+ force_sig_info_fault(signal, si_code, address,
+ tsk, vma, 0);
}
/*
@@ -756,7 +760,8 @@ show_signal_msg(struct pt_regs *regs, un
static void
__bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,
- unsigned long address, int si_code)
+ unsigned long address, struct vm_area_struct *vma,
+ int si_code)
{
struct task_struct *tsk = current;
@@ -799,7 +804,7 @@ __bad_area_nosemaphore(struct pt_regs *r
tsk->thread.error_code = error_code;
tsk->thread.trap_nr = X86_TRAP_PF;
- force_sig_info_fault(SIGSEGV, si_code, address, tsk, 0);
+ force_sig_info_fault(SIGSEGV, si_code, address, tsk, vma, 0);
return;
}
@@ -812,14 +817,14 @@ __bad_area_nosemaphore(struct pt_regs *r
static noinline void
bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,
- unsigned long address)
+ unsigned long address, struct vm_area_struct *vma)
{
- __bad_area_nosemaphore(regs, error_code, address, SEGV_MAPERR);
+ __bad_area_nosemaphore(regs, error_code, address, vma, SEGV_MAPERR);
}
static void
__bad_area(struct pt_regs *regs, unsigned long error_code,
- unsigned long address, int si_code)
+ unsigned long address, struct vm_area_struct *vma, int si_code)
{
struct mm_struct *mm = current->mm;
@@ -829,25 +834,25 @@ __bad_area(struct pt_regs *regs, unsigne
*/
up_read(&mm->mmap_sem);
- __bad_area_nosemaphore(regs, error_code, address, si_code);
+ __bad_area_nosemaphore(regs, error_code, address, vma, si_code);
}
static noinline void
bad_area(struct pt_regs *regs, unsigned long error_code, unsigned long address)
{
- __bad_area(regs, error_code, address, SEGV_MAPERR);
+ __bad_area(regs, error_code, address, NULL, SEGV_MAPERR);
}
static noinline void
bad_area_access_error(struct pt_regs *regs, unsigned long error_code,
- unsigned long address)
+ unsigned long address, struct vm_area_struct *vma)
{
- __bad_area(regs, error_code, address, SEGV_ACCERR);
+ __bad_area(regs, error_code, address, vma, SEGV_ACCERR);
}
static void
do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address,
- unsigned int fault)
+ struct vm_area_struct *vma, unsigned int fault)
{
struct task_struct *tsk = current;
int code = BUS_ADRERR;
@@ -874,12 +879,13 @@ do_sigbus(struct pt_regs *regs, unsigned
code = BUS_MCEERR_AR;
}
#endif
- force_sig_info_fault(SIGBUS, code, address, tsk, fault);
+ force_sig_info_fault(SIGBUS, code, address, tsk, vma, fault);
}
static noinline void
mm_fault_error(struct pt_regs *regs, unsigned long error_code,
- unsigned long address, unsigned int fault)
+ unsigned long address, struct vm_area_struct *vma,
+ unsigned int fault)
{
if (fatal_signal_pending(current) && !(error_code & PF_USER)) {
no_context(regs, error_code, address, 0, 0);
@@ -903,9 +909,9 @@ mm_fault_error(struct pt_regs *regs, uns
} else {
if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON|
VM_FAULT_HWPOISON_LARGE))
- do_sigbus(regs, error_code, address, fault);
+ do_sigbus(regs, error_code, address, vma, fault);
else if (fault & VM_FAULT_SIGSEGV)
- bad_area_nosemaphore(regs, error_code, address);
+ bad_area_nosemaphore(regs, error_code, address, vma);
else
BUG();
}
@@ -1119,7 +1125,7 @@ __do_page_fault(struct pt_regs *regs, un
* Don't take the mm semaphore here. If we fixup a prefetch
* fault we could otherwise deadlock:
*/
- bad_area_nosemaphore(regs, error_code, address);
+ bad_area_nosemaphore(regs, error_code, address, NULL);
return;
}
@@ -1132,7 +1138,7 @@ __do_page_fault(struct pt_regs *regs, un
pgtable_bad(regs, error_code, address);
if (unlikely(smap_violation(error_code, regs))) {
- bad_area_nosemaphore(regs, error_code, address);
+ bad_area_nosemaphore(regs, error_code, address, NULL);
return;
}
@@ -1141,7 +1147,7 @@ __do_page_fault(struct pt_regs *regs, un
* in a region with pagefaults disabled then we must not take the fault
*/
if (unlikely(faulthandler_disabled() || !mm)) {
- bad_area_nosemaphore(regs, error_code, address);
+ bad_area_nosemaphore(regs, error_code, address, NULL);
return;
}
@@ -1185,7 +1191,7 @@ __do_page_fault(struct pt_regs *regs, un
if (unlikely(!down_read_trylock(&mm->mmap_sem))) {
if ((error_code & PF_USER) == 0 &&
!search_exception_tables(regs->ip)) {
- bad_area_nosemaphore(regs, error_code, address);
+ bad_area_nosemaphore(regs, error_code, address, NULL);
return;
}
retry:
@@ -1233,7 +1239,7 @@ retry:
*/
good_area:
if (unlikely(access_error(error_code, vma))) {
- bad_area_access_error(regs, error_code, address);
+ bad_area_access_error(regs, error_code, address, vma);
return;
}
@@ -1271,7 +1277,7 @@ good_area:
up_read(&mm->mmap_sem);
if (unlikely(fault & VM_FAULT_ERROR)) {
- mm_fault_error(regs, error_code, address, fault);
+ mm_fault_error(regs, error_code, address, vma, fault);
return;
}
_
[toc] | [prev] | [next] | [standalone]
| From | Dave Hansen <dave@sr71.net> |
|---|---|
| Date | 2016-01-29 19:30 +0100 |
| Subject | [PATCH 22/31] x86, pkeys: dump pkey from VMA in /proc/pid/smaps |
| Message-ID | <qWlY0-79P-57@gated-at.bofh.it> |
| In reply to | #1321954 |
From: Dave Hansen <dave.hansen@linux.intel.com>
The protection key can now be just as important as read/write
permissions on a VMA. We need some debug mechanism to help
figure out if it is in play. smaps seems like a logical
place to expose it.
arch/x86/kernel/setup.c is a bit of a weirdo place to put
this code, but it already had seq_file.h and there was not
a much better existing place to put it.
We also use no #ifdef. If protection keys is .config'd out we
will effectively get the same function as if we used the weak
generic function.
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Cc: vbabka@suse.cz
---
b/arch/x86/kernel/setup.c | 9 +++++++++
b/fs/proc/task_mmu.c | 14 ++++++++++++++
2 files changed, 23 insertions(+)
diff -puN arch/x86/kernel/setup.c~pkeys-40-smaps arch/x86/kernel/setup.c
--- a/arch/x86/kernel/setup.c~pkeys-40-smaps 2016-01-28 15:52:26.386680200 -0800
+++ b/arch/x86/kernel/setup.c 2016-01-28 15:52:26.391680429 -0800
@@ -112,6 +112,7 @@
#include <asm/alternative.h>
#include <asm/prom.h>
#include <asm/microcode.h>
+#include <asm/mmu_context.h>
/*
* max_low_pfn_mapped: highest direct mapped pfn under 4GB
@@ -1282,3 +1283,11 @@ static int __init register_kernel_offset
return 0;
}
__initcall(register_kernel_offset_dumper);
+
+void arch_show_smap(struct seq_file *m, struct vm_area_struct *vma)
+{
+ if (!boot_cpu_has(X86_FEATURE_OSPKE))
+ return;
+
+ seq_printf(m, "ProtectionKey: %8u\n", vma_pkey(vma));
+}
diff -puN fs/proc/task_mmu.c~pkeys-40-smaps fs/proc/task_mmu.c
--- a/fs/proc/task_mmu.c~pkeys-40-smaps 2016-01-28 15:52:26.387680246 -0800
+++ b/fs/proc/task_mmu.c 2016-01-28 15:52:26.391680429 -0800
@@ -668,11 +668,20 @@ static void show_smap_vma_flags(struct s
[ilog2(VM_MERGEABLE)] = "mg",
[ilog2(VM_UFFD_MISSING)]= "um",
[ilog2(VM_UFFD_WP)] = "uw",
+#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
+ /* These come out via ProtectionKey: */
+ [ilog2(VM_PKEY_BIT0)] = "",
+ [ilog2(VM_PKEY_BIT1)] = "",
+ [ilog2(VM_PKEY_BIT2)] = "",
+ [ilog2(VM_PKEY_BIT3)] = "",
+#endif
};
size_t i;
seq_puts(m, "VmFlags: ");
for (i = 0; i < BITS_PER_LONG; i++) {
+ if (!mnemonics[i][0])
+ continue;
if (vma->vm_flags & (1UL << i)) {
seq_printf(m, "%c%c ",
mnemonics[i][0], mnemonics[i][1]);
@@ -710,6 +719,10 @@ static int smaps_hugetlb_range(pte_t *pt
}
#endif /* HUGETLB_PAGE */
+void __weak arch_show_smap(struct seq_file *m, struct vm_area_struct *vma)
+{
+}
+
static int show_smap(struct seq_file *m, void *v, int is_pid)
{
struct vm_area_struct *vma = v;
@@ -791,6 +804,7 @@ static int show_smap(struct seq_file *m,
(vma->vm_flags & VM_LOCKED) ?
(unsigned long)(mss.pss >> (10 + PSS_SHIFT)) : 0);
+ arch_show_smap(m, vma);
show_smap_vma_flags(m, vma);
m_cache_vma(m, vma);
return 0;
_
[toc] | [prev] | [next] | [standalone]
| From | Vlastimil Babka <vbabka@suse.cz> |
|---|---|
| Date | 2016-02-02 17:20 +0100 |
| Subject | Re: [PATCH 22/31] x86, pkeys: dump pkey from VMA in /proc/pid/smaps |
| Message-ID | <qXLQl-5Be-9@gated-at.bofh.it> |
| In reply to | #1321985 |
On 01/29/2016 07:17 PM, Dave Hansen wrote:
> From: Dave Hansen <dave.hansen@linux.intel.com>
>
> The protection key can now be just as important as read/write
> permissions on a VMA. We need some debug mechanism to help
> figure out if it is in play. smaps seems like a logical
> place to expose it.
>
> arch/x86/kernel/setup.c is a bit of a weirdo place to put
> this code, but it already had seq_file.h and there was not
> a much better existing place to put it.
>
> We also use no #ifdef. If protection keys is .config'd out we
> will effectively get the same function as if we used the weak
> generic function.
>
> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
> Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
> Cc: vbabka@suse.cz
> ---
>
> b/arch/x86/kernel/setup.c | 9 +++++++++
> b/fs/proc/task_mmu.c | 14 ++++++++++++++
> 2 files changed, 23 insertions(+)
>
> diff -puN arch/x86/kernel/setup.c~pkeys-40-smaps arch/x86/kernel/setup.c
> --- a/arch/x86/kernel/setup.c~pkeys-40-smaps 2016-01-28 15:52:26.386680200 -0800
> +++ b/arch/x86/kernel/setup.c 2016-01-28 15:52:26.391680429 -0800
> @@ -112,6 +112,7 @@
> #include <asm/alternative.h>
> #include <asm/prom.h>
> #include <asm/microcode.h>
> +#include <asm/mmu_context.h>
>
> /*
> * max_low_pfn_mapped: highest direct mapped pfn under 4GB
> @@ -1282,3 +1283,11 @@ static int __init register_kernel_offset
> return 0;
> }
> __initcall(register_kernel_offset_dumper);
> +
> +void arch_show_smap(struct seq_file *m, struct vm_area_struct *vma)
> +{
> + if (!boot_cpu_has(X86_FEATURE_OSPKE))
> + return;
> +
> + seq_printf(m, "ProtectionKey: %8u\n", vma_pkey(vma));
> +}
> diff -puN fs/proc/task_mmu.c~pkeys-40-smaps fs/proc/task_mmu.c
> --- a/fs/proc/task_mmu.c~pkeys-40-smaps 2016-01-28 15:52:26.387680246 -0800
> +++ b/fs/proc/task_mmu.c 2016-01-28 15:52:26.391680429 -0800
> @@ -668,11 +668,20 @@ static void show_smap_vma_flags(struct s
> [ilog2(VM_MERGEABLE)] = "mg",
> [ilog2(VM_UFFD_MISSING)]= "um",
> [ilog2(VM_UFFD_WP)] = "uw",
> +#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
> + /* These come out via ProtectionKey: */
> + [ilog2(VM_PKEY_BIT0)] = "",
> + [ilog2(VM_PKEY_BIT1)] = "",
> + [ilog2(VM_PKEY_BIT2)] = "",
> + [ilog2(VM_PKEY_BIT3)] = "",
> +#endif
> };
> size_t i;
>
> seq_puts(m, "VmFlags: ");
> for (i = 0; i < BITS_PER_LONG; i++) {
> + if (!mnemonics[i][0])
> + continue;
> if (vma->vm_flags & (1UL << i)) {
> seq_printf(m, "%c%c ",
> mnemonics[i][0], mnemonics[i][1]);
> @@ -710,6 +719,10 @@ static int smaps_hugetlb_range(pte_t *pt
> }
> #endif /* HUGETLB_PAGE */
>
> +void __weak arch_show_smap(struct seq_file *m, struct vm_area_struct *vma)
> +{
> +}
Is it valid that this serves also as a declaration? Or should it be also
in some header?
> +
> static int show_smap(struct seq_file *m, void *v, int is_pid)
> {
> struct vm_area_struct *vma = v;
> @@ -791,6 +804,7 @@ static int show_smap(struct seq_file *m,
> (vma->vm_flags & VM_LOCKED) ?
> (unsigned long)(mss.pss >> (10 + PSS_SHIFT)) : 0);
>
> + arch_show_smap(m, vma);
> show_smap_vma_flags(m, vma);
> m_cache_vma(m, vma);
> return 0;
> _
>
[toc] | [prev] | [next] | [standalone]
| From | Dave Hansen <dave@sr71.net> |
|---|---|
| Date | 2016-02-02 20:10 +0100 |
| Subject | Re: [PATCH 22/31] x86, pkeys: dump pkey from VMA in /proc/pid/smaps |
| Message-ID | <qXOuS-7C0-21@gated-at.bofh.it> |
| In reply to | #1324237 |
On 02/02/2016 08:11 AM, Vlastimil Babka wrote:
>> +void __weak arch_show_smap(struct seq_file *m, struct vm_area_struct
>> *vma)
>> +{
>> +}
>
> Is it valid that this serves also as a declaration? Or should it be also
> in some header?
I guess having it in a header would make it less likely that someone
screws up a definition farther down the line. But, it also seemed a wee
bit of overkill for a single user.
I'm happy to send a follow-on patch to add it to a header somewhere.
[toc] | [prev] | [next] | [standalone]
| From | Dave Hansen <dave@sr71.net> |
|---|---|
| Date | 2016-01-29 19:30 +0100 |
| Subject | [PATCH 06/31] x86, pkeys: add PKRU xsave fields and data structure(s) |
| Message-ID | <qWlY0-79P-67@gated-at.bofh.it> |
| In reply to | #1321954 |
From: Dave Hansen <dave.hansen@linux.intel.com>
The protection keys register (PKRU) is saved and restored using
xsave. Define the data structure that we will use to access it
inside the xsave buffer.
Note that we also have to widen the printk of the xsave feature
masks since this is feature 0x200 and we only did two characters
before.
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
---
b/arch/x86/include/asm/fpu/types.h | 11 +++++++++++
b/arch/x86/include/asm/fpu/xstate.h | 4 +++-
b/arch/x86/kernel/fpu/xstate.c | 7 ++++++-
3 files changed, 20 insertions(+), 2 deletions(-)
diff -puN arch/x86/include/asm/fpu/types.h~pkeys-03-xsave arch/x86/include/asm/fpu/types.h
--- a/arch/x86/include/asm/fpu/types.h~pkeys-03-xsave 2016-01-28 15:52:18.904337170 -0800
+++ b/arch/x86/include/asm/fpu/types.h 2016-01-28 15:52:18.910337445 -0800
@@ -109,6 +109,7 @@ enum xfeature {
XFEATURE_ZMM_Hi256,
XFEATURE_Hi16_ZMM,
XFEATURE_PT_UNIMPLEMENTED_SO_FAR,
+ XFEATURE_PKRU,
XFEATURE_MAX,
};
@@ -121,6 +122,7 @@ enum xfeature {
#define XFEATURE_MASK_OPMASK (1 << XFEATURE_OPMASK)
#define XFEATURE_MASK_ZMM_Hi256 (1 << XFEATURE_ZMM_Hi256)
#define XFEATURE_MASK_Hi16_ZMM (1 << XFEATURE_Hi16_ZMM)
+#define XFEATURE_MASK_PKRU (1 << XFEATURE_PKRU)
#define XFEATURE_MASK_FPSSE (XFEATURE_MASK_FP | XFEATURE_MASK_SSE)
#define XFEATURE_MASK_AVX512 (XFEATURE_MASK_OPMASK \
@@ -213,6 +215,15 @@ struct avx_512_hi16_state {
struct reg_512_bit hi16_zmm[16];
} __packed;
+/*
+ * State component 9: 32-bit PKRU register. The state is
+ * 8 bytes long but only 4 bytes is used currently.
+ */
+struct pkru_state {
+ u32 pkru;
+ u32 pad;
+} __packed;
+
struct xstate_header {
u64 xfeatures;
u64 xcomp_bv;
diff -puN arch/x86/include/asm/fpu/xstate.h~pkeys-03-xsave arch/x86/include/asm/fpu/xstate.h
--- a/arch/x86/include/asm/fpu/xstate.h~pkeys-03-xsave 2016-01-28 15:52:18.905337216 -0800
+++ b/arch/x86/include/asm/fpu/xstate.h 2016-01-28 15:52:18.911337491 -0800
@@ -27,7 +27,9 @@
XFEATURE_MASK_Hi16_ZMM)
/* Supported features which require eager state saving */
-#define XFEATURE_MASK_EAGER (XFEATURE_MASK_BNDREGS | XFEATURE_MASK_BNDCSR)
+#define XFEATURE_MASK_EAGER (XFEATURE_MASK_BNDREGS | \
+ XFEATURE_MASK_BNDCSR | \
+ XFEATURE_MASK_PKRU)
/* All currently supported features */
#define XCNTXT_MASK (XFEATURE_MASK_LAZY | XFEATURE_MASK_EAGER)
diff -puN arch/x86/kernel/fpu/xstate.c~pkeys-03-xsave arch/x86/kernel/fpu/xstate.c
--- a/arch/x86/kernel/fpu/xstate.c~pkeys-03-xsave 2016-01-28 15:52:18.907337308 -0800
+++ b/arch/x86/kernel/fpu/xstate.c 2016-01-28 15:52:18.911337491 -0800
@@ -29,6 +29,8 @@ static const char *xfeature_names[] =
"AVX-512 Hi256" ,
"AVX-512 ZMM_Hi256" ,
"Processor Trace (unused)" ,
+ "Protection Keys User registers",
+ "unknown xstate feature" ,
};
/*
@@ -58,6 +60,7 @@ void fpu__xstate_clear_all_cpu_caps(void
setup_clear_cpu_cap(X86_FEATURE_AVX512CD);
setup_clear_cpu_cap(X86_FEATURE_MPX);
setup_clear_cpu_cap(X86_FEATURE_XGETBV1);
+ setup_clear_cpu_cap(X86_FEATURE_PKU);
}
/*
@@ -236,7 +239,7 @@ static void __init print_xstate_feature(
const char *feature_name;
if (cpu_has_xfeatures(xstate_mask, &feature_name))
- pr_info("x86/fpu: Supporting XSAVE feature 0x%02Lx: '%s'\n", xstate_mask, feature_name);
+ pr_info("x86/fpu: Supporting XSAVE feature 0x%03Lx: '%s'\n", xstate_mask, feature_name);
}
/*
@@ -252,6 +255,7 @@ static void __init print_xstate_features
print_xstate_feature(XFEATURE_MASK_OPMASK);
print_xstate_feature(XFEATURE_MASK_ZMM_Hi256);
print_xstate_feature(XFEATURE_MASK_Hi16_ZMM);
+ print_xstate_feature(XFEATURE_MASK_PKRU);
}
/*
@@ -468,6 +472,7 @@ static void check_xstate_against_struct(
XCHECK_SZ(sz, nr, XFEATURE_OPMASK, struct avx_512_opmask_state);
XCHECK_SZ(sz, nr, XFEATURE_ZMM_Hi256, struct avx_512_zmm_uppers_state);
XCHECK_SZ(sz, nr, XFEATURE_Hi16_ZMM, struct avx_512_hi16_state);
+ XCHECK_SZ(sz, nr, XFEATURE_PKRU, struct pkru_state);
/*
* Make *SURE* to add any feature numbers in below if
_
[toc] | [prev] | [next] | [standalone]
| From | Ingo Molnar <mingo@kernel.org> |
|---|---|
| Date | 2016-02-09 13:50 +0100 |
| Subject | Re: [PATCH 01/31] mm, gup: introduce concept of "foreign" get_user_pages() |
| Message-ID | <r0fTY-44E-15@gated-at.bofh.it> |
| In reply to | #1321954 |
* Dave Hansen <dave@sr71.net> wrote: > > OK, so I've fixed up my build process to _actually_ build the > nommu code. > > One of Vlastimil's comments made me go dig back in to the uprobes > code's use of get_user_pages(). I decided to change both of them > to be "foreign" accesses. > > This also fixes the nommu breakage that Vlastimil noted last time. > > Srikar, I'd appreciate if you can have a look at the uprobes.c > modifications, especially the comment. I don't think this will > change any behavior, but I want to make sure the comment is > accurate. > > --- > > From: Dave Hansen <dave.hansen@linux.intel.com> > > For protection keys, we need to understand whether protections > should be enforced in software or not. In general, we enforce > protections when working on our own task, but not when on others. > We call these "current" and "foreign" operations. > > This patch introduces a new get_user_pages() variant: > > get_user_pages_foreign() > > We modify the vanilla get_user_pages() so it can no longer be > used on mm/tasks other than 'current/current->mm', which is by > far the most common way it is called. Using it makes a few of > the call sites look a bit nicer. > > In other words, get_user_pages_foreign() is a replacement for > when get_user_pages() is called on non-current tsk/mm. > > This also switches get_user_pages_(un)locked() over to be like > get_user_pages() and not take a tsk/mm. There is no > get_user_pages_foreign_(un)locked(). If someone wants that > behavior they just have to use "__" variant and pass in > FOLL_FOREIGN explicitly. > > The uprobes is_trap_at_addr() location holds mmap_sem and > calls get_user_pages(current->mm) on an instruction address. This > makes it a pretty unique gup caller. Being an instruction access > and also really originating from the kernel (vs. the app), I opted > to consider this a 'foreign' access where protection keys will not > be enforced. > > Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> > Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com> > Acked-by: Vlastimil Babka <vbabka@suse.cz> > Cc: Andrew Morton <akpm@linux-foundation.org> > Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> > Cc: Andrea Arcangeli <aarcange@redhat.com> > Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> > Cc: jack@suse.cz > --- > > b/arch/cris/arch-v32/drivers/cryptocop.c | 8 --- > b/arch/ia64/kernel/err_inject.c | 3 - > b/arch/mips/mm/gup.c | 3 - > b/arch/s390/mm/gup.c | 4 - > b/arch/sh/mm/gup.c | 2 > b/arch/sparc/mm/gup.c | 2 > b/arch/x86/mm/gup.c | 2 > b/arch/x86/mm/mpx.c | 4 - > b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 3 - > b/drivers/gpu/drm/etnaviv/etnaviv_gem.c | 2 > b/drivers/gpu/drm/i915/i915_gem_userptr.c | 2 > b/drivers/gpu/drm/radeon/radeon_ttm.c | 3 - > b/drivers/gpu/drm/via/via_dmablit.c | 3 - > b/drivers/infiniband/core/umem.c | 2 > b/drivers/infiniband/core/umem_odp.c | 8 +-- > b/drivers/infiniband/hw/mthca/mthca_memfree.c | 3 - > b/drivers/infiniband/hw/qib/qib_user_pages.c | 3 - > b/drivers/infiniband/hw/usnic/usnic_uiom.c | 2 > b/drivers/media/pci/ivtv/ivtv-udma.c | 4 - > b/drivers/media/pci/ivtv/ivtv-yuv.c | 10 +--- > b/drivers/media/v4l2-core/videobuf-dma-sg.c | 3 - > b/drivers/misc/mic/scif/scif_rma.c | 2 > b/drivers/misc/sgi-gru/grufault.c | 3 - > b/drivers/scsi/st.c | 2 > b/drivers/staging/rdma/ipath/ipath_user_pages.c | 3 - > b/drivers/video/fbdev/pvr2fb.c | 4 - > b/drivers/virt/fsl_hypervisor.c | 5 -- > b/fs/exec.c | 8 ++- > b/include/linux/mm.h | 21 +++++---- > b/kernel/events/uprobes.c | 10 +++- > b/mm/frame_vector.c | 2 > b/mm/gup.c | 52 +++++++++++++++--------- > b/mm/ksm.c | 2 > b/mm/memory.c | 2 > b/mm/mempolicy.c | 6 +- > b/mm/nommu.c | 30 ++++++++----- > b/mm/process_vm_access.c | 11 +++-- > b/mm/util.c | 4 - > b/net/ceph/pagevec.c | 2 > b/security/tomoyo/domain.c | 9 +++- > b/virt/kvm/async_pf.c | 7 ++- > b/virt/kvm/kvm_main.c | 10 ++-- > 42 files changed, 148 insertions(+), 123 deletions(-) So this patch conflicts with recent upstream changes: patching file drivers/scsi/st.c can't find file to patch at input line 463 mind respinning it against v4.5-rc3 or so? Also, please split this into three patches: - one patch adds the _foreign() GUP variant and applies it to code that uses it on remote tasks. - introduce the new get_user_pages() but also add macros so that both 8-parameter and 7-parameter variants work without breaking the build. We can remove the compatibility wrapping on v4.6 or so. - the third will be a large but trivial patch, which will change 8-parameter GUP usage to 7-parameter usage. ... this should reduce the pain from the GUP interface change churn. Agreed? Thanks, Ingo
[toc] | [prev] | [next] | [standalone]
| From | Ingo Molnar <mingo@kernel.org> |
|---|---|
| Date | 2016-02-09 14:10 +0100 |
| Subject | Re: [PATCH 01/31] mm, gup: introduce concept of "foreign" get_user_pages() |
| Message-ID | <r0gdk-4tO-9@gated-at.bofh.it> |
| In reply to | #1330207 |
* Ingo Molnar <mingo@kernel.org> wrote: > Also, please split this into three patches: > > - one patch adds the _foreign() GUP variant and applies it to code that uses it > on remote tasks. This reminds me: please also rename the new API to get_user_pages_remote(), as remote/local is the phrase we typically use in MM code. Thanks, Ingo
[toc] | [prev] | [next] | [standalone]
| From | Dave Hansen <dave@sr71.net> |
|---|---|
| Date | 2016-02-09 16:20 +0100 |
| Subject | Re: [PATCH 01/31] mm, gup: introduce concept of "foreign" get_user_pages() |
| Message-ID | <r0if9-5Nd-53@gated-at.bofh.it> |
| In reply to | #1330207 |
On 02/09/2016 04:46 AM, Ingo Molnar wrote: > - introduce the new get_user_pages() but also add macros so that both 8-parameter > and 7-parameter variants work without breaking the build. We can remove the > compatibility wrapping on v4.6 or so. Do you want this done with some __VA_ARGS__ macro trickery, or did you have something else in mind?
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | linux.kernel
csiph-web