diff options
Diffstat (limited to 'arch/s390')
| -rw-r--r-- | arch/s390/Kconfig | 1 | ||||
| -rw-r--r-- | arch/s390/Makefile | 4 | ||||
| -rw-r--r-- | arch/s390/include/asm/dma.h | 6 | ||||
| -rw-r--r-- | arch/s390/include/asm/io.h | 5 | ||||
| -rw-r--r-- | arch/s390/include/asm/irq.h | 78 | ||||
| -rw-r--r-- | arch/s390/include/asm/pgtable.h | 17 | ||||
| -rw-r--r-- | arch/s390/include/asm/timex.h | 28 | ||||
| -rw-r--r-- | arch/s390/include/uapi/asm/unistd.h | 3 | ||||
| -rw-r--r-- | arch/s390/kernel/compat_wrapper.S | 6 | ||||
| -rw-r--r-- | arch/s390/kernel/debug.c | 11 | ||||
| -rw-r--r-- | arch/s390/kernel/irq.c | 124 | ||||
| -rw-r--r-- | arch/s390/kernel/nmi.c | 2 | ||||
| -rw-r--r-- | arch/s390/kernel/perf_cpum_cf.c | 2 | ||||
| -rw-r--r-- | arch/s390/kernel/runtime_instr.c | 2 | ||||
| -rw-r--r-- | arch/s390/kernel/setup.c | 3 | ||||
| -rw-r--r-- | arch/s390/kernel/smp.c | 11 | ||||
| -rw-r--r-- | arch/s390/kernel/syscalls.S | 1 | ||||
| -rw-r--r-- | arch/s390/kernel/time.c | 9 | ||||
| -rw-r--r-- | arch/s390/kernel/topology.c | 2 | ||||
| -rw-r--r-- | arch/s390/kernel/vtime.c | 6 | ||||
| -rw-r--r-- | arch/s390/kvm/interrupt.c | 2 | ||||
| -rw-r--r-- | arch/s390/kvm/kvm-s390.c | 2 | ||||
| -rw-r--r-- | arch/s390/mm/fault.c | 2 | ||||
| -rw-r--r-- | arch/s390/oprofile/hwsampler.c | 2 | ||||
| -rw-r--r-- | arch/s390/pci/pci.c | 35 | ||||
| -rw-r--r-- | arch/s390/pci/pci_dma.c | 2 | 
26 files changed, 223 insertions, 143 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index b5ea38c2564..c15ba7d1be6 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -78,7 +78,6 @@ config S390  	select HAVE_KVM if 64BIT  	select HAVE_ARCH_TRACEHOOK  	select INIT_ALL_POSSIBLE -	select HAVE_IRQ_WORK  	select HAVE_PERF_EVENTS  	select ARCH_HAVE_NMI_SAFE_CMPXCHG  	select HAVE_DEBUG_KMEMLEAK diff --git a/arch/s390/Makefile b/arch/s390/Makefile index 4b8e08b56f4..7e3ce78d429 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile @@ -24,8 +24,8 @@ CHECKFLAGS	+= -D__s390__ -msize-long  else  LD_BFD		:= elf64-s390  LDFLAGS		:= -m elf64_s390 -KBUILD_AFLAGS_MODULE += -fpic -D__PIC__ -KBUILD_CFLAGS_MODULE += -fpic -D__PIC__ +KBUILD_AFLAGS_MODULE += -fPIC +KBUILD_CFLAGS_MODULE += -fPIC  KBUILD_CFLAGS	+= -m64  KBUILD_AFLAGS	+= -m64  UTS_MACHINE	:= s390x diff --git a/arch/s390/include/asm/dma.h b/arch/s390/include/asm/dma.h index de015d85e3e..bb9bdcd2086 100644 --- a/arch/s390/include/asm/dma.h +++ b/arch/s390/include/asm/dma.h @@ -10,4 +10,10 @@   */  #define MAX_DMA_ADDRESS         0x80000000 +#ifdef CONFIG_PCI +extern int isa_dma_bridge_buggy; +#else +#define isa_dma_bridge_buggy	(0) +#endif +  #endif /* _ASM_S390_DMA_H */ diff --git a/arch/s390/include/asm/io.h b/arch/s390/include/asm/io.h index 16c3eb164f4..27cb32185ce 100644 --- a/arch/s390/include/asm/io.h +++ b/arch/s390/include/asm/io.h @@ -85,6 +85,11 @@ static inline void iounmap(volatile void __iomem *addr)  #define __raw_writel	zpci_write_u32  #define __raw_writeq	zpci_write_u64 +#define readb_relaxed	readb +#define readw_relaxed	readw +#define readl_relaxed	readl +#define readq_relaxed	readq +  #endif /* CONFIG_PCI */  #include <asm-generic/io.h> diff --git a/arch/s390/include/asm/irq.h b/arch/s390/include/asm/irq.h index e6972f85d2b..7def77302d6 100644 --- a/arch/s390/include/asm/irq.h +++ b/arch/s390/include/asm/irq.h @@ -2,43 +2,61 @@  #define _ASM_IRQ_H  #include <linux/hardirq.h> +#include <linux/percpu.h> +#include <linux/cache.h>  #include <linux/types.h> -enum interruption_class { +enum interruption_main_class {  	EXTERNAL_INTERRUPT,  	IO_INTERRUPT, -	EXTINT_CLK, -	EXTINT_EXC, -	EXTINT_EMS, -	EXTINT_TMR, -	EXTINT_TLA, -	EXTINT_PFL, -	EXTINT_DSD, -	EXTINT_VRT, -	EXTINT_SCP, -	EXTINT_IUC, -	EXTINT_CMS, -	EXTINT_CMC, -	EXTINT_CMR, -	IOINT_CIO, -	IOINT_QAI, -	IOINT_DAS, -	IOINT_C15, -	IOINT_C70, -	IOINT_TAP, -	IOINT_VMR, -	IOINT_LCS, -	IOINT_CLW, -	IOINT_CTC, -	IOINT_APB, -	IOINT_ADM, -	IOINT_CSC, -	IOINT_PCI, -	IOINT_MSI, +	NR_IRQS +}; + +enum interruption_class { +	IRQEXT_CLK, +	IRQEXT_EXC, +	IRQEXT_EMS, +	IRQEXT_TMR, +	IRQEXT_TLA, +	IRQEXT_PFL, +	IRQEXT_DSD, +	IRQEXT_VRT, +	IRQEXT_SCP, +	IRQEXT_IUC, +	IRQEXT_CMS, +	IRQEXT_CMC, +	IRQEXT_CMR, +	IRQIO_CIO, +	IRQIO_QAI, +	IRQIO_DAS, +	IRQIO_C15, +	IRQIO_C70, +	IRQIO_TAP, +	IRQIO_VMR, +	IRQIO_LCS, +	IRQIO_CLW, +	IRQIO_CTC, +	IRQIO_APB, +	IRQIO_ADM, +	IRQIO_CSC, +	IRQIO_PCI, +	IRQIO_MSI,  	NMI_NMI, -	NR_IRQS, +	CPU_RST, +	NR_ARCH_IRQS  }; +struct irq_stat { +	unsigned int irqs[NR_ARCH_IRQS]; +}; + +DECLARE_PER_CPU_SHARED_ALIGNED(struct irq_stat, irq_stat); + +static __always_inline void inc_irq_stat(enum interruption_class irq) +{ +	__get_cpu_var(irq_stat).irqs[irq]++; +} +  struct ext_code {  	unsigned short subcode;  	unsigned short code; diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index c928dc1938f..098adbb6266 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -1365,6 +1365,18 @@ static inline void pmdp_invalidate(struct vm_area_struct *vma,  	__pmd_idte(address, pmdp);  } +#define __HAVE_ARCH_PMDP_SET_WRPROTECT +static inline void pmdp_set_wrprotect(struct mm_struct *mm, +				      unsigned long address, pmd_t *pmdp) +{ +	pmd_t pmd = *pmdp; + +	if (pmd_write(pmd)) { +		__pmd_idte(address, pmdp); +		set_pmd_at(mm, address, pmdp, pmd_wrprotect(pmd)); +	} +} +  static inline pmd_t mk_pmd_phys(unsigned long physpage, pgprot_t pgprot)  {  	pmd_t __pmd; @@ -1387,10 +1399,7 @@ static inline int has_transparent_hugepage(void)  static inline unsigned long pmd_pfn(pmd_t pmd)  { -	if (pmd_trans_huge(pmd)) -		return pmd_val(pmd) >> HPAGE_SHIFT; -	else -		return pmd_val(pmd) >> PAGE_SHIFT; +	return pmd_val(pmd) >> PAGE_SHIFT;  }  #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ diff --git a/arch/s390/include/asm/timex.h b/arch/s390/include/asm/timex.h index fba4d66788a..4c060bb5b8e 100644 --- a/arch/s390/include/asm/timex.h +++ b/arch/s390/include/asm/timex.h @@ -128,4 +128,32 @@ static inline unsigned long long get_clock_monotonic(void)  	return get_clock_xt() - sched_clock_base_cc;  } +/** + * tod_to_ns - convert a TOD format value to nanoseconds + * @todval: to be converted TOD format value + * Returns: number of nanoseconds that correspond to the TOD format value + * + * Converting a 64 Bit TOD format value to nanoseconds means that the value + * must be divided by 4.096. In order to achieve that we multiply with 125 + * and divide by 512: + * + *    ns = (todval * 125) >> 9; + * + * In order to avoid an overflow with the multiplication we can rewrite this. + * With a split todval == 2^32 * th + tl (th upper 32 bits, tl lower 32 bits) + * we end up with + * + *    ns = ((2^32 * th + tl) * 125 ) >> 9; + * -> ns = (2^23 * th * 125) + ((tl * 125) >> 9); + * + */ +static inline unsigned long long tod_to_ns(unsigned long long todval) +{ +	unsigned long long ns; + +	ns = ((todval >> 32) << 23) * 125; +	ns += ((todval & 0xffffffff) * 125) >> 9; +	return ns; +} +  #endif diff --git a/arch/s390/include/uapi/asm/unistd.h b/arch/s390/include/uapi/asm/unistd.h index 63e6078699f..864f693c237 100644 --- a/arch/s390/include/uapi/asm/unistd.h +++ b/arch/s390/include/uapi/asm/unistd.h @@ -279,7 +279,8 @@  #define __NR_process_vm_writev	341  #define __NR_s390_runtime_instr 342  #define __NR_kcmp		343 -#define NR_syscalls 344 +#define __NR_finit_module	344 +#define NR_syscalls 345  /*    * There are some system calls that are not present on 64 bit, some diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 827e094a2f4..9b9a805656b 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -1659,3 +1659,9 @@ ENTRY(sys_kcmp_wrapper)  	llgfr	%r5,%r5			# unsigned long  	llgfr	%r6,%r6			# unsigned long  	jg	sys_kcmp + +ENTRY(sys_finit_module_wrapper) +	lgfr	%r2,%r2			# int +	llgtr	%r3,%r3			# const char __user * +	lgfr	%r4,%r4			# int +	jg	sys_finit_module diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index ba500d8dc39..4e8215e0d4b 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c @@ -1127,13 +1127,14 @@ debug_register_view(debug_info_t * id, struct debug_view *view)  	if (i == DEBUG_MAX_VIEWS) {  		pr_err("Registering view %s/%s would exceed the maximum "  		       "number of views %i\n", id->name, view->name, i); -		debugfs_remove(pde);  		rc = -1;  	} else {  		id->views[i] = view;  		id->debugfs_entries[i] = pde;  	}  	spin_unlock_irqrestore(&id->lock, flags); +	if (rc) +		debugfs_remove(pde);  out:  	return rc;  } @@ -1146,9 +1147,9 @@ EXPORT_SYMBOL(debug_register_view);  int  debug_unregister_view(debug_info_t * id, struct debug_view *view)  { -	int rc = 0; -	int i; +	struct dentry *dentry = NULL;  	unsigned long flags; +	int i, rc = 0;  	if (!id)  		goto out; @@ -1160,10 +1161,12 @@ debug_unregister_view(debug_info_t * id, struct debug_view *view)  	if (i == DEBUG_MAX_VIEWS)  		rc = -1;  	else { -		debugfs_remove(id->debugfs_entries[i]); +		dentry = id->debugfs_entries[i];  		id->views[i] = NULL; +		id->debugfs_entries[i] = NULL;  	}  	spin_unlock_irqrestore(&id->lock, flags); +	debugfs_remove(dentry);  out:  	return rc;  } diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index bf24293970c..9df824ea166 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c @@ -24,43 +24,65 @@  #include <asm/irq.h>  #include "entry.h" +DEFINE_PER_CPU_SHARED_ALIGNED(struct irq_stat, irq_stat); +EXPORT_PER_CPU_SYMBOL_GPL(irq_stat); +  struct irq_class {  	char *name;  	char *desc;  }; -static const struct irq_class intrclass_names[] = { +/* + * The list of "main" irq classes on s390. This is the list of interrrupts + * that appear both in /proc/stat ("intr" line) and /proc/interrupts. + * Historically only external and I/O interrupts have been part of /proc/stat. + * We can't add the split external and I/O sub classes since the first field + * in the "intr" line in /proc/stat is supposed to be the sum of all other + * fields. + * Since the external and I/O interrupt fields are already sums we would end + * up with having a sum which accounts each interrupt twice. + */ +static const struct irq_class irqclass_main_desc[NR_IRQS] = {  	[EXTERNAL_INTERRUPT] = {.name = "EXT"}, -	[IO_INTERRUPT]	     = {.name = "I/O"}, -	[EXTINT_CLK] = {.name = "CLK", .desc = "[EXT] Clock Comparator"}, -	[EXTINT_EXC] = {.name = "EXC", .desc = "[EXT] External Call"}, -	[EXTINT_EMS] = {.name = "EMS", .desc = "[EXT] Emergency Signal"}, -	[EXTINT_TMR] = {.name = "TMR", .desc = "[EXT] CPU Timer"}, -	[EXTINT_TLA] = {.name = "TAL", .desc = "[EXT] Timing Alert"}, -	[EXTINT_PFL] = {.name = "PFL", .desc = "[EXT] Pseudo Page Fault"}, -	[EXTINT_DSD] = {.name = "DSD", .desc = "[EXT] DASD Diag"}, -	[EXTINT_VRT] = {.name = "VRT", .desc = "[EXT] Virtio"}, -	[EXTINT_SCP] = {.name = "SCP", .desc = "[EXT] Service Call"}, -	[EXTINT_IUC] = {.name = "IUC", .desc = "[EXT] IUCV"}, -	[EXTINT_CMS] = {.name = "CMS", .desc = "[EXT] CPU-Measurement: Sampling"}, -	[EXTINT_CMC] = {.name = "CMC", .desc = "[EXT] CPU-Measurement: Counter"}, -	[EXTINT_CMR] = {.name = "CMR", .desc = "[EXT] CPU-Measurement: RI"}, -	[IOINT_CIO]  = {.name = "CIO", .desc = "[I/O] Common I/O Layer Interrupt"}, -	[IOINT_QAI]  = {.name = "QAI", .desc = "[I/O] QDIO Adapter Interrupt"}, -	[IOINT_DAS]  = {.name = "DAS", .desc = "[I/O] DASD"}, -	[IOINT_C15]  = {.name = "C15", .desc = "[I/O] 3215"}, -	[IOINT_C70]  = {.name = "C70", .desc = "[I/O] 3270"}, -	[IOINT_TAP]  = {.name = "TAP", .desc = "[I/O] Tape"}, -	[IOINT_VMR]  = {.name = "VMR", .desc = "[I/O] Unit Record Devices"}, -	[IOINT_LCS]  = {.name = "LCS", .desc = "[I/O] LCS"}, -	[IOINT_CLW]  = {.name = "CLW", .desc = "[I/O] CLAW"}, -	[IOINT_CTC]  = {.name = "CTC", .desc = "[I/O] CTC"}, -	[IOINT_APB]  = {.name = "APB", .desc = "[I/O] AP Bus"}, -	[IOINT_ADM]  = {.name = "ADM", .desc = "[I/O] EADM Subchannel"}, -	[IOINT_CSC]  = {.name = "CSC", .desc = "[I/O] CHSC Subchannel"}, -	[IOINT_PCI]  = {.name = "PCI", .desc = "[I/O] PCI Interrupt" }, -	[IOINT_MSI] =  {.name = "MSI", .desc = "[I/O] MSI Interrupt" }, +	[IO_INTERRUPT]	     = {.name = "I/O"} +}; + +/* + * The list of split external and I/O interrupts that appear only in + * /proc/interrupts. + * In addition this list contains non external / I/O events like NMIs. + */ +static const struct irq_class irqclass_sub_desc[NR_ARCH_IRQS] = { +	[IRQEXT_CLK] = {.name = "CLK", .desc = "[EXT] Clock Comparator"}, +	[IRQEXT_EXC] = {.name = "EXC", .desc = "[EXT] External Call"}, +	[IRQEXT_EMS] = {.name = "EMS", .desc = "[EXT] Emergency Signal"}, +	[IRQEXT_TMR] = {.name = "TMR", .desc = "[EXT] CPU Timer"}, +	[IRQEXT_TLA] = {.name = "TAL", .desc = "[EXT] Timing Alert"}, +	[IRQEXT_PFL] = {.name = "PFL", .desc = "[EXT] Pseudo Page Fault"}, +	[IRQEXT_DSD] = {.name = "DSD", .desc = "[EXT] DASD Diag"}, +	[IRQEXT_VRT] = {.name = "VRT", .desc = "[EXT] Virtio"}, +	[IRQEXT_SCP] = {.name = "SCP", .desc = "[EXT] Service Call"}, +	[IRQEXT_IUC] = {.name = "IUC", .desc = "[EXT] IUCV"}, +	[IRQEXT_CMS] = {.name = "CMS", .desc = "[EXT] CPU-Measurement: Sampling"}, +	[IRQEXT_CMC] = {.name = "CMC", .desc = "[EXT] CPU-Measurement: Counter"}, +	[IRQEXT_CMR] = {.name = "CMR", .desc = "[EXT] CPU-Measurement: RI"}, +	[IRQIO_CIO]  = {.name = "CIO", .desc = "[I/O] Common I/O Layer Interrupt"}, +	[IRQIO_QAI]  = {.name = "QAI", .desc = "[I/O] QDIO Adapter Interrupt"}, +	[IRQIO_DAS]  = {.name = "DAS", .desc = "[I/O] DASD"}, +	[IRQIO_C15]  = {.name = "C15", .desc = "[I/O] 3215"}, +	[IRQIO_C70]  = {.name = "C70", .desc = "[I/O] 3270"}, +	[IRQIO_TAP]  = {.name = "TAP", .desc = "[I/O] Tape"}, +	[IRQIO_VMR]  = {.name = "VMR", .desc = "[I/O] Unit Record Devices"}, +	[IRQIO_LCS]  = {.name = "LCS", .desc = "[I/O] LCS"}, +	[IRQIO_CLW]  = {.name = "CLW", .desc = "[I/O] CLAW"}, +	[IRQIO_CTC]  = {.name = "CTC", .desc = "[I/O] CTC"}, +	[IRQIO_APB]  = {.name = "APB", .desc = "[I/O] AP Bus"}, +	[IRQIO_ADM]  = {.name = "ADM", .desc = "[I/O] EADM Subchannel"}, +	[IRQIO_CSC]  = {.name = "CSC", .desc = "[I/O] CHSC Subchannel"}, +	[IRQIO_PCI]  = {.name = "PCI", .desc = "[I/O] PCI Interrupt" }, +	[IRQIO_MSI]  = {.name = "MSI", .desc = "[I/O] MSI Interrupt" },  	[NMI_NMI]    = {.name = "NMI", .desc = "[NMI] Machine Check"}, +	[CPU_RST]    = {.name = "RST", .desc = "[CPU] CPU Restart"},  };  /* @@ -68,30 +90,34 @@ static const struct irq_class intrclass_names[] = {   */  int show_interrupts(struct seq_file *p, void *v)  { -	int i = *(loff_t *) v, j; +	int irq = *(loff_t *) v; +	int cpu;  	get_online_cpus(); -	if (i == 0) { +	if (irq == 0) {  		seq_puts(p, "           "); -		for_each_online_cpu(j) -			seq_printf(p, "CPU%d       ",j); +		for_each_online_cpu(cpu) +			seq_printf(p, "CPU%d       ", cpu);  		seq_putc(p, '\n');  	} - -	if (i < NR_IRQS) { -		seq_printf(p, "%s: ", intrclass_names[i].name); -#ifndef CONFIG_SMP -		seq_printf(p, "%10u ", kstat_irqs(i)); -#else -		for_each_online_cpu(j) -			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); -#endif -		if (intrclass_names[i].desc) -			seq_printf(p, "  %s", intrclass_names[i].desc); -                seq_putc(p, '\n'); -        } +	if (irq < NR_IRQS) { +		seq_printf(p, "%s: ", irqclass_main_desc[irq].name); +		for_each_online_cpu(cpu) +			seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[irq]); +		seq_putc(p, '\n'); +		goto skip_arch_irqs; +	} +	for (irq = 0; irq < NR_ARCH_IRQS; irq++) { +		seq_printf(p, "%s: ", irqclass_sub_desc[irq].name); +		for_each_online_cpu(cpu) +			seq_printf(p, "%10u ", per_cpu(irq_stat, cpu).irqs[irq]); +		if (irqclass_sub_desc[irq].desc) +			seq_printf(p, "  %s", irqclass_sub_desc[irq].desc); +		seq_putc(p, '\n'); +	} +skip_arch_irqs:  	put_online_cpus(); -        return 0; +	return 0;  }  /* @@ -222,7 +248,7 @@ void __irq_entry do_extint(struct pt_regs *regs, struct ext_code ext_code,  		/* Serve timer interrupts first. */  		clock_comparator_work();  	} -	kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++; +	kstat_incr_irqs_this_cpu(EXTERNAL_INTERRUPT, NULL);  	if (ext_code.code != 0x1004)  		__get_cpu_var(s390_idle).nohz_delay = 1; diff --git a/arch/s390/kernel/nmi.c b/arch/s390/kernel/nmi.c index a6daa5c5cdb..7918fbea36b 100644 --- a/arch/s390/kernel/nmi.c +++ b/arch/s390/kernel/nmi.c @@ -254,7 +254,7 @@ void notrace s390_do_machine_check(struct pt_regs *regs)  	int umode;  	nmi_enter(); -	kstat_cpu(smp_processor_id()).irqs[NMI_NMI]++; +	inc_irq_stat(NMI_NMI);  	mci = (struct mci *) &S390_lowcore.mcck_interruption_code;  	mcck = &__get_cpu_var(cpu_mcck);  	umode = user_mode(regs); diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c index c4e7269d4a0..86ec7447e1f 100644 --- a/arch/s390/kernel/perf_cpum_cf.c +++ b/arch/s390/kernel/perf_cpum_cf.c @@ -229,7 +229,7 @@ static void cpumf_measurement_alert(struct ext_code ext_code,  	if (!(alert & CPU_MF_INT_CF_MASK))  		return; -	kstat_cpu(smp_processor_id()).irqs[EXTINT_CMC]++; +	inc_irq_stat(IRQEXT_CMC);  	cpuhw = &__get_cpu_var(cpu_hw_events);  	/* Measurement alerts are shared and might happen when the PMU diff --git a/arch/s390/kernel/runtime_instr.c b/arch/s390/kernel/runtime_instr.c index 61066f6f71a..077a99389b0 100644 --- a/arch/s390/kernel/runtime_instr.c +++ b/arch/s390/kernel/runtime_instr.c @@ -71,7 +71,7 @@ static void runtime_instr_int_handler(struct ext_code ext_code,  	if (!(param32 & CPU_MF_INT_RI_MASK))  		return; -	kstat_cpu(smp_processor_id()).irqs[EXTINT_CMR]++; +	inc_irq_stat(IRQEXT_CMR);  	if (!current->thread.ri_cb)  		return; diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 2568590973a..a5360de85ec 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -16,7 +16,7 @@  #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt  #include <linux/errno.h> -#include <linux/module.h> +#include <linux/export.h>  #include <linux/sched.h>  #include <linux/kernel.h>  #include <linux/memblock.h> @@ -289,6 +289,7 @@ void machine_power_off(void)   * Dummy power off function.   */  void (*pm_power_off)(void) = machine_power_off; +EXPORT_SYMBOL_GPL(pm_power_off);  static int __init early_parse_mem(char *p)  { diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index ea431e551c6..7433a2f9e5c 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -433,9 +433,9 @@ static void do_ext_call_interrupt(struct ext_code ext_code,  	cpu = smp_processor_id();  	if (ext_code.code == 0x1202) -		kstat_cpu(cpu).irqs[EXTINT_EXC]++; +		inc_irq_stat(IRQEXT_EXC);  	else -		kstat_cpu(cpu).irqs[EXTINT_EMS]++; +		inc_irq_stat(IRQEXT_EMS);  	/*  	 * handle bit signal external calls  	 */ @@ -623,9 +623,9 @@ static struct sclp_cpu_info *smp_get_cpu_info(void)  	return info;  } -static int __devinit smp_add_present_cpu(int cpu); +static int __cpuinit smp_add_present_cpu(int cpu); -static int __devinit __smp_rescan_cpus(struct sclp_cpu_info *info, +static int __cpuinit __smp_rescan_cpus(struct sclp_cpu_info *info,  				       int sysfs_add)  {  	struct pcpu *pcpu; @@ -709,6 +709,7 @@ static void __cpuinit smp_start_secondary(void *cpuvoid)  	pfault_init();  	notify_cpu_starting(smp_processor_id());  	set_cpu_online(smp_processor_id(), true); +	inc_irq_stat(CPU_RST);  	local_irq_enable();  	/* cpu_idle will call schedule for us */  	cpu_idle(); @@ -986,7 +987,7 @@ static int __cpuinit smp_cpu_notify(struct notifier_block *self,  	return notifier_from_errno(err);  } -static int __devinit smp_add_present_cpu(int cpu) +static int __cpuinit smp_add_present_cpu(int cpu)  {  	struct cpu *c = &pcpu_devices[cpu].cpu;  	struct device *s = &c->dev; diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 48174850f3b..6a6c61f94dd 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -352,3 +352,4 @@ SYSCALL(sys_process_vm_readv,sys_process_vm_readv,compat_sys_process_vm_readv_wr  SYSCALL(sys_process_vm_writev,sys_process_vm_writev,compat_sys_process_vm_writev_wrapper)  SYSCALL(sys_ni_syscall,sys_s390_runtime_instr,sys_s390_runtime_instr_wrapper)  SYSCALL(sys_kcmp,sys_kcmp,sys_kcmp_wrapper) +SYSCALL(sys_finit_module,sys_finit_module,sys_finit_module_wrapper) diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 7fcd690d42c..0aa98db8a80 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -63,7 +63,7 @@ static DEFINE_PER_CPU(struct clock_event_device, comparators);   */  unsigned long long notrace __kprobes sched_clock(void)  { -	return (get_clock_monotonic() * 125) >> 9; +	return tod_to_ns(get_clock_monotonic());  }  /* @@ -120,6 +120,9 @@ static int s390_next_ktime(ktime_t expires,  	nsecs = ktime_to_ns(ktime_add(timespec_to_ktime(ts), expires));  	do_div(nsecs, 125);  	S390_lowcore.clock_comparator = sched_clock_base_cc + (nsecs << 9); +	/* Program the maximum value if we have an overflow (== year 2042) */ +	if (unlikely(S390_lowcore.clock_comparator < sched_clock_base_cc)) +		S390_lowcore.clock_comparator = -1ULL;  	set_clock_comparator(S390_lowcore.clock_comparator);  	return 0;  } @@ -168,7 +171,7 @@ static void clock_comparator_interrupt(struct ext_code ext_code,  				       unsigned int param32,  				       unsigned long param64)  { -	kstat_cpu(smp_processor_id()).irqs[EXTINT_CLK]++; +	inc_irq_stat(IRQEXT_CLK);  	if (S390_lowcore.clock_comparator == -1ULL)  		set_clock_comparator(S390_lowcore.clock_comparator);  } @@ -179,7 +182,7 @@ static void stp_timing_alert(struct stp_irq_parm *);  static void timing_alert_interrupt(struct ext_code ext_code,  				   unsigned int param32, unsigned long param64)  { -	kstat_cpu(smp_processor_id()).irqs[EXTINT_TLA]++; +	inc_irq_stat(IRQEXT_TLA);  	if (param32 & 0x00c40000)  		etr_timing_alert((struct etr_irq_parm *) ¶m32);  	if (param32 & 0x00038000) diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c index f1aba87cceb..4b2e3e31700 100644 --- a/arch/s390/kernel/topology.c +++ b/arch/s390/kernel/topology.c @@ -10,6 +10,7 @@  #include <linux/bootmem.h>  #include <linux/cpuset.h>  #include <linux/device.h> +#include <linux/export.h>  #include <linux/kernel.h>  #include <linux/sched.h>  #include <linux/init.h> @@ -42,6 +43,7 @@ static struct mask_info socket_info;  static struct mask_info book_info;  struct cpu_topology_s390 cpu_topology[NR_CPUS]; +EXPORT_SYMBOL_GPL(cpu_topology);  static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu)  { diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index e84b8b68444..ce9cc5aa203 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c @@ -127,7 +127,7 @@ void vtime_account_user(struct task_struct *tsk)   * Update process times based on virtual cpu times stored by entry.S   * to the lowcore fields user_timer, system_timer & steal_clock.   */ -void vtime_account(struct task_struct *tsk) +void vtime_account_irq_enter(struct task_struct *tsk)  {  	struct thread_info *ti = task_thread_info(tsk);  	u64 timer, system; @@ -145,10 +145,10 @@ void vtime_account(struct task_struct *tsk)  	virt_timer_forward(system);  } -EXPORT_SYMBOL_GPL(vtime_account); +EXPORT_SYMBOL_GPL(vtime_account_irq_enter);  void vtime_account_system(struct task_struct *tsk) -__attribute__((alias("vtime_account"))); +__attribute__((alias("vtime_account_irq_enter")));  EXPORT_SYMBOL_GPL(vtime_account_system);  void __kprobes vtime_stop_cpu(void) diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index c30615e605a..82c481ddef7 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -408,7 +408,7 @@ int kvm_s390_handle_wait(struct kvm_vcpu *vcpu)  		return 0;  	} -	sltime = ((vcpu->arch.sie_block->ckc - now)*125)>>9; +	sltime = tod_to_ns(vcpu->arch.sie_block->ckc - now);  	hrtimer_start(&vcpu->arch.ckc_timer, ktime_set (0, sltime) , HRTIMER_MODE_REL);  	VCPU_EVENT(vcpu, 5, "enabled wait via clock comparator: %llx ns", sltime); diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index c9011bfaabb..f090e819bf7 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -613,7 +613,9 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)  		kvm_s390_deliver_pending_interrupts(vcpu);  	vcpu->arch.sie_block->icptcode = 0; +	preempt_disable();  	kvm_guest_enter(); +	preempt_enable();  	VCPU_EVENT(vcpu, 6, "entering sie flags %x",  		   atomic_read(&vcpu->arch.sie_block->cpuflags));  	trace_kvm_s390_sie_enter(vcpu, diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 42601d6e166..2fb9e63b8fc 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -569,7 +569,7 @@ static void pfault_interrupt(struct ext_code ext_code,  	subcode = ext_code.subcode;  	if ((subcode & 0xff00) != __SUBCODE_MASK)  		return; -	kstat_cpu(smp_processor_id()).irqs[EXTINT_PFL]++; +	inc_irq_stat(IRQEXT_PFL);  	/* Get the token (= pid of the affected task). */  	pid = sizeof(void *) == 4 ? param32 : param64;  	rcu_read_lock(); diff --git a/arch/s390/oprofile/hwsampler.c b/arch/s390/oprofile/hwsampler.c index 0cb385da202..b5b2916895e 100644 --- a/arch/s390/oprofile/hwsampler.c +++ b/arch/s390/oprofile/hwsampler.c @@ -233,7 +233,7 @@ static void hws_ext_handler(struct ext_code ext_code,  	if (!(param32 & CPU_MF_INT_SF_MASK))  		return; -	kstat_cpu(smp_processor_id()).irqs[EXTINT_CMS]++; +	inc_irq_stat(IRQEXT_CMS);  	atomic_xchg(&cb->ext_params, atomic_read(&cb->ext_params) | param32);  	if (hws_wq) diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 8fa416b8775..60e0372545d 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -160,35 +160,6 @@ int pci_proc_domain(struct pci_bus *bus)  }  EXPORT_SYMBOL_GPL(pci_proc_domain); -/* Store PCI function information block */ -static int zpci_store_fib(struct zpci_dev *zdev, u8 *fc) -{ -	struct zpci_fib *fib; -	u8 status, cc; - -	fib = (void *) get_zeroed_page(GFP_KERNEL); -	if (!fib) -		return -ENOMEM; - -	do { -		cc = __stpcifc(zdev->fh, 0, fib, &status); -		if (cc == 2) { -			msleep(ZPCI_INSN_BUSY_DELAY); -			memset(fib, 0, PAGE_SIZE); -		} -	} while (cc == 2); - -	if (cc) -		pr_err_once("%s: cc: %u  status: %u\n", -			    __func__, cc, status); - -	/* Return PCI function controls */ -	*fc = fib->fc; - -	free_page((unsigned long) fib); -	return (cc) ? -EIO : 0; -} -  /* Modify PCI: Register adapter interruptions */  static int zpci_register_airq(struct zpci_dev *zdev, unsigned int aisb,  			      u64 aibv) @@ -385,7 +356,7 @@ unsigned int probe_irq_mask(unsigned long val)  }  EXPORT_SYMBOL_GPL(probe_irq_mask); -void __devinit pcibios_fixup_bus(struct pci_bus *bus) +void pcibios_fixup_bus(struct pci_bus *bus)  {  } @@ -469,7 +440,7 @@ static void zpci_irq_handler(void *dont, void *need)  	int rescan = 0, max = aisb_max;  	struct zdev_irq_map *imap; -	kstat_cpu(smp_processor_id()).irqs[IOINT_PCI]++; +	inc_irq_stat(IRQIO_PCI);  	sbit = start;  scan: @@ -481,7 +452,7 @@ scan:  		/* find vector bit */  		imap = bucket->imap[sbit];  		for_each_set_bit_left(mbit, &imap->aibv, imap->msi_vecs) { -			kstat_cpu(smp_processor_id()).irqs[IOINT_MSI]++; +			inc_irq_stat(IRQIO_MSI);  			clear_bit(63 - mbit, &imap->aibv);  			spin_lock(&imap->lock); diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c index 6138468b420..a547419907c 100644 --- a/arch/s390/pci/pci_dma.c +++ b/arch/s390/pci/pci_dma.c @@ -13,8 +13,6 @@  #include <linux/pci.h>  #include <asm/pci_dma.h> -static enum zpci_ioat_dtype zpci_ioat_dt = ZPCI_IOTA_RTTO; -  static struct kmem_cache *dma_region_table_cache;  static struct kmem_cache *dma_page_table_cache;  |