diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-01 13:36:22 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-01 13:36:22 -0400 |
commit | bba2a5b8221850418846d62887d5de311df335f9 (patch) | |
tree | 129ade5d7f32fec65707a64a2d5ae19ca0167323 | |
parent | a1c516a60a702630347e27c7beb7f2f44ca7a8b5 (diff) | |
parent | 0fdd49ad1bb17457d119f8c3bc8ecdd0734eed9c (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 fixes from Martin Schwidefsky:
"Three more bug fixes for v4.13.
The two memory management related fixes are quite new, they fix kernel
crashes that can be triggered by user space.
The third commit fixes a bug in the vfio ccw translation code"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
s390/mm: fix BUG_ON in crst_table_upgrade
s390/mm: fork vs. 5 level page tabel
vfio: ccw: fix bad ptr math for TIC cda translation
-rw-r--r-- | arch/s390/include/asm/mmu_context.h | 5 | ||||
-rw-r--r-- | arch/s390/mm/mmap.c | 6 | ||||
-rw-r--r-- | drivers/s390/cio/vfio_ccw_cp.c | 2 |
3 files changed, 10 insertions, 3 deletions
diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h index 4541ac44b35f..24bc41622a98 100644 --- a/arch/s390/include/asm/mmu_context.h +++ b/arch/s390/include/asm/mmu_context.h | |||
@@ -44,6 +44,11 @@ static inline int init_new_context(struct task_struct *tsk, | |||
44 | mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | | 44 | mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | |
45 | _ASCE_USER_BITS | _ASCE_TYPE_REGION3; | 45 | _ASCE_USER_BITS | _ASCE_TYPE_REGION3; |
46 | break; | 46 | break; |
47 | case -PAGE_SIZE: | ||
48 | /* forked 5-level task, set new asce with new_mm->pgd */ | ||
49 | mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | | ||
50 | _ASCE_USER_BITS | _ASCE_TYPE_REGION1; | ||
51 | break; | ||
47 | case 1UL << 53: | 52 | case 1UL << 53: |
48 | /* forked 4-level task, set new asce with new mm->pgd */ | 53 | /* forked 4-level task, set new asce with new mm->pgd */ |
49 | mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | | 54 | mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | |
diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c index 2e10d2b8ad35..5bea139517a2 100644 --- a/arch/s390/mm/mmap.c +++ b/arch/s390/mm/mmap.c | |||
@@ -119,7 +119,8 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, | |||
119 | return addr; | 119 | return addr; |
120 | 120 | ||
121 | check_asce_limit: | 121 | check_asce_limit: |
122 | if (addr + len > current->mm->context.asce_limit) { | 122 | if (addr + len > current->mm->context.asce_limit && |
123 | addr + len <= TASK_SIZE) { | ||
123 | rc = crst_table_upgrade(mm, addr + len); | 124 | rc = crst_table_upgrade(mm, addr + len); |
124 | if (rc) | 125 | if (rc) |
125 | return (unsigned long) rc; | 126 | return (unsigned long) rc; |
@@ -183,7 +184,8 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, | |||
183 | } | 184 | } |
184 | 185 | ||
185 | check_asce_limit: | 186 | check_asce_limit: |
186 | if (addr + len > current->mm->context.asce_limit) { | 187 | if (addr + len > current->mm->context.asce_limit && |
188 | addr + len <= TASK_SIZE) { | ||
187 | rc = crst_table_upgrade(mm, addr + len); | 189 | rc = crst_table_upgrade(mm, addr + len); |
188 | if (rc) | 190 | if (rc) |
189 | return (unsigned long) rc; | 191 | return (unsigned long) rc; |
diff --git a/drivers/s390/cio/vfio_ccw_cp.c b/drivers/s390/cio/vfio_ccw_cp.c index ba6ac83a6c25..5ccfdc80d0ec 100644 --- a/drivers/s390/cio/vfio_ccw_cp.c +++ b/drivers/s390/cio/vfio_ccw_cp.c | |||
@@ -481,7 +481,7 @@ static int ccwchain_fetch_tic(struct ccwchain *chain, | |||
481 | ccw_tail = ccw_head + (iter->ch_len - 1) * sizeof(struct ccw1); | 481 | ccw_tail = ccw_head + (iter->ch_len - 1) * sizeof(struct ccw1); |
482 | 482 | ||
483 | if ((ccw_head <= ccw->cda) && (ccw->cda <= ccw_tail)) { | 483 | if ((ccw_head <= ccw->cda) && (ccw->cda <= ccw_tail)) { |
484 | ccw->cda = (__u32) (addr_t) (iter->ch_ccw + | 484 | ccw->cda = (__u32) (addr_t) (((char *)iter->ch_ccw) + |
485 | (ccw->cda - ccw_head)); | 485 | (ccw->cda - ccw_head)); |
486 | return 0; | 486 | return 0; |
487 | } | 487 | } |