forked from luck/tmp_suning_uos_patched
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
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
This commit is contained in:
commit
4ad48bb72c
@ -9,6 +9,8 @@
|
||||
|
||||
#define LPM_ANYPATH 0xff
|
||||
#define __MAX_CSSID 0
|
||||
#define __MAX_SUBCHANNEL 65535
|
||||
#define __MAX_SSID 3
|
||||
|
||||
#include <asm/scsw.h>
|
||||
|
||||
|
@ -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,7 +1276,9 @@ static inline pmd_t pmd_mkhuge(pmd_t pmd)
|
||||
|
||||
static inline pmd_t pmd_mkwrite(pmd_t pmd)
|
||||
{
|
||||
pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO;
|
||||
/* Do not clobber _HPAGE_TYPE_NONE pages! */
|
||||
if (!(pmd_val(pmd) & _SEGMENT_ENTRY_INV))
|
||||
pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO;
|
||||
return pmd;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -112,9 +112,6 @@ extern int for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *);
|
||||
extern void css_reiterate_subchannels(void);
|
||||
void css_update_ssd_info(struct subchannel *sch);
|
||||
|
||||
#define __MAX_SUBCHANNEL 65535
|
||||
#define __MAX_SSID 3
|
||||
|
||||
struct channel_subsystem {
|
||||
u8 cssid;
|
||||
int valid;
|
||||
|
@ -1424,7 +1424,7 @@ static enum io_sch_action sch_get_action(struct subchannel *sch)
|
||||
}
|
||||
if (device_is_disconnected(cdev))
|
||||
return IO_SCH_REPROBE;
|
||||
if (cdev->online)
|
||||
if (cdev->online && !cdev->private->flags.resuming)
|
||||
return IO_SCH_VERIFY;
|
||||
if (cdev->private->state == DEV_STATE_NOT_OPER)
|
||||
return IO_SCH_UNREG_ATTACH;
|
||||
@ -1469,12 +1469,6 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process)
|
||||
rc = 0;
|
||||
goto out_unlock;
|
||||
case IO_SCH_VERIFY:
|
||||
if (cdev->private->flags.resuming == 1) {
|
||||
if (cio_enable_subchannel(sch, (u32)(addr_t)sch)) {
|
||||
ccw_device_set_notoper(cdev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Trigger path verification. */
|
||||
io_subchannel_verify(sch);
|
||||
rc = 0;
|
||||
|
@ -125,8 +125,7 @@ int idset_is_empty(struct idset *set)
|
||||
|
||||
void idset_add_set(struct idset *to, struct idset *from)
|
||||
{
|
||||
int len = min(__BITOPS_WORDS(to->num_ssid * to->num_id),
|
||||
__BITOPS_WORDS(from->num_ssid * from->num_id));
|
||||
int len = min(to->num_ssid * to->num_id, from->num_ssid * from->num_id);
|
||||
|
||||
bitmap_or(to->bitmap, to->bitmap, from->bitmap, len);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user