Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Martin Schwidefsky: "A couple of bug fixes, one of them is a TLB flush fix. Included as well is one small coding style patch and a patch to update the default configuration." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: [S390] Fix compile error in swab.h [S390] Fix stfle() lowcore protection problem [S390] cpum_cf: get rid of compile warnings [S390] irq: simple coding style change [S390] update default configuration [S390] fix tlb flushing for page table pages [S390] kernel: Use local_irq_save() for memcpy_real() [S390] s390/char/vmur.c: fix memory leak [S390] drivers/s390/block/dasd_eckd.c: add missing dasd_sfree_request
This commit is contained in:
@@ -90,7 +90,6 @@ config S390
|
|||||||
select HAVE_KERNEL_XZ
|
select HAVE_KERNEL_XZ
|
||||||
select HAVE_ARCH_MUTEX_CPU_RELAX
|
select HAVE_ARCH_MUTEX_CPU_RELAX
|
||||||
select HAVE_ARCH_JUMP_LABEL if !MARCH_G5
|
select HAVE_ARCH_JUMP_LABEL if !MARCH_G5
|
||||||
select HAVE_RCU_TABLE_FREE if SMP
|
|
||||||
select ARCH_SAVE_PAGE_KEYS if HIBERNATION
|
select ARCH_SAVE_PAGE_KEYS if HIBERNATION
|
||||||
select HAVE_MEMBLOCK
|
select HAVE_MEMBLOCK
|
||||||
select HAVE_MEMBLOCK_NODE_MAP
|
select HAVE_MEMBLOCK_NODE_MAP
|
||||||
|
@@ -1,8 +1,12 @@
|
|||||||
CONFIG_EXPERIMENTAL=y
|
CONFIG_EXPERIMENTAL=y
|
||||||
CONFIG_SYSVIPC=y
|
CONFIG_SYSVIPC=y
|
||||||
CONFIG_POSIX_MQUEUE=y
|
CONFIG_POSIX_MQUEUE=y
|
||||||
|
CONFIG_FHANDLE=y
|
||||||
|
CONFIG_TASKSTATS=y
|
||||||
|
CONFIG_TASK_DELAY_ACCT=y
|
||||||
|
CONFIG_TASK_XACCT=y
|
||||||
|
CONFIG_TASK_IO_ACCOUNTING=y
|
||||||
CONFIG_AUDIT=y
|
CONFIG_AUDIT=y
|
||||||
CONFIG_RCU_TRACE=y
|
|
||||||
CONFIG_IKCONFIG=y
|
CONFIG_IKCONFIG=y
|
||||||
CONFIG_IKCONFIG_PROC=y
|
CONFIG_IKCONFIG_PROC=y
|
||||||
CONFIG_CGROUPS=y
|
CONFIG_CGROUPS=y
|
||||||
@@ -14,16 +18,22 @@ CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y
|
|||||||
CONFIG_CGROUP_SCHED=y
|
CONFIG_CGROUP_SCHED=y
|
||||||
CONFIG_RT_GROUP_SCHED=y
|
CONFIG_RT_GROUP_SCHED=y
|
||||||
CONFIG_BLK_CGROUP=y
|
CONFIG_BLK_CGROUP=y
|
||||||
|
CONFIG_NAMESPACES=y
|
||||||
CONFIG_BLK_DEV_INITRD=y
|
CONFIG_BLK_DEV_INITRD=y
|
||||||
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
|
CONFIG_RD_BZIP2=y
|
||||||
|
CONFIG_RD_LZMA=y
|
||||||
|
CONFIG_RD_XZ=y
|
||||||
|
CONFIG_RD_LZO=y
|
||||||
|
CONFIG_EXPERT=y
|
||||||
# CONFIG_COMPAT_BRK is not set
|
# CONFIG_COMPAT_BRK is not set
|
||||||
CONFIG_SLAB=y
|
|
||||||
CONFIG_PROFILING=y
|
CONFIG_PROFILING=y
|
||||||
CONFIG_OPROFILE=y
|
CONFIG_OPROFILE=y
|
||||||
CONFIG_KPROBES=y
|
CONFIG_KPROBES=y
|
||||||
CONFIG_MODULES=y
|
CONFIG_MODULES=y
|
||||||
CONFIG_MODULE_UNLOAD=y
|
CONFIG_MODULE_UNLOAD=y
|
||||||
CONFIG_MODVERSIONS=y
|
CONFIG_MODVERSIONS=y
|
||||||
|
CONFIG_PARTITION_ADVANCED=y
|
||||||
|
CONFIG_IBM_PARTITION=y
|
||||||
CONFIG_DEFAULT_DEADLINE=y
|
CONFIG_DEFAULT_DEADLINE=y
|
||||||
CONFIG_NO_HZ=y
|
CONFIG_NO_HZ=y
|
||||||
CONFIG_HIGH_RES_TIMERS=y
|
CONFIG_HIGH_RES_TIMERS=y
|
||||||
@@ -34,18 +44,15 @@ CONFIG_KSM=y
|
|||||||
CONFIG_BINFMT_MISC=m
|
CONFIG_BINFMT_MISC=m
|
||||||
CONFIG_CMM=m
|
CONFIG_CMM=m
|
||||||
CONFIG_HZ_100=y
|
CONFIG_HZ_100=y
|
||||||
CONFIG_KEXEC=y
|
CONFIG_CRASH_DUMP=y
|
||||||
CONFIG_PM=y
|
|
||||||
CONFIG_HIBERNATION=y
|
CONFIG_HIBERNATION=y
|
||||||
CONFIG_PACKET=y
|
CONFIG_PACKET=y
|
||||||
CONFIG_UNIX=y
|
CONFIG_UNIX=y
|
||||||
CONFIG_NET_KEY=y
|
CONFIG_NET_KEY=y
|
||||||
CONFIG_AFIUCV=m
|
|
||||||
CONFIG_INET=y
|
CONFIG_INET=y
|
||||||
CONFIG_IP_MULTICAST=y
|
CONFIG_IP_MULTICAST=y
|
||||||
# CONFIG_INET_LRO is not set
|
# CONFIG_INET_LRO is not set
|
||||||
CONFIG_IPV6=y
|
CONFIG_IPV6=y
|
||||||
CONFIG_NET_SCTPPROBE=m
|
|
||||||
CONFIG_L2TP=m
|
CONFIG_L2TP=m
|
||||||
CONFIG_L2TP_DEBUGFS=m
|
CONFIG_L2TP_DEBUGFS=m
|
||||||
CONFIG_VLAN_8021Q=y
|
CONFIG_VLAN_8021Q=y
|
||||||
@@ -84,15 +91,14 @@ CONFIG_SCSI_CONSTANTS=y
|
|||||||
CONFIG_SCSI_LOGGING=y
|
CONFIG_SCSI_LOGGING=y
|
||||||
CONFIG_SCSI_SCAN_ASYNC=y
|
CONFIG_SCSI_SCAN_ASYNC=y
|
||||||
CONFIG_ZFCP=y
|
CONFIG_ZFCP=y
|
||||||
CONFIG_ZFCP_DIF=y
|
|
||||||
CONFIG_NETDEVICES=y
|
CONFIG_NETDEVICES=y
|
||||||
CONFIG_DUMMY=m
|
|
||||||
CONFIG_BONDING=m
|
CONFIG_BONDING=m
|
||||||
|
CONFIG_DUMMY=m
|
||||||
CONFIG_EQUALIZER=m
|
CONFIG_EQUALIZER=m
|
||||||
CONFIG_TUN=m
|
CONFIG_TUN=m
|
||||||
CONFIG_NET_ETHERNET=y
|
|
||||||
CONFIG_VIRTIO_NET=y
|
CONFIG_VIRTIO_NET=y
|
||||||
CONFIG_RAW_DRIVER=m
|
CONFIG_RAW_DRIVER=m
|
||||||
|
CONFIG_VIRTIO_BALLOON=y
|
||||||
CONFIG_EXT2_FS=y
|
CONFIG_EXT2_FS=y
|
||||||
CONFIG_EXT3_FS=y
|
CONFIG_EXT3_FS=y
|
||||||
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
|
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
|
||||||
@@ -103,27 +109,21 @@ CONFIG_PROC_KCORE=y
|
|||||||
CONFIG_TMPFS=y
|
CONFIG_TMPFS=y
|
||||||
CONFIG_TMPFS_POSIX_ACL=y
|
CONFIG_TMPFS_POSIX_ACL=y
|
||||||
# CONFIG_NETWORK_FILESYSTEMS is not set
|
# CONFIG_NETWORK_FILESYSTEMS is not set
|
||||||
CONFIG_PARTITION_ADVANCED=y
|
|
||||||
CONFIG_IBM_PARTITION=y
|
|
||||||
CONFIG_DLM=m
|
|
||||||
CONFIG_MAGIC_SYSRQ=y
|
CONFIG_MAGIC_SYSRQ=y
|
||||||
CONFIG_DEBUG_KERNEL=y
|
|
||||||
CONFIG_TIMER_STATS=y
|
CONFIG_TIMER_STATS=y
|
||||||
CONFIG_PROVE_LOCKING=y
|
CONFIG_PROVE_LOCKING=y
|
||||||
CONFIG_PROVE_RCU=y
|
CONFIG_PROVE_RCU=y
|
||||||
CONFIG_LOCK_STAT=y
|
CONFIG_LOCK_STAT=y
|
||||||
CONFIG_DEBUG_LOCKDEP=y
|
CONFIG_DEBUG_LOCKDEP=y
|
||||||
CONFIG_DEBUG_SPINLOCK_SLEEP=y
|
|
||||||
CONFIG_DEBUG_LIST=y
|
CONFIG_DEBUG_LIST=y
|
||||||
CONFIG_DEBUG_NOTIFIERS=y
|
CONFIG_DEBUG_NOTIFIERS=y
|
||||||
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
|
CONFIG_RCU_TRACE=y
|
||||||
CONFIG_KPROBES_SANITY_TEST=y
|
CONFIG_KPROBES_SANITY_TEST=y
|
||||||
CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
|
CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
|
||||||
CONFIG_CPU_NOTIFIER_ERROR_INJECT=m
|
CONFIG_CPU_NOTIFIER_ERROR_INJECT=m
|
||||||
CONFIG_LATENCYTOP=y
|
CONFIG_LATENCYTOP=y
|
||||||
CONFIG_SYSCTL_SYSCALL_CHECK=y
|
|
||||||
CONFIG_DEBUG_PAGEALLOC=y
|
CONFIG_DEBUG_PAGEALLOC=y
|
||||||
# CONFIG_FTRACE is not set
|
CONFIG_BLK_DEV_IO_TRACE=y
|
||||||
# CONFIG_STRICT_DEVMEM is not set
|
# CONFIG_STRICT_DEVMEM is not set
|
||||||
CONFIG_CRYPTO_NULL=m
|
CONFIG_CRYPTO_NULL=m
|
||||||
CONFIG_CRYPTO_CRYPTD=m
|
CONFIG_CRYPTO_CRYPTD=m
|
||||||
@@ -173,4 +173,3 @@ CONFIG_CRYPTO_SHA512_S390=m
|
|||||||
CONFIG_CRYPTO_DES_S390=m
|
CONFIG_CRYPTO_DES_S390=m
|
||||||
CONFIG_CRYPTO_AES_S390=m
|
CONFIG_CRYPTO_AES_S390=m
|
||||||
CONFIG_CRC7=m
|
CONFIG_CRC7=m
|
||||||
CONFIG_VIRTIO_BALLOON=y
|
|
||||||
|
@@ -38,12 +38,11 @@ static inline void stfle(u64 *stfle_fac_list, int size)
|
|||||||
unsigned long nr;
|
unsigned long nr;
|
||||||
|
|
||||||
preempt_disable();
|
preempt_disable();
|
||||||
S390_lowcore.stfl_fac_list = 0;
|
|
||||||
asm volatile(
|
asm volatile(
|
||||||
" .insn s,0xb2b10000,0(0)\n" /* stfl */
|
" .insn s,0xb2b10000,0(0)\n" /* stfl */
|
||||||
"0:\n"
|
"0:\n"
|
||||||
EX_TABLE(0b, 0b)
|
EX_TABLE(0b, 0b)
|
||||||
: "=m" (S390_lowcore.stfl_fac_list));
|
: "+m" (S390_lowcore.stfl_fac_list));
|
||||||
nr = 4; /* bytes stored by stfl */
|
nr = 4; /* bytes stored by stfl */
|
||||||
memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4);
|
memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4);
|
||||||
if (S390_lowcore.stfl_fac_list & 0x01000000) {
|
if (S390_lowcore.stfl_fac_list & 0x01000000) {
|
||||||
|
@@ -22,10 +22,7 @@ void crst_table_free(struct mm_struct *, unsigned long *);
|
|||||||
|
|
||||||
unsigned long *page_table_alloc(struct mm_struct *, unsigned long);
|
unsigned long *page_table_alloc(struct mm_struct *, unsigned long);
|
||||||
void page_table_free(struct mm_struct *, unsigned long *);
|
void page_table_free(struct mm_struct *, unsigned long *);
|
||||||
#ifdef CONFIG_HAVE_RCU_TABLE_FREE
|
|
||||||
void page_table_free_rcu(struct mmu_gather *, unsigned long *);
|
void page_table_free_rcu(struct mmu_gather *, unsigned long *);
|
||||||
void __tlb_remove_table(void *_table);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline void clear_table(unsigned long *s, unsigned long val, size_t n)
|
static inline void clear_table(unsigned long *s, unsigned long val, size_t n)
|
||||||
{
|
{
|
||||||
|
@@ -77,7 +77,7 @@ static inline __u16 __arch_swab16p(const __u16 *x)
|
|||||||
|
|
||||||
asm volatile(
|
asm volatile(
|
||||||
#ifndef __s390x__
|
#ifndef __s390x__
|
||||||
" icm %0,2,%O+1(%R1)\n"
|
" icm %0,2,%O1+1(%R1)\n"
|
||||||
" ic %0,%1\n"
|
" ic %0,%1\n"
|
||||||
: "=&d" (result) : "Q" (*x) : "cc");
|
: "=&d" (result) : "Q" (*x) : "cc");
|
||||||
#else /* __s390x__ */
|
#else /* __s390x__ */
|
||||||
|
@@ -30,14 +30,10 @@
|
|||||||
|
|
||||||
struct mmu_gather {
|
struct mmu_gather {
|
||||||
struct mm_struct *mm;
|
struct mm_struct *mm;
|
||||||
#ifdef CONFIG_HAVE_RCU_TABLE_FREE
|
|
||||||
struct mmu_table_batch *batch;
|
struct mmu_table_batch *batch;
|
||||||
#endif
|
|
||||||
unsigned int fullmm;
|
unsigned int fullmm;
|
||||||
unsigned int need_flush;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_HAVE_RCU_TABLE_FREE
|
|
||||||
struct mmu_table_batch {
|
struct mmu_table_batch {
|
||||||
struct rcu_head rcu;
|
struct rcu_head rcu;
|
||||||
unsigned int nr;
|
unsigned int nr;
|
||||||
@@ -49,7 +45,6 @@ struct mmu_table_batch {
|
|||||||
|
|
||||||
extern void tlb_table_flush(struct mmu_gather *tlb);
|
extern void tlb_table_flush(struct mmu_gather *tlb);
|
||||||
extern void tlb_remove_table(struct mmu_gather *tlb, void *table);
|
extern void tlb_remove_table(struct mmu_gather *tlb, void *table);
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline void tlb_gather_mmu(struct mmu_gather *tlb,
|
static inline void tlb_gather_mmu(struct mmu_gather *tlb,
|
||||||
struct mm_struct *mm,
|
struct mm_struct *mm,
|
||||||
@@ -57,29 +52,20 @@ static inline void tlb_gather_mmu(struct mmu_gather *tlb,
|
|||||||
{
|
{
|
||||||
tlb->mm = mm;
|
tlb->mm = mm;
|
||||||
tlb->fullmm = full_mm_flush;
|
tlb->fullmm = full_mm_flush;
|
||||||
tlb->need_flush = 0;
|
|
||||||
#ifdef CONFIG_HAVE_RCU_TABLE_FREE
|
|
||||||
tlb->batch = NULL;
|
tlb->batch = NULL;
|
||||||
#endif
|
|
||||||
if (tlb->fullmm)
|
if (tlb->fullmm)
|
||||||
__tlb_flush_mm(mm);
|
__tlb_flush_mm(mm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void tlb_flush_mmu(struct mmu_gather *tlb)
|
static inline void tlb_flush_mmu(struct mmu_gather *tlb)
|
||||||
{
|
{
|
||||||
if (!tlb->need_flush)
|
|
||||||
return;
|
|
||||||
tlb->need_flush = 0;
|
|
||||||
__tlb_flush_mm(tlb->mm);
|
|
||||||
#ifdef CONFIG_HAVE_RCU_TABLE_FREE
|
|
||||||
tlb_table_flush(tlb);
|
tlb_table_flush(tlb);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void tlb_finish_mmu(struct mmu_gather *tlb,
|
static inline void tlb_finish_mmu(struct mmu_gather *tlb,
|
||||||
unsigned long start, unsigned long end)
|
unsigned long start, unsigned long end)
|
||||||
{
|
{
|
||||||
tlb_flush_mmu(tlb);
|
tlb_table_flush(tlb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -105,10 +91,8 @@ static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
|
|||||||
static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
|
static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
|
||||||
unsigned long address)
|
unsigned long address)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_HAVE_RCU_TABLE_FREE
|
|
||||||
if (!tlb->fullmm)
|
if (!tlb->fullmm)
|
||||||
return page_table_free_rcu(tlb, (unsigned long *) pte);
|
return page_table_free_rcu(tlb, (unsigned long *) pte);
|
||||||
#endif
|
|
||||||
page_table_free(tlb->mm, (unsigned long *) pte);
|
page_table_free(tlb->mm, (unsigned long *) pte);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,10 +109,8 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd,
|
|||||||
#ifdef __s390x__
|
#ifdef __s390x__
|
||||||
if (tlb->mm->context.asce_limit <= (1UL << 31))
|
if (tlb->mm->context.asce_limit <= (1UL << 31))
|
||||||
return;
|
return;
|
||||||
#ifdef CONFIG_HAVE_RCU_TABLE_FREE
|
|
||||||
if (!tlb->fullmm)
|
if (!tlb->fullmm)
|
||||||
return tlb_remove_table(tlb, pmd);
|
return tlb_remove_table(tlb, pmd);
|
||||||
#endif
|
|
||||||
crst_table_free(tlb->mm, (unsigned long *) pmd);
|
crst_table_free(tlb->mm, (unsigned long *) pmd);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -146,10 +128,8 @@ static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud,
|
|||||||
#ifdef __s390x__
|
#ifdef __s390x__
|
||||||
if (tlb->mm->context.asce_limit <= (1UL << 42))
|
if (tlb->mm->context.asce_limit <= (1UL << 42))
|
||||||
return;
|
return;
|
||||||
#ifdef CONFIG_HAVE_RCU_TABLE_FREE
|
|
||||||
if (!tlb->fullmm)
|
if (!tlb->fullmm)
|
||||||
return tlb_remove_table(tlb, pud);
|
return tlb_remove_table(tlb, pud);
|
||||||
#endif
|
|
||||||
crst_table_free(tlb->mm, (unsigned long *) pud);
|
crst_table_free(tlb->mm, (unsigned long *) pud);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@@ -474,9 +474,9 @@ ENTRY(startup_kdump)
|
|||||||
stck __LC_LAST_UPDATE_CLOCK
|
stck __LC_LAST_UPDATE_CLOCK
|
||||||
spt 5f-.LPG0(%r13)
|
spt 5f-.LPG0(%r13)
|
||||||
mvc __LC_LAST_UPDATE_TIMER(8),5f-.LPG0(%r13)
|
mvc __LC_LAST_UPDATE_TIMER(8),5f-.LPG0(%r13)
|
||||||
|
xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST
|
||||||
#ifndef CONFIG_MARCH_G5
|
#ifndef CONFIG_MARCH_G5
|
||||||
# check capabilities against MARCH_{G5,Z900,Z990,Z9_109,Z10}
|
# check capabilities against MARCH_{G5,Z900,Z990,Z9_109,Z10}
|
||||||
xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST
|
|
||||||
.insn s,0xb2b10000,__LC_STFL_FAC_LIST # store facility list
|
.insn s,0xb2b10000,__LC_STFL_FAC_LIST # store facility list
|
||||||
tm __LC_STFL_FAC_LIST,0x01 # stfle available ?
|
tm __LC_STFL_FAC_LIST,0x01 # stfle available ?
|
||||||
jz 0f
|
jz 0f
|
||||||
|
@@ -118,9 +118,10 @@ asmlinkage void do_softirq(void)
|
|||||||
"a" (__do_softirq)
|
"a" (__do_softirq)
|
||||||
: "0", "1", "2", "3", "4", "5", "14",
|
: "0", "1", "2", "3", "4", "5", "14",
|
||||||
"cc", "memory" );
|
"cc", "memory" );
|
||||||
} else
|
} else {
|
||||||
/* We are already on the async stack. */
|
/* We are already on the async stack. */
|
||||||
__do_softirq();
|
__do_softirq();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
@@ -192,11 +193,12 @@ int unregister_external_interrupt(u16 code, ext_int_handler_t handler)
|
|||||||
int index = ext_hash(code);
|
int index = ext_hash(code);
|
||||||
|
|
||||||
spin_lock_irqsave(&ext_int_hash_lock, flags);
|
spin_lock_irqsave(&ext_int_hash_lock, flags);
|
||||||
list_for_each_entry_rcu(p, &ext_int_hash[index], entry)
|
list_for_each_entry_rcu(p, &ext_int_hash[index], entry) {
|
||||||
if (p->code == code && p->handler == handler) {
|
if (p->code == code && p->handler == handler) {
|
||||||
list_del_rcu(&p->entry);
|
list_del_rcu(&p->entry);
|
||||||
kfree_rcu(p, rcu);
|
kfree_rcu(p, rcu);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
spin_unlock_irqrestore(&ext_int_hash_lock, flags);
|
spin_unlock_irqrestore(&ext_int_hash_lock, flags);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -211,9 +213,10 @@ void __irq_entry do_extint(struct pt_regs *regs, struct ext_code ext_code,
|
|||||||
|
|
||||||
old_regs = set_irq_regs(regs);
|
old_regs = set_irq_regs(regs);
|
||||||
irq_enter();
|
irq_enter();
|
||||||
if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator)
|
if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) {
|
||||||
/* Serve timer interrupts first. */
|
/* Serve timer interrupts first. */
|
||||||
clock_comparator_work();
|
clock_comparator_work();
|
||||||
|
}
|
||||||
kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++;
|
kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++;
|
||||||
if (ext_code.code != 0x1004)
|
if (ext_code.code != 0x1004)
|
||||||
__get_cpu_var(s390_idle).nohz_delay = 1;
|
__get_cpu_var(s390_idle).nohz_delay = 1;
|
||||||
|
@@ -178,7 +178,7 @@ static void cpumf_pmu_enable(struct pmu *pmu)
|
|||||||
err = lcctl(cpuhw->state);
|
err = lcctl(cpuhw->state);
|
||||||
if (err) {
|
if (err) {
|
||||||
pr_err("Enabling the performance measuring unit "
|
pr_err("Enabling the performance measuring unit "
|
||||||
"failed with rc=%lx\n", err);
|
"failed with rc=%x\n", err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,7 +203,7 @@ static void cpumf_pmu_disable(struct pmu *pmu)
|
|||||||
err = lcctl(inactive);
|
err = lcctl(inactive);
|
||||||
if (err) {
|
if (err) {
|
||||||
pr_err("Disabling the performance measuring unit "
|
pr_err("Disabling the performance measuring unit "
|
||||||
"failed with rc=%lx\n", err);
|
"failed with rc=%x\n", err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -61,21 +61,14 @@ long probe_kernel_write(void *dst, const void *src, size_t size)
|
|||||||
return copied < 0 ? -EFAULT : 0;
|
return copied < 0 ? -EFAULT : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static int __memcpy_real(void *dest, void *src, size_t count)
|
||||||
* Copy memory in real mode (kernel to kernel)
|
|
||||||
*/
|
|
||||||
int memcpy_real(void *dest, void *src, size_t count)
|
|
||||||
{
|
{
|
||||||
register unsigned long _dest asm("2") = (unsigned long) dest;
|
register unsigned long _dest asm("2") = (unsigned long) dest;
|
||||||
register unsigned long _len1 asm("3") = (unsigned long) count;
|
register unsigned long _len1 asm("3") = (unsigned long) count;
|
||||||
register unsigned long _src asm("4") = (unsigned long) src;
|
register unsigned long _src asm("4") = (unsigned long) src;
|
||||||
register unsigned long _len2 asm("5") = (unsigned long) count;
|
register unsigned long _len2 asm("5") = (unsigned long) count;
|
||||||
unsigned long flags;
|
|
||||||
int rc = -EFAULT;
|
int rc = -EFAULT;
|
||||||
|
|
||||||
if (!count)
|
|
||||||
return 0;
|
|
||||||
flags = __arch_local_irq_stnsm(0xf8UL);
|
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"0: mvcle %1,%2,0x0\n"
|
"0: mvcle %1,%2,0x0\n"
|
||||||
"1: jo 0b\n"
|
"1: jo 0b\n"
|
||||||
@@ -86,7 +79,23 @@ int memcpy_real(void *dest, void *src, size_t count)
|
|||||||
"+d" (_len2), "=m" (*((long *) dest))
|
"+d" (_len2), "=m" (*((long *) dest))
|
||||||
: "m" (*((long *) src))
|
: "m" (*((long *) src))
|
||||||
: "cc", "memory");
|
: "cc", "memory");
|
||||||
arch_local_irq_restore(flags);
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy memory in real mode (kernel to kernel)
|
||||||
|
*/
|
||||||
|
int memcpy_real(void *dest, void *src, size_t count)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (!count)
|
||||||
|
return 0;
|
||||||
|
local_irq_save(flags);
|
||||||
|
__arch_local_irq_stnsm(0xfbUL);
|
||||||
|
rc = __memcpy_real(dest, src, count);
|
||||||
|
local_irq_restore(flags);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -678,8 +678,6 @@ void page_table_free(struct mm_struct *mm, unsigned long *table)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_HAVE_RCU_TABLE_FREE
|
|
||||||
|
|
||||||
static void __page_table_free_rcu(void *table, unsigned bit)
|
static void __page_table_free_rcu(void *table, unsigned bit)
|
||||||
{
|
{
|
||||||
struct page *page;
|
struct page *page;
|
||||||
@@ -733,7 +731,66 @@ void __tlb_remove_table(void *_table)
|
|||||||
free_pages((unsigned long) table, ALLOC_ORDER);
|
free_pages((unsigned long) table, ALLOC_ORDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
static void tlb_remove_table_smp_sync(void *arg)
|
||||||
|
{
|
||||||
|
/* Simply deliver the interrupt */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tlb_remove_table_one(void *table)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This isn't an RCU grace period and hence the page-tables cannot be
|
||||||
|
* assumed to be actually RCU-freed.
|
||||||
|
*
|
||||||
|
* It is however sufficient for software page-table walkers that rely
|
||||||
|
* on IRQ disabling. See the comment near struct mmu_table_batch.
|
||||||
|
*/
|
||||||
|
smp_call_function(tlb_remove_table_smp_sync, NULL, 1);
|
||||||
|
__tlb_remove_table(table);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tlb_remove_table_rcu(struct rcu_head *head)
|
||||||
|
{
|
||||||
|
struct mmu_table_batch *batch;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
batch = container_of(head, struct mmu_table_batch, rcu);
|
||||||
|
|
||||||
|
for (i = 0; i < batch->nr; i++)
|
||||||
|
__tlb_remove_table(batch->tables[i]);
|
||||||
|
|
||||||
|
free_page((unsigned long)batch);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tlb_table_flush(struct mmu_gather *tlb)
|
||||||
|
{
|
||||||
|
struct mmu_table_batch **batch = &tlb->batch;
|
||||||
|
|
||||||
|
if (*batch) {
|
||||||
|
__tlb_flush_mm(tlb->mm);
|
||||||
|
call_rcu_sched(&(*batch)->rcu, tlb_remove_table_rcu);
|
||||||
|
*batch = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tlb_remove_table(struct mmu_gather *tlb, void *table)
|
||||||
|
{
|
||||||
|
struct mmu_table_batch **batch = &tlb->batch;
|
||||||
|
|
||||||
|
if (*batch == NULL) {
|
||||||
|
*batch = (struct mmu_table_batch *)
|
||||||
|
__get_free_page(GFP_NOWAIT | __GFP_NOWARN);
|
||||||
|
if (*batch == NULL) {
|
||||||
|
__tlb_flush_mm(tlb->mm);
|
||||||
|
tlb_remove_table_one(table);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
(*batch)->nr = 0;
|
||||||
|
}
|
||||||
|
(*batch)->tables[(*batch)->nr++] = table;
|
||||||
|
if ((*batch)->nr == MAX_TABLE_BATCH)
|
||||||
|
tlb_table_flush(tlb);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* switch on pgstes for its userspace process (for kvm)
|
* switch on pgstes for its userspace process (for kvm)
|
||||||
|
@@ -2844,6 +2844,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
|
|||||||
sector_t recid, trkid;
|
sector_t recid, trkid;
|
||||||
unsigned int offs;
|
unsigned int offs;
|
||||||
unsigned int count, count_to_trk_end;
|
unsigned int count, count_to_trk_end;
|
||||||
|
int ret;
|
||||||
|
|
||||||
basedev = block->base;
|
basedev = block->base;
|
||||||
if (rq_data_dir(req) == READ) {
|
if (rq_data_dir(req) == READ) {
|
||||||
@@ -2884,8 +2885,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
|
|||||||
|
|
||||||
itcw = itcw_init(cqr->data, itcw_size, itcw_op, 0, ctidaw, 0);
|
itcw = itcw_init(cqr->data, itcw_size, itcw_op, 0, ctidaw, 0);
|
||||||
if (IS_ERR(itcw)) {
|
if (IS_ERR(itcw)) {
|
||||||
dasd_sfree_request(cqr, startdev);
|
ret = -EINVAL;
|
||||||
return ERR_PTR(-EINVAL);
|
goto out_error;
|
||||||
}
|
}
|
||||||
cqr->cpaddr = itcw_get_tcw(itcw);
|
cqr->cpaddr = itcw_get_tcw(itcw);
|
||||||
if (prepare_itcw(itcw, first_trk, last_trk,
|
if (prepare_itcw(itcw, first_trk, last_trk,
|
||||||
@@ -2897,8 +2898,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
|
|||||||
/* Clock not in sync and XRC is enabled.
|
/* Clock not in sync and XRC is enabled.
|
||||||
* Try again later.
|
* Try again later.
|
||||||
*/
|
*/
|
||||||
dasd_sfree_request(cqr, startdev);
|
ret = -EAGAIN;
|
||||||
return ERR_PTR(-EAGAIN);
|
goto out_error;
|
||||||
}
|
}
|
||||||
len_to_track_end = 0;
|
len_to_track_end = 0;
|
||||||
/*
|
/*
|
||||||
@@ -2937,8 +2938,10 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
|
|||||||
tidaw_flags = 0;
|
tidaw_flags = 0;
|
||||||
last_tidaw = itcw_add_tidaw(itcw, tidaw_flags,
|
last_tidaw = itcw_add_tidaw(itcw, tidaw_flags,
|
||||||
dst, part_len);
|
dst, part_len);
|
||||||
if (IS_ERR(last_tidaw))
|
if (IS_ERR(last_tidaw)) {
|
||||||
return ERR_PTR(-EINVAL);
|
ret = -EINVAL;
|
||||||
|
goto out_error;
|
||||||
|
}
|
||||||
dst += part_len;
|
dst += part_len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2947,8 +2950,10 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
|
|||||||
dst = page_address(bv->bv_page) + bv->bv_offset;
|
dst = page_address(bv->bv_page) + bv->bv_offset;
|
||||||
last_tidaw = itcw_add_tidaw(itcw, 0x00,
|
last_tidaw = itcw_add_tidaw(itcw, 0x00,
|
||||||
dst, bv->bv_len);
|
dst, bv->bv_len);
|
||||||
if (IS_ERR(last_tidaw))
|
if (IS_ERR(last_tidaw)) {
|
||||||
return ERR_PTR(-EINVAL);
|
ret = -EINVAL;
|
||||||
|
goto out_error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
last_tidaw->flags |= TIDAW_FLAGS_LAST;
|
last_tidaw->flags |= TIDAW_FLAGS_LAST;
|
||||||
@@ -2968,6 +2973,9 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
|
|||||||
cqr->buildclk = get_clock();
|
cqr->buildclk = get_clock();
|
||||||
cqr->status = DASD_CQR_FILLED;
|
cqr->status = DASD_CQR_FILLED;
|
||||||
return cqr;
|
return cqr;
|
||||||
|
out_error:
|
||||||
|
dasd_sfree_request(cqr, startdev);
|
||||||
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
|
static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
|
||||||
|
@@ -903,7 +903,7 @@ static int ur_set_online(struct ccw_device *cdev)
|
|||||||
goto fail_urdev_put;
|
goto fail_urdev_put;
|
||||||
}
|
}
|
||||||
|
|
||||||
cdev_init(urd->char_device, &ur_fops);
|
urd->char_device->ops = &ur_fops;
|
||||||
urd->char_device->dev = MKDEV(major, minor);
|
urd->char_device->dev = MKDEV(major, minor);
|
||||||
urd->char_device->owner = ur_fops.owner;
|
urd->char_device->owner = ur_fops.owner;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user