diff options
| author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2015-04-15 07:23:26 -0400 |
|---|---|---|
| committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2015-04-23 10:55:49 -0400 |
| commit | 0b46e0a3ec0d7a04af6a091354f1b5e1b952d70a (patch) | |
| tree | 011ed5650974aad0df2e6a6c9952e1fc2f935dec /arch/s390/include | |
| parent | 7e01b5acd88b3f3108d8c4ce44e3205d67437202 (diff) | |
s390/kvm: remove delayed reallocation of page tables for KVM
Replacing a 2K page table with a 4K page table while a VMA is active
for the affected memory region is fundamentally broken. Rip out the
page table reallocation code and replace it with a simple system
control 'vm.allocate_pgste'. If the system control is set the page
tables for all processes are allocated as full 4K pages, even for
processes that do not need it.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/include')
| -rw-r--r-- | arch/s390/include/asm/mmu.h | 4 | ||||
| -rw-r--r-- | arch/s390/include/asm/mmu_context.h | 3 | ||||
| -rw-r--r-- | arch/s390/include/asm/pgalloc.h | 1 | ||||
| -rw-r--r-- | arch/s390/include/asm/pgtable.h | 9 |
4 files changed, 16 insertions, 1 deletions
diff --git a/arch/s390/include/asm/mmu.h b/arch/s390/include/asm/mmu.h index a5e656260a70..d29ad9545b41 100644 --- a/arch/s390/include/asm/mmu.h +++ b/arch/s390/include/asm/mmu.h | |||
| @@ -14,7 +14,9 @@ typedef struct { | |||
| 14 | unsigned long asce_bits; | 14 | unsigned long asce_bits; |
| 15 | unsigned long asce_limit; | 15 | unsigned long asce_limit; |
| 16 | unsigned long vdso_base; | 16 | unsigned long vdso_base; |
| 17 | /* The mmu context has extended page tables. */ | 17 | /* The mmu context allocates 4K page tables. */ |
| 18 | unsigned int alloc_pgste:1; | ||
| 19 | /* The mmu context uses extended page tables. */ | ||
| 18 | unsigned int has_pgste:1; | 20 | unsigned int has_pgste:1; |
| 19 | /* The mmu context uses storage keys. */ | 21 | /* The mmu context uses storage keys. */ |
| 20 | unsigned int use_skey:1; | 22 | unsigned int use_skey:1; |
diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h index d25d9ff10ba8..fb1b93ea3e3f 100644 --- a/arch/s390/include/asm/mmu_context.h +++ b/arch/s390/include/asm/mmu_context.h | |||
| @@ -20,8 +20,11 @@ static inline int init_new_context(struct task_struct *tsk, | |||
| 20 | mm->context.flush_mm = 0; | 20 | mm->context.flush_mm = 0; |
| 21 | mm->context.asce_bits = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS; | 21 | mm->context.asce_bits = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS; |
| 22 | mm->context.asce_bits |= _ASCE_TYPE_REGION3; | 22 | mm->context.asce_bits |= _ASCE_TYPE_REGION3; |
| 23 | #ifdef CONFIG_PGSTE | ||
| 24 | mm->context.alloc_pgste = page_table_allocate_pgste; | ||
| 23 | mm->context.has_pgste = 0; | 25 | mm->context.has_pgste = 0; |
| 24 | mm->context.use_skey = 0; | 26 | mm->context.use_skey = 0; |
| 27 | #endif | ||
| 25 | mm->context.asce_limit = STACK_TOP_MAX; | 28 | mm->context.asce_limit = STACK_TOP_MAX; |
| 26 | crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm)); | 29 | crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm)); |
| 27 | return 0; | 30 | return 0; |
diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h index 51e7fb634ebc..7b7858f158b4 100644 --- a/arch/s390/include/asm/pgalloc.h +++ b/arch/s390/include/asm/pgalloc.h | |||
| @@ -21,6 +21,7 @@ void crst_table_free(struct mm_struct *, unsigned long *); | |||
| 21 | unsigned long *page_table_alloc(struct mm_struct *); | 21 | unsigned long *page_table_alloc(struct mm_struct *); |
| 22 | void page_table_free(struct mm_struct *, unsigned long *); | 22 | void page_table_free(struct mm_struct *, unsigned long *); |
| 23 | void page_table_free_rcu(struct mmu_gather *, unsigned long *, unsigned long); | 23 | void page_table_free_rcu(struct mmu_gather *, unsigned long *, unsigned long); |
| 24 | extern int page_table_allocate_pgste; | ||
| 24 | 25 | ||
| 25 | int set_guest_storage_key(struct mm_struct *mm, unsigned long addr, | 26 | int set_guest_storage_key(struct mm_struct *mm, unsigned long addr, |
| 26 | unsigned long key, bool nq); | 27 | unsigned long key, bool nq); |
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 989cfae9e202..1fba63997d50 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h | |||
| @@ -423,6 +423,15 @@ static inline int mm_has_pgste(struct mm_struct *mm) | |||
| 423 | return 0; | 423 | return 0; |
| 424 | } | 424 | } |
| 425 | 425 | ||
| 426 | static inline int mm_alloc_pgste(struct mm_struct *mm) | ||
| 427 | { | ||
| 428 | #ifdef CONFIG_PGSTE | ||
| 429 | if (unlikely(mm->context.alloc_pgste)) | ||
| 430 | return 1; | ||
| 431 | #endif | ||
| 432 | return 0; | ||
| 433 | } | ||
| 434 | |||
| 426 | /* | 435 | /* |
| 427 | * In the case that a guest uses storage keys | 436 | * In the case that a guest uses storage keys |
| 428 | * faults should no longer be backed by zero pages | 437 | * faults should no longer be backed by zero pages |
