diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h index 4541ac44b35f0e39b831b3eba2e5669d29dd9f89..24bc41622a983cf353c6d414d521cbd94cd43cbb 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, mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | _ASCE_USER_BITS | _ASCE_TYPE_REGION3; break; + case -PAGE_SIZE: + /* forked 5-level task, set new asce with new_mm->pgd */ + mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | + _ASCE_USER_BITS | _ASCE_TYPE_REGION1; + break; case 1UL << 53: /* forked 4-level task, set new asce with new mm->pgd */ mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c index 2e10d2b8ad359607981ce381e27c3bf22e2e184d..5bea139517a2edc21dc50074d2c2e9a94dabb19e 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, return addr; check_asce_limit: - if (addr + len > current->mm->context.asce_limit) { + if (addr + len > current->mm->context.asce_limit && + addr + len <= TASK_SIZE) { rc = crst_table_upgrade(mm, addr + len); if (rc) return (unsigned long) rc; @@ -183,7 +184,8 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, } check_asce_limit: - if (addr + len > current->mm->context.asce_limit) { + if (addr + len > current->mm->context.asce_limit && + addr + len <= TASK_SIZE) { rc = crst_table_upgrade(mm, addr + len); if (rc) return (unsigned long) rc; diff --git a/drivers/s390/cio/vfio_ccw_cp.c b/drivers/s390/cio/vfio_ccw_cp.c index ba6ac83a6c2500c874f6a64518e72398bf5d52cb..5ccfdc80d0ec942d2e4dde4113830ab9eb2ba735 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, ccw_tail = ccw_head + (iter->ch_len - 1) * sizeof(struct ccw1); if ((ccw_head <= ccw->cda) && (ccw->cda <= ccw_tail)) { - ccw->cda = (__u32) (addr_t) (iter->ch_ccw + + ccw->cda = (__u32) (addr_t) (((char *)iter->ch_ccw) + (ccw->cda - ccw_head)); return 0; }