diff options
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r-- | arch/s390/kernel/cache.c | 2 | ||||
-rw-r--r-- | arch/s390/kernel/crash_dump.c | 2 | ||||
-rw-r--r-- | arch/s390/kernel/dumpstack.c | 24 | ||||
-rw-r--r-- | arch/s390/kernel/entry.h | 4 | ||||
-rw-r--r-- | arch/s390/kernel/perf_cpum_cf.c | 9 | ||||
-rw-r--r-- | arch/s390/kernel/perf_cpum_sf.c | 9 | ||||
-rw-r--r-- | arch/s390/kernel/process.c | 24 | ||||
-rw-r--r-- | arch/s390/kernel/processor.c | 16 | ||||
-rw-r--r-- | arch/s390/kernel/setup.c | 17 | ||||
-rw-r--r-- | arch/s390/kernel/vtime.c | 2 |
10 files changed, 75 insertions, 34 deletions
diff --git a/arch/s390/kernel/cache.c b/arch/s390/kernel/cache.c index 8ba32436effe..77a84bd78be2 100644 --- a/arch/s390/kernel/cache.c +++ b/arch/s390/kernel/cache.c @@ -72,7 +72,6 @@ void show_cacheinfo(struct seq_file *m) if (!test_facility(34)) return; - get_online_cpus(); this_cpu_ci = get_cpu_cacheinfo(cpumask_any(cpu_online_mask)); for (idx = 0; idx < this_cpu_ci->num_leaves; idx++) { cache = this_cpu_ci->info_list + idx; @@ -86,7 +85,6 @@ void show_cacheinfo(struct seq_file *m) seq_printf(m, "associativity=%d", cache->ways_of_associativity); seq_puts(m, "\n"); } - put_online_cpus(); } static inline enum cache_type get_cache_type(struct cache_info *ci, int level) diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c index 3986c9f62191..29df8484282b 100644 --- a/arch/s390/kernel/crash_dump.c +++ b/arch/s390/kernel/crash_dump.c @@ -173,7 +173,7 @@ int copy_oldmem_kernel(void *dst, void *src, size_t count) /* * Copy memory of the old, dumped system to a user space virtual address */ -int copy_oldmem_user(void __user *dst, void *src, size_t count) +static int copy_oldmem_user(void __user *dst, void *src, size_t count) { unsigned long from, len; int rc; diff --git a/arch/s390/kernel/dumpstack.c b/arch/s390/kernel/dumpstack.c index 1b6081c0aff9..69f9908ac44c 100644 --- a/arch/s390/kernel/dumpstack.c +++ b/arch/s390/kernel/dumpstack.c @@ -89,6 +89,30 @@ void dump_trace(dump_trace_func_t func, void *data, struct task_struct *task, } EXPORT_SYMBOL_GPL(dump_trace); +struct return_address_data { + unsigned long address; + int depth; +}; + +static int __return_address(void *data, unsigned long address) +{ + struct return_address_data *rd = data; + + if (rd->depth--) + return 0; + rd->address = address; + return 1; +} + +unsigned long return_address(int depth) +{ + struct return_address_data rd = { .depth = depth + 2 }; + + dump_trace(__return_address, &rd, NULL, current_stack_pointer()); + return rd.address; +} +EXPORT_SYMBOL_GPL(return_address); + static int show_address(void *data, unsigned long address) { printk("([<%016lx>] %pSR)\n", address, (void *)address); diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h index b7019ab74070..bedd2f55d860 100644 --- a/arch/s390/kernel/entry.h +++ b/arch/s390/kernel/entry.h @@ -1,6 +1,7 @@ #ifndef _ENTRY_H #define _ENTRY_H +#include <linux/percpu.h> #include <linux/types.h> #include <linux/signal.h> #include <asm/ptrace.h> @@ -75,4 +76,7 @@ long sys_s390_personality(unsigned int personality); long sys_s390_runtime_instr(int command, int signum); long sys_s390_pci_mmio_write(unsigned long, const void __user *, size_t); long sys_s390_pci_mmio_read(unsigned long, void __user *, size_t); + +DECLARE_PER_CPU(u64, mt_cycles[8]); + #endif /* _ENTRY_H */ diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c index 62f066b5259e..59215c518f37 100644 --- a/arch/s390/kernel/perf_cpum_cf.c +++ b/arch/s390/kernel/perf_cpum_cf.c @@ -665,18 +665,21 @@ static struct pmu cpumf_pmu = { static int cpumf_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) { - unsigned int cpu = (long) hcpu; int flags; switch (action & ~CPU_TASKS_FROZEN) { case CPU_ONLINE: case CPU_DOWN_FAILED: flags = PMC_INIT; - smp_call_function_single(cpu, setup_pmc_cpu, &flags, 1); + local_irq_disable(); + setup_pmc_cpu(&flags); + local_irq_enable(); break; case CPU_DOWN_PREPARE: flags = PMC_RELEASE; - smp_call_function_single(cpu, setup_pmc_cpu, &flags, 1); + local_irq_disable(); + setup_pmc_cpu(&flags); + local_irq_enable(); break; default: break; diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c index eaab9a7cb3be..a8e832166417 100644 --- a/arch/s390/kernel/perf_cpum_sf.c +++ b/arch/s390/kernel/perf_cpum_sf.c @@ -1510,7 +1510,6 @@ static void cpumf_measurement_alert(struct ext_code ext_code, static int cpumf_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) { - unsigned int cpu = (long) hcpu; int flags; /* Ignore the notification if no events are scheduled on the PMU. @@ -1523,11 +1522,15 @@ static int cpumf_pmu_notifier(struct notifier_block *self, case CPU_ONLINE: case CPU_DOWN_FAILED: flags = PMC_INIT; - smp_call_function_single(cpu, setup_pmc_cpu, &flags, 1); + local_irq_disable(); + setup_pmc_cpu(&flags); + local_irq_enable(); break; case CPU_DOWN_PREPARE: flags = PMC_RELEASE; - smp_call_function_single(cpu, setup_pmc_cpu, &flags, 1); + local_irq_disable(); + setup_pmc_cpu(&flags); + local_irq_enable(); break; default: break; diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 2bba7df4ac51..481d7a83efc6 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -7,6 +7,7 @@ * Denis Joseph Barrow, */ +#include <linux/elf-randomize.h> #include <linux/compiler.h> #include <linux/cpu.h> #include <linux/sched.h> @@ -37,9 +38,6 @@ asmlinkage void ret_from_fork(void) asm ("ret_from_fork"); -/* FPU save area for the init task */ -__vector128 init_task_fpu_regs[__NUM_VXRS] __init_task_data; - /* * Return saved PC of a blocked thread. used in kernel/sched. * resume in entry.S does not create a new stack frame, it @@ -85,35 +83,19 @@ void release_thread(struct task_struct *dead_task) void arch_release_task_struct(struct task_struct *tsk) { - /* Free either the floating-point or the vector register save area */ - kfree(tsk->thread.fpu.regs); } int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) { - size_t fpu_regs_size; - - *dst = *src; - - /* - * If the vector extension is available, it is enabled for all tasks, - * and, thus, the FPU register save area must be allocated accordingly. - */ - fpu_regs_size = MACHINE_HAS_VX ? sizeof(__vector128) * __NUM_VXRS - : sizeof(freg_t) * __NUM_FPRS; - dst->thread.fpu.regs = kzalloc(fpu_regs_size, GFP_KERNEL|__GFP_REPEAT); - if (!dst->thread.fpu.regs) - return -ENOMEM; - /* * Save the floating-point or vector register state of the current * task and set the CIF_FPU flag to lazy restore the FPU register * state when returning to user space. */ save_fpu_regs(); - dst->thread.fpu.fpc = current->thread.fpu.fpc; - memcpy(dst->thread.fpu.regs, current->thread.fpu.regs, fpu_regs_size); + memcpy(dst, src, arch_task_struct_size); + dst->thread.fpu.regs = dst->thread.fpu.fprs; return 0; } diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c index 647128d5b983..de7451065c34 100644 --- a/arch/s390/kernel/processor.c +++ b/arch/s390/kernel/processor.c @@ -6,6 +6,7 @@ #define KMSG_COMPONENT "cpu" #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#include <linux/cpufeature.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/seq_file.h> @@ -84,7 +85,6 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_puts(m, "\n"); show_cacheinfo(m); } - get_online_cpus(); if (cpu_online(n)) { struct cpuid *id = &per_cpu(cpu_id, n); seq_printf(m, "processor %li: " @@ -93,23 +93,31 @@ static int show_cpuinfo(struct seq_file *m, void *v) "machine = %04X\n", n, id->version, id->ident, id->machine); } - put_online_cpus(); return 0; } +static inline void *c_update(loff_t *pos) +{ + if (*pos) + *pos = cpumask_next(*pos - 1, cpu_online_mask); + return *pos < nr_cpu_ids ? (void *)*pos + 1 : NULL; +} + static void *c_start(struct seq_file *m, loff_t *pos) { - return *pos < nr_cpu_ids ? (void *)((unsigned long) *pos + 1) : NULL; + get_online_cpus(); + return c_update(pos); } static void *c_next(struct seq_file *m, void *v, loff_t *pos) { ++*pos; - return c_start(m, pos); + return c_update(pos); } static void c_stop(struct seq_file *m, void *v) { + put_online_cpus(); } const struct seq_operations cpuinfo_op = { diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index d3f9688f26b5..f31939147ccd 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -809,6 +809,22 @@ static void __init setup_randomness(void) } /* + * Find the correct size for the task_struct. This depends on + * the size of the struct fpu at the end of the thread_struct + * which is embedded in the task_struct. + */ +static void __init setup_task_size(void) +{ + int task_size = sizeof(struct task_struct); + + if (!MACHINE_HAS_VX) { + task_size -= sizeof(__vector128) * __NUM_VXRS; + task_size += sizeof(freg_t) * __NUM_FPRS; + } + arch_task_struct_size = task_size; +} + +/* * Setup function called from init/main.c just after the banner * was printed. */ @@ -846,6 +862,7 @@ void __init setup_arch(char **cmdline_p) os_info_init(); setup_ipl(); + setup_task_size(); /* Do some memory reservations *before* memory is added to memblock */ reserve_memory_end(); diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index dafc44f519c3..856e30d8463f 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c @@ -18,6 +18,8 @@ #include <asm/cpu_mf.h> #include <asm/smp.h> +#include "entry.h" + static void virt_timer_expire(void); static LIST_HEAD(virt_timer_list); |