Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4ad48bb7 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull s390 fixes from Martin Schwidefsky:
 "A couple of bug fixes.  I keep the fingers crossed that we now got
  transparent huge pages ready for prime time."

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
  s390/cio: fix length calculation in idset.c
  s390/sclp: fix addressing mode clobber
  s390: Move css limits from drivers/s390/cio/ to include/asm/.
  s390/thp: respect page protection in pmd_none() and pmd_present()
  s390/mm: use pmd_large() instead of pmd_huge()
  s390/cio: suppress 2nd path verification during resume
parents 976bacef 7f0bc6c0
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -9,6 +9,8 @@

#define LPM_ANYPATH 0xff
#define __MAX_CSSID 0
#define __MAX_SUBCHANNEL 65535
#define __MAX_SSID 3

#include <asm/scsw.h>

+22 −13
Original line number Diff line number Diff line
@@ -506,12 +506,15 @@ static inline int pud_bad(pud_t pud)

static inline int pmd_present(pmd_t pmd)
{
	return (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) != 0UL;
	unsigned long mask = _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY_RO;
	return (pmd_val(pmd) & mask) == _HPAGE_TYPE_NONE ||
	       !(pmd_val(pmd) & _SEGMENT_ENTRY_INV);
}

static inline int pmd_none(pmd_t pmd)
{
	return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) != 0UL;
	return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) &&
	       !(pmd_val(pmd) & _SEGMENT_ENTRY_RO);
}

static inline int pmd_large(pmd_t pmd)
@@ -1223,6 +1226,11 @@ static inline void __pmd_idte(unsigned long address, pmd_t *pmdp)
}

#ifdef CONFIG_TRANSPARENT_HUGEPAGE

#define SEGMENT_NONE	__pgprot(_HPAGE_TYPE_NONE)
#define SEGMENT_RO	__pgprot(_HPAGE_TYPE_RO)
#define SEGMENT_RW	__pgprot(_HPAGE_TYPE_RW)

#define __HAVE_ARCH_PGTABLE_DEPOSIT
extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable);

@@ -1242,16 +1250,15 @@ static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,

static inline unsigned long massage_pgprot_pmd(pgprot_t pgprot)
{
	unsigned long pgprot_pmd = 0;

	if (pgprot_val(pgprot) & _PAGE_INVALID) {
		if (pgprot_val(pgprot) & _PAGE_SWT)
			pgprot_pmd |= _HPAGE_TYPE_NONE;
		pgprot_pmd |= _SEGMENT_ENTRY_INV;
	}
	if (pgprot_val(pgprot) & _PAGE_RO)
		pgprot_pmd |= _SEGMENT_ENTRY_RO;
	return pgprot_pmd;
	/*
	 * pgprot is PAGE_NONE, PAGE_RO, or PAGE_RW (see __Pxxx / __Sxxx)
	 * Convert to segment table entry format.
	 */
	if (pgprot_val(pgprot) == pgprot_val(PAGE_NONE))
		return pgprot_val(SEGMENT_NONE);
	if (pgprot_val(pgprot) == pgprot_val(PAGE_RO))
		return pgprot_val(SEGMENT_RO);
	return pgprot_val(SEGMENT_RW);
}

static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
@@ -1269,6 +1276,8 @@ static inline pmd_t pmd_mkhuge(pmd_t pmd)

static inline pmd_t pmd_mkwrite(pmd_t pmd)
{
	/* Do not clobber _HPAGE_TYPE_NONE pages! */
	if (!(pmd_val(pmd) & _SEGMENT_ENTRY_INV))
		pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO;
	return pmd;
}
+7 −1
Original line number Diff line number Diff line
@@ -44,6 +44,12 @@ _sclp_wait_int:
#endif
	mvc	.LoldpswS1-.LbaseS1(16,%r13),0(%r8)
	mvc	0(16,%r8),0(%r9)
#ifdef CONFIG_64BIT
	epsw	%r6,%r7				# set current addressing mode
	nill	%r6,0x1				# in new psw (31 or 64 bit mode)
	nilh	%r7,0x8000
	stm	%r6,%r7,0(%r8)
#endif
	lhi	%r6,0x0200			# cr mask for ext int (cr0.54)
	ltr	%r2,%r2
	jz	.LsetctS1
@@ -87,7 +93,7 @@ _sclp_wait_int:
	.long	0x00080000, 0x80000000+.LwaitS1	# PSW to handle ext int
#ifdef CONFIG_64BIT
.LextpswS1_64:
	.quad	0x0000000180000000, .LwaitS1	# PSW to handle ext int, 64 bit
	.quad	0, .LwaitS1			# PSW to handle ext int, 64 bit
#endif
.LwaitpswS1:
	.long	0x010a0000, 0x00000000+.LloopS1	# PSW to wait for ext int
+1 −1
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ static __always_inline unsigned long follow_table(struct mm_struct *mm,
	pmd = pmd_offset(pud, addr);
	if (pmd_none(*pmd))
		return -0x10UL;
	if (pmd_huge(*pmd)) {
	if (pmd_large(*pmd)) {
		if (write && (pmd_val(*pmd) & _SEGMENT_ENTRY_RO))
			return -0x04UL;
		return (pmd_val(*pmd) & HPAGE_MASK) + (addr & ~HPAGE_MASK);
+1 −1
Original line number Diff line number Diff line
@@ -126,7 +126,7 @@ static inline int gup_pmd_range(pud_t *pudp, pud_t pud, unsigned long addr,
		 */
		if (pmd_none(pmd) || pmd_trans_splitting(pmd))
			return 0;
		if (unlikely(pmd_huge(pmd))) {
		if (unlikely(pmd_large(pmd))) {
			if (!gup_huge_pmd(pmdp, pmd, addr, next,
					  write, pages, nr))
				return 0;
Loading