Skip to content

Commit 2da33f9

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 fixes from Martin Schwidefsky: "Three bug fixes: - The fix for the page table corruption (CVE-2016-2143) - The diagnose statistics introduced a regression for the dasd diag driver - Boot crash on systems without the set-program-parameters facility" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: s390/mm: four page table levels vs. fork s390/cpumf: Fix lpp detection s390/dasd: fix diag 0x250 inline assembly
2 parents 8e0f93c + 3446c13 commit 2da33f9

File tree

4 files changed

+38
-13
lines changed

4 files changed

+38
-13
lines changed

arch/s390/include/asm/mmu_context.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,25 @@
1515
static inline int init_new_context(struct task_struct *tsk,
1616
struct mm_struct *mm)
1717
{
18+
spin_lock_init(&mm->context.list_lock);
19+
INIT_LIST_HEAD(&mm->context.pgtable_list);
20+
INIT_LIST_HEAD(&mm->context.gmap_list);
1821
cpumask_clear(&mm->context.cpu_attach_mask);
1922
atomic_set(&mm->context.attach_count, 0);
2023
mm->context.flush_mm = 0;
21-
mm->context.asce_bits = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS;
22-
mm->context.asce_bits |= _ASCE_TYPE_REGION3;
2324
#ifdef CONFIG_PGSTE
2425
mm->context.alloc_pgste = page_table_allocate_pgste;
2526
mm->context.has_pgste = 0;
2627
mm->context.use_skey = 0;
2728
#endif
28-
mm->context.asce_limit = STACK_TOP_MAX;
29+
if (mm->context.asce_limit == 0) {
30+
/* context created by exec, set asce limit to 4TB */
31+
mm->context.asce_bits = _ASCE_TABLE_LENGTH |
32+
_ASCE_USER_BITS | _ASCE_TYPE_REGION3;
33+
mm->context.asce_limit = STACK_TOP_MAX;
34+
} else if (mm->context.asce_limit == (1UL << 31)) {
35+
mm_inc_nr_pmds(mm);
36+
}
2937
crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm));
3038
return 0;
3139
}
@@ -111,8 +119,6 @@ static inline void activate_mm(struct mm_struct *prev,
111119
static inline void arch_dup_mmap(struct mm_struct *oldmm,
112120
struct mm_struct *mm)
113121
{
114-
if (oldmm->context.asce_limit < mm->context.asce_limit)
115-
crst_table_downgrade(mm, oldmm->context.asce_limit);
116122
}
117123

118124
static inline void arch_exit_mmap(struct mm_struct *mm)

arch/s390/include/asm/pgalloc.h

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,26 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
100100

101101
static inline pgd_t *pgd_alloc(struct mm_struct *mm)
102102
{
103-
spin_lock_init(&mm->context.list_lock);
104-
INIT_LIST_HEAD(&mm->context.pgtable_list);
105-
INIT_LIST_HEAD(&mm->context.gmap_list);
106-
return (pgd_t *) crst_table_alloc(mm);
103+
unsigned long *table = crst_table_alloc(mm);
104+
105+
if (!table)
106+
return NULL;
107+
if (mm->context.asce_limit == (1UL << 31)) {
108+
/* Forking a compat process with 2 page table levels */
109+
if (!pgtable_pmd_page_ctor(virt_to_page(table))) {
110+
crst_table_free(mm, table);
111+
return NULL;
112+
}
113+
}
114+
return (pgd_t *) table;
115+
}
116+
117+
static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
118+
{
119+
if (mm->context.asce_limit == (1UL << 31))
120+
pgtable_pmd_page_dtor(virt_to_page(pgd));
121+
crst_table_free(mm, (unsigned long *) pgd);
107122
}
108-
#define pgd_free(mm, pgd) crst_table_free(mm, (unsigned long *) pgd)
109123

110124
static inline void pmd_populate(struct mm_struct *mm,
111125
pmd_t *pmd, pgtable_t pte)

arch/s390/kernel/head64.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
__HEAD
1818
ENTRY(startup_continue)
19-
tm __LC_STFLE_FAC_LIST+6,0x80 # LPP available ?
19+
tm __LC_STFLE_FAC_LIST+5,0x80 # LPP available ?
2020
jz 0f
2121
xc __LC_LPP+1(7,0),__LC_LPP+1 # clear lpp and current_pid
2222
mvi __LC_LPP,0x80 # and set LPP_MAGIC

drivers/s390/block/dasd_diag.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ static const u8 DASD_DIAG_CMS1[] = { 0xc3, 0xd4, 0xe2, 0xf1 };/* EBCDIC CMS1 */
6767
* and function code cmd.
6868
* In case of an exception return 3. Otherwise return result of bitwise OR of
6969
* resulting condition code and DIAG return code. */
70-
static inline int dia250(void *iob, int cmd)
70+
static inline int __dia250(void *iob, int cmd)
7171
{
7272
register unsigned long reg2 asm ("2") = (unsigned long) iob;
7373
typedef union {
@@ -77,7 +77,6 @@ static inline int dia250(void *iob, int cmd)
7777
int rc;
7878

7979
rc = 3;
80-
diag_stat_inc(DIAG_STAT_X250);
8180
asm volatile(
8281
" diag 2,%2,0x250\n"
8382
"0: ipm %0\n"
@@ -91,6 +90,12 @@ static inline int dia250(void *iob, int cmd)
9190
return rc;
9291
}
9392

93+
static inline int dia250(void *iob, int cmd)
94+
{
95+
diag_stat_inc(DIAG_STAT_X250);
96+
return __dia250(iob, cmd);
97+
}
98+
9499
/* Initialize block I/O to DIAG device using the specified blocksize and
95100
* block offset. On success, return zero and set end_block to contain the
96101
* number of blocks on the device minus the specified offset. Return non-zero

0 commit comments

Comments
 (0)