diff options
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/include/asm/cio.h | 2 | ||||
-rw-r--r-- | arch/s390/include/asm/pgtable.h | 35 | ||||
-rw-r--r-- | arch/s390/kernel/sclp.S | 8 | ||||
-rw-r--r-- | arch/s390/lib/uaccess_pt.c | 2 | ||||
-rw-r--r-- | arch/s390/mm/gup.c | 2 |
5 files changed, 33 insertions, 16 deletions
diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h index 55bde603521..ad2b924167d 100644 --- a/arch/s390/include/asm/cio.h +++ b/arch/s390/include/asm/cio.h | |||
@@ -9,6 +9,8 @@ | |||
9 | 9 | ||
10 | #define LPM_ANYPATH 0xff | 10 | #define LPM_ANYPATH 0xff |
11 | #define __MAX_CSSID 0 | 11 | #define __MAX_CSSID 0 |
12 | #define __MAX_SUBCHANNEL 65535 | ||
13 | #define __MAX_SSID 3 | ||
12 | 14 | ||
13 | #include <asm/scsw.h> | 15 | #include <asm/scsw.h> |
14 | 16 | ||
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index dd647c919a6..2d3b7cb2600 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h | |||
@@ -506,12 +506,15 @@ static inline int pud_bad(pud_t pud) | |||
506 | 506 | ||
507 | static inline int pmd_present(pmd_t pmd) | 507 | static inline int pmd_present(pmd_t pmd) |
508 | { | 508 | { |
509 | return (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) != 0UL; | 509 | unsigned long mask = _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY_RO; |
510 | return (pmd_val(pmd) & mask) == _HPAGE_TYPE_NONE || | ||
511 | !(pmd_val(pmd) & _SEGMENT_ENTRY_INV); | ||
510 | } | 512 | } |
511 | 513 | ||
512 | static inline int pmd_none(pmd_t pmd) | 514 | static inline int pmd_none(pmd_t pmd) |
513 | { | 515 | { |
514 | return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) != 0UL; | 516 | return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) && |
517 | !(pmd_val(pmd) & _SEGMENT_ENTRY_RO); | ||
515 | } | 518 | } |
516 | 519 | ||
517 | static inline int pmd_large(pmd_t pmd) | 520 | static inline int pmd_large(pmd_t pmd) |
@@ -1223,6 +1226,11 @@ static inline void __pmd_idte(unsigned long address, pmd_t *pmdp) | |||
1223 | } | 1226 | } |
1224 | 1227 | ||
1225 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 1228 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
1229 | |||
1230 | #define SEGMENT_NONE __pgprot(_HPAGE_TYPE_NONE) | ||
1231 | #define SEGMENT_RO __pgprot(_HPAGE_TYPE_RO) | ||
1232 | #define SEGMENT_RW __pgprot(_HPAGE_TYPE_RW) | ||
1233 | |||
1226 | #define __HAVE_ARCH_PGTABLE_DEPOSIT | 1234 | #define __HAVE_ARCH_PGTABLE_DEPOSIT |
1227 | extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable); | 1235 | extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable); |
1228 | 1236 | ||
@@ -1242,16 +1250,15 @@ static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, | |||
1242 | 1250 | ||
1243 | static inline unsigned long massage_pgprot_pmd(pgprot_t pgprot) | 1251 | static inline unsigned long massage_pgprot_pmd(pgprot_t pgprot) |
1244 | { | 1252 | { |
1245 | unsigned long pgprot_pmd = 0; | 1253 | /* |
1246 | 1254 | * pgprot is PAGE_NONE, PAGE_RO, or PAGE_RW (see __Pxxx / __Sxxx) | |
1247 | if (pgprot_val(pgprot) & _PAGE_INVALID) { | 1255 | * Convert to segment table entry format. |
1248 | if (pgprot_val(pgprot) & _PAGE_SWT) | 1256 | */ |
1249 | pgprot_pmd |= _HPAGE_TYPE_NONE; | 1257 | if (pgprot_val(pgprot) == pgprot_val(PAGE_NONE)) |
1250 | pgprot_pmd |= _SEGMENT_ENTRY_INV; | 1258 | return pgprot_val(SEGMENT_NONE); |
1251 | } | 1259 | if (pgprot_val(pgprot) == pgprot_val(PAGE_RO)) |
1252 | if (pgprot_val(pgprot) & _PAGE_RO) | 1260 | return pgprot_val(SEGMENT_RO); |
1253 | pgprot_pmd |= _SEGMENT_ENTRY_RO; | 1261 | return pgprot_val(SEGMENT_RW); |
1254 | return pgprot_pmd; | ||
1255 | } | 1262 | } |
1256 | 1263 | ||
1257 | static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) | 1264 | static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) |
@@ -1269,7 +1276,9 @@ static inline pmd_t pmd_mkhuge(pmd_t pmd) | |||
1269 | 1276 | ||
1270 | static inline pmd_t pmd_mkwrite(pmd_t pmd) | 1277 | static inline pmd_t pmd_mkwrite(pmd_t pmd) |
1271 | { | 1278 | { |
1272 | pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO; | 1279 | /* Do not clobber _HPAGE_TYPE_NONE pages! */ |
1280 | if (!(pmd_val(pmd) & _SEGMENT_ENTRY_INV)) | ||
1281 | pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO; | ||
1273 | return pmd; | 1282 | return pmd; |
1274 | } | 1283 | } |
1275 | 1284 | ||
diff --git a/arch/s390/kernel/sclp.S b/arch/s390/kernel/sclp.S index bf053898630..b6506ee32a3 100644 --- a/arch/s390/kernel/sclp.S +++ b/arch/s390/kernel/sclp.S | |||
@@ -44,6 +44,12 @@ _sclp_wait_int: | |||
44 | #endif | 44 | #endif |
45 | mvc .LoldpswS1-.LbaseS1(16,%r13),0(%r8) | 45 | mvc .LoldpswS1-.LbaseS1(16,%r13),0(%r8) |
46 | mvc 0(16,%r8),0(%r9) | 46 | mvc 0(16,%r8),0(%r9) |
47 | #ifdef CONFIG_64BIT | ||
48 | epsw %r6,%r7 # set current addressing mode | ||
49 | nill %r6,0x1 # in new psw (31 or 64 bit mode) | ||
50 | nilh %r7,0x8000 | ||
51 | stm %r6,%r7,0(%r8) | ||
52 | #endif | ||
47 | lhi %r6,0x0200 # cr mask for ext int (cr0.54) | 53 | lhi %r6,0x0200 # cr mask for ext int (cr0.54) |
48 | ltr %r2,%r2 | 54 | ltr %r2,%r2 |
49 | jz .LsetctS1 | 55 | jz .LsetctS1 |
@@ -87,7 +93,7 @@ _sclp_wait_int: | |||
87 | .long 0x00080000, 0x80000000+.LwaitS1 # PSW to handle ext int | 93 | .long 0x00080000, 0x80000000+.LwaitS1 # PSW to handle ext int |
88 | #ifdef CONFIG_64BIT | 94 | #ifdef CONFIG_64BIT |
89 | .LextpswS1_64: | 95 | .LextpswS1_64: |
90 | .quad 0x0000000180000000, .LwaitS1 # PSW to handle ext int, 64 bit | 96 | .quad 0, .LwaitS1 # PSW to handle ext int, 64 bit |
91 | #endif | 97 | #endif |
92 | .LwaitpswS1: | 98 | .LwaitpswS1: |
93 | .long 0x010a0000, 0x00000000+.LloopS1 # PSW to wait for ext int | 99 | .long 0x010a0000, 0x00000000+.LloopS1 # PSW to wait for ext int |
diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c index 2d37bb861fa..9017a63dda3 100644 --- a/arch/s390/lib/uaccess_pt.c +++ b/arch/s390/lib/uaccess_pt.c | |||
@@ -39,7 +39,7 @@ static __always_inline unsigned long follow_table(struct mm_struct *mm, | |||
39 | pmd = pmd_offset(pud, addr); | 39 | pmd = pmd_offset(pud, addr); |
40 | if (pmd_none(*pmd)) | 40 | if (pmd_none(*pmd)) |
41 | return -0x10UL; | 41 | return -0x10UL; |
42 | if (pmd_huge(*pmd)) { | 42 | if (pmd_large(*pmd)) { |
43 | if (write && (pmd_val(*pmd) & _SEGMENT_ENTRY_RO)) | 43 | if (write && (pmd_val(*pmd) & _SEGMENT_ENTRY_RO)) |
44 | return -0x04UL; | 44 | return -0x04UL; |
45 | return (pmd_val(*pmd) & HPAGE_MASK) + (addr & ~HPAGE_MASK); | 45 | return (pmd_val(*pmd) & HPAGE_MASK) + (addr & ~HPAGE_MASK); |
diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c index 60acb93a468..8b8285310b5 100644 --- a/arch/s390/mm/gup.c +++ b/arch/s390/mm/gup.c | |||
@@ -126,7 +126,7 @@ static inline int gup_pmd_range(pud_t *pudp, pud_t pud, unsigned long addr, | |||
126 | */ | 126 | */ |
127 | if (pmd_none(pmd) || pmd_trans_splitting(pmd)) | 127 | if (pmd_none(pmd) || pmd_trans_splitting(pmd)) |
128 | return 0; | 128 | return 0; |
129 | if (unlikely(pmd_huge(pmd))) { | 129 | if (unlikely(pmd_large(pmd))) { |
130 | if (!gup_huge_pmd(pmdp, pmd, addr, next, | 130 | if (!gup_huge_pmd(pmdp, pmd, addr, next, |
131 | write, pages, nr)) | 131 | write, pages, nr)) |
132 | return 0; | 132 | return 0; |