diff options
author | Carsten Otte <cotte@de.ibm.com> | 2008-03-25 13:47:10 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-04-27 05:00:40 -0400 |
commit | 402b08622d9ac6e32e25289573272e0f21bb58a7 (patch) | |
tree | 40d7386154cef85c9bfd2bd862db025933820776 /include | |
parent | 37817f2982d0f559f90cecc66e150dd9d2c2df05 (diff) |
s390: KVM preparation: provide hook to enable pgstes in user pagetable
The SIE instruction on s390 uses the 2nd half of the page table page to
virtualize the storage keys of a guest. This patch offers the s390_enable_sie
function, which reorganizes the page tables of a single-threaded process to
reserve space in the page table:
s390_enable_sie makes sure that the process is single threaded and then uses
dup_mm to create a new mm with reorganized page tables. The old mm is freed
and the process has now a page status extended field after every page table.
Code that wants to exploit pgstes should SELECT CONFIG_PGSTE.
This patch has a small common code hit, namely making dup_mm non-static.
Edit (Carsten): I've modified Martin's patch, following Jeremy Fitzhardinge's
review feedback. Now we do have the prototype for dup_mm in
include/linux/sched.h. Following Martin's suggestion, s390_enable_sie() does now
call task_lock() to prevent race against ptrace modification of mm_users.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Carsten Otte <cotte@de.ibm.com>
Acked-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'include')
-rw-r--r-- | include/asm-s390/mmu.h | 1 | ||||
-rw-r--r-- | include/asm-s390/mmu_context.h | 8 | ||||
-rw-r--r-- | include/asm-s390/pgtable.h | 1 | ||||
-rw-r--r-- | include/linux/sched.h | 2 |
4 files changed, 11 insertions, 1 deletions
diff --git a/include/asm-s390/mmu.h b/include/asm-s390/mmu.h index 1698e29c5b20..5dd5e7b3476f 100644 --- a/include/asm-s390/mmu.h +++ b/include/asm-s390/mmu.h | |||
@@ -7,6 +7,7 @@ typedef struct { | |||
7 | unsigned long asce_bits; | 7 | unsigned long asce_bits; |
8 | unsigned long asce_limit; | 8 | unsigned long asce_limit; |
9 | int noexec; | 9 | int noexec; |
10 | int pgstes; | ||
10 | } mm_context_t; | 11 | } mm_context_t; |
11 | 12 | ||
12 | #endif | 13 | #endif |
diff --git a/include/asm-s390/mmu_context.h b/include/asm-s390/mmu_context.h index b5a34c6f91a9..4c2fbf48c9c4 100644 --- a/include/asm-s390/mmu_context.h +++ b/include/asm-s390/mmu_context.h | |||
@@ -20,7 +20,13 @@ static inline int init_new_context(struct task_struct *tsk, | |||
20 | #ifdef CONFIG_64BIT | 20 | #ifdef CONFIG_64BIT |
21 | mm->context.asce_bits |= _ASCE_TYPE_REGION3; | 21 | mm->context.asce_bits |= _ASCE_TYPE_REGION3; |
22 | #endif | 22 | #endif |
23 | mm->context.noexec = s390_noexec; | 23 | if (current->mm->context.pgstes) { |
24 | mm->context.noexec = 0; | ||
25 | mm->context.pgstes = 1; | ||
26 | } else { | ||
27 | mm->context.noexec = s390_noexec; | ||
28 | mm->context.pgstes = 0; | ||
29 | } | ||
24 | mm->context.asce_limit = STACK_TOP_MAX; | 30 | mm->context.asce_limit = STACK_TOP_MAX; |
25 | crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm)); | 31 | crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm)); |
26 | return 0; | 32 | return 0; |
diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h index 65154dc9a9e5..8e9a629dc199 100644 --- a/include/asm-s390/pgtable.h +++ b/include/asm-s390/pgtable.h | |||
@@ -966,6 +966,7 @@ static inline pte_t mk_swap_pte(unsigned long type, unsigned long offset) | |||
966 | 966 | ||
967 | extern int add_shared_memory(unsigned long start, unsigned long size); | 967 | extern int add_shared_memory(unsigned long start, unsigned long size); |
968 | extern int remove_shared_memory(unsigned long start, unsigned long size); | 968 | extern int remove_shared_memory(unsigned long start, unsigned long size); |
969 | extern int s390_enable_sie(void); | ||
969 | 970 | ||
970 | /* | 971 | /* |
971 | * No page table caches to initialise | 972 | * No page table caches to initialise |
diff --git a/include/linux/sched.h b/include/linux/sched.h index d0bd97044abd..9a4f3e63e3bf 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -1798,6 +1798,8 @@ extern void mmput(struct mm_struct *); | |||
1798 | extern struct mm_struct *get_task_mm(struct task_struct *task); | 1798 | extern struct mm_struct *get_task_mm(struct task_struct *task); |
1799 | /* Remove the current tasks stale references to the old mm_struct */ | 1799 | /* Remove the current tasks stale references to the old mm_struct */ |
1800 | extern void mm_release(struct task_struct *, struct mm_struct *); | 1800 | extern void mm_release(struct task_struct *, struct mm_struct *); |
1801 | /* Allocate a new mm structure and copy contents from tsk->mm */ | ||
1802 | extern struct mm_struct *dup_mm(struct task_struct *tsk); | ||
1801 | 1803 | ||
1802 | extern int copy_thread(int, unsigned long, unsigned long, unsigned long, struct task_struct *, struct pt_regs *); | 1804 | extern int copy_thread(int, unsigned long, unsigned long, unsigned long, struct task_struct *, struct pt_regs *); |
1803 | extern void flush_thread(void); | 1805 | extern void flush_thread(void); |