From 2b67fc46061b2171fb8fbb55d1ac717abd533569 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 5 Feb 2007 21:16:47 +0100 Subject: [S390] Get rid of a lot of sparse warnings. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/smp.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) (limited to 'arch/s390/kernel/smp.c') diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index c0cd255fddbd..3cb7e1032072 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -22,23 +22,23 @@ #include #include - #include #include #include #include - #include #include #include #include - +#include +#include #include #include #include #include #include #include +#include extern volatile int __cpu_logical_map[]; @@ -53,12 +53,6 @@ cpumask_t cpu_possible_map = CPU_MASK_NONE; static struct task_struct *current_set[NR_CPUS]; -/* - * Reboot, halt and power_off routines for SMP. - */ -extern char vmhalt_cmd[]; -extern char vmpoff_cmd[]; - static void smp_ext_bitcall(int, ec_bit_sig); static void smp_ext_bitcall_others(ec_bit_sig); @@ -298,7 +292,7 @@ void machine_power_off_smp(void) * cpus are handled. */ -void do_ext_call_interrupt(__u16 code) +static void do_ext_call_interrupt(__u16 code) { unsigned long bits; @@ -385,7 +379,7 @@ struct ec_creg_mask_parms { /* * callback for setting/clearing control bits */ -void smp_ctl_bit_callback(void *info) { +static void smp_ctl_bit_callback(void *info) { struct ec_creg_mask_parms *pp = info; unsigned long cregs[16]; int i; @@ -458,9 +452,6 @@ __init smp_count_cpus(void) /* * Activate a secondary processor. */ -extern void init_cpu_timer(void); -extern void init_cpu_vtimer(void); - int __devinit start_secondary(void *cpuvoid) { /* Setup the cpu */ -- cgit v1.2.3 From c1821c2e9711adc3cd298a16b7237c92a2cee78d Mon Sep 17 00:00:00 2001 From: Gerald Schaefer Date: Mon, 5 Feb 2007 21:18:17 +0100 Subject: [S390] noexec protection This provides a noexec protection on s390 hardware. Our hardware does not have any bits left in the pte for a hw noexec bit, so this is a different approach using shadow page tables and a special addressing mode that allows separate address spaces for code and data. As a special feature of our "secondary-space" addressing mode, separate page tables can be specified for the translation of data addresses (storage operands) and instruction addresses. The shadow page table is used for the instruction addresses and the standard page table for the data addresses. The shadow page table is linked to the standard page table by a pointer in page->lru.next of the struct page corresponding to the page that contains the standard page table (since page->private is not really private with the pte_lock and the page table pages are not in the LRU list). Depending on the software bits of a pte, it is either inserted into both page tables or just into the standard (data) page table. Pages of a vma that does not have the VM_EXEC bit set get mapped only in the data address space. Any try to execute code on such a page will cause a page translation exception. The standard reaction to this is a SIGSEGV with two exceptions: the two system call opcodes 0x0a77 (sys_sigreturn) and 0x0aad (sys_rt_sigreturn) are allowed. They are stored by the kernel to the signal stack frame. Unfortunately, the signal return mechanism cannot be modified to use an SA_RESTORER because the exception unwinding code depends on the system call opcode stored behind the signal stack frame. This feature requires that user space is executed in secondary-space mode and the kernel in home-space mode, which means that the addressing modes need to be switched and that the noexec protection only works for user space. After switching the addressing modes, we cannot use the mvcp/mvcs instructions anymore to copy between kernel and user space. A new mvcos instruction has been added to the z9 EC/BC hardware which allows to copy between arbitrary address spaces, but on older hardware the page tables need to be walked manually. Signed-off-by: Gerald Schaefer Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/s390/kernel/smp.c') diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 3cb7e1032072..cb155d9fd749 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -244,7 +244,7 @@ static inline void do_wait_for_stop(void) void smp_send_stop(void) { /* Disable all interrupts/machine checks */ - __load_psw_mask(PSW_KERNEL_BITS & ~PSW_MASK_MCHECK); + __load_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK); /* write magic number to zero page (absolute 0) */ lowcore_ptr[smp_processor_id()]->panic_magic = __PANIC_MAGIC; -- cgit v1.2.3 From d54853ef8cb17296ac7bce9c77430fb7c80532d0 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 5 Feb 2007 21:18:19 +0100 Subject: [S390] ETR support. This patch adds support for clock synchronization to an external time reference (ETR). The external time reference sends an oscillator signal and a synchronization signal every 2^20 microseconds to keep the TOD clocks of all connected servers in sync. For availability two ETR units can be connected to a machine. If the clock deviates for more than the sync-check tolerance all cpus get a machine check that indicates that the clock is out of sync. For the lovely details how to get the clock back in sync see the code below. Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/smp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/s390/kernel/smp.c') diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index cb155d9fd749..08f9a4dfb18b 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -457,9 +457,10 @@ int __devinit start_secondary(void *cpuvoid) /* Setup the cpu */ cpu_init(); preempt_disable(); - /* init per CPU timer */ + /* Enable TOD clock interrupts on the secondary cpu. */ init_cpu_timer(); #ifdef CONFIG_VIRT_TIMER + /* Enable cpu timer interrupts on the secondary cpu. */ init_cpu_vtimer(); #endif /* Enable pfault pseudo page faults on this cpu. */ -- cgit v1.2.3 From 4d284cac76d0bfebc42d76b428c4e44d921200a9 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 5 Feb 2007 21:18:53 +0100 Subject: [S390] Avoid excessive inlining. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/smp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch/s390/kernel/smp.c') diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 08f9a4dfb18b..65b52320d145 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -194,7 +194,7 @@ int smp_call_function_on(void (*func) (void *info), void *info, } EXPORT_SYMBOL(smp_call_function_on); -static inline void do_send_stop(void) +static void do_send_stop(void) { int cpu, rc; @@ -208,7 +208,7 @@ static inline void do_send_stop(void) } } -static inline void do_store_status(void) +static void do_store_status(void) { int cpu, rc; @@ -224,7 +224,7 @@ static inline void do_store_status(void) } } -static inline void do_wait_for_stop(void) +static void do_wait_for_stop(void) { int cpu; @@ -534,7 +534,7 @@ smp_put_cpu(int cpu) spin_unlock_irqrestore(&smp_reserve_lock, flags); } -static inline int +static int cpu_stopped(int cpu) { __u32 status; -- cgit v1.2.3 From 0ec67667ab414b18a0518d5b11c842fd342e9cb1 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 12 Feb 2007 15:47:04 +0100 Subject: [S390] smp_call_function/smp_call_function_on locking. smp_call_function and smp_call_function_on share the same lock and smp_call_function_on disables softirq's so it can be called from softirq context as well. Hence smp_call_function muss disable softirqs as well to avoid deadlocks. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/smp.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'arch/s390/kernel/smp.c') diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 65b52320d145..83a4ea6e3d60 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -57,7 +57,7 @@ static void smp_ext_bitcall(int, ec_bit_sig); static void smp_ext_bitcall_others(ec_bit_sig); /* -5B * Structure and data for smp_call_function(). This is designed to minimise + * Structure and data for smp_call_function(). This is designed to minimise * static memory requirements. It also looks cleaner. */ static DEFINE_SPINLOCK(call_lock); @@ -104,7 +104,7 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic, * remote CPUs are nearly ready to execute <> or are or have executed. * * You must not call this function with disabled interrupts or from a - * hardware interrupt handler or from a bottom half handler. + * hardware interrupt handler. */ { struct call_data_struct data; @@ -113,8 +113,8 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic, if (cpus <= 0) return 0; - /* Can deadlock when called with interrupts disabled */ - WARN_ON(irqs_disabled()); + /* Can deadlock when interrupts are disabled or if in wrong context */ + WARN_ON(irqs_disabled() || in_irq()); data.func = func; data.info = info; @@ -123,7 +123,7 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic, if (wait) atomic_set(&data.finished, 0); - spin_lock(&call_lock); + spin_lock_bh(&call_lock); call_data = &data; /* Send a message to all other CPUs and wait for them to respond */ smp_ext_bitcall_others(ec_call_function); @@ -135,7 +135,7 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic, if (wait) while (atomic_read(&data.finished) != cpus) cpu_relax(); - spin_unlock(&call_lock); + spin_unlock_bh(&call_lock); return 0; } @@ -159,6 +159,9 @@ int smp_call_function_on(void (*func) (void *info), void *info, if (!cpu_online(cpu)) return -EINVAL; + /* Can deadlock when interrupts are disabled or if in wrong context */ + WARN_ON(irqs_disabled() || in_irq()); + /* disable preemption for local function call */ curr_cpu = get_cpu(); -- cgit v1.2.3