diff options
Diffstat (limited to 'arch/ia64')
-rw-r--r-- | arch/ia64/Kconfig | 13 | ||||
-rw-r--r-- | arch/ia64/include/asm/Kbuild | 1 | ||||
-rw-r--r-- | arch/ia64/include/asm/irq_remapping.h | 4 | ||||
-rw-r--r-- | arch/ia64/include/asm/processor.h | 9 | ||||
-rw-r--r-- | arch/ia64/include/asm/thread_info.h | 3 | ||||
-rw-r--r-- | arch/ia64/include/asm/topology.h | 25 | ||||
-rw-r--r-- | arch/ia64/kernel/fsys.S | 191 | ||||
-rw-r--r-- | arch/ia64/kernel/process.c | 20 | ||||
-rw-r--r-- | arch/ia64/kernel/signal.c | 15 | ||||
-rw-r--r-- | arch/ia64/kernel/smpboot.c | 63 | ||||
-rw-r--r-- | arch/ia64/kvm/kvm-ia64.c | 2 |
11 files changed, 32 insertions, 314 deletions
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index bd7266903bf8..8186ec5ea151 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -33,6 +33,12 @@ config IA64 select ARCH_WANT_OPTIONAL_GPIOLIB select ARCH_HAVE_NMI_SAFE_CMPXCHG select GENERIC_IOMAP + select GENERIC_SMP_IDLE_THREAD + select ARCH_INIT_TASK + select ARCH_TASK_STRUCT_ALLOCATOR + select ARCH_THREAD_INFO_ALLOCATOR + select ARCH_CLOCKSOURCE_DATA + select GENERIC_TIME_VSYSCALL default y help The Itanium Processor Family is Intel's 64-bit successor to @@ -88,10 +94,6 @@ config GENERIC_CALIBRATE_DELAY bool default y -config GENERIC_TIME_VSYSCALL - bool - default y - config HAVE_SETUP_PER_CPU_AREA def_bool y @@ -106,9 +108,6 @@ config EFI bool default y -config ARCH_CLOCKSOURCE_DATA - def_bool y - config SCHED_OMIT_FRAME_POINTER bool default y diff --git a/arch/ia64/include/asm/Kbuild b/arch/ia64/include/asm/Kbuild index 241d1c53ba69..d4eb9383f5f6 100644 --- a/arch/ia64/include/asm/Kbuild +++ b/arch/ia64/include/asm/Kbuild @@ -1,6 +1,7 @@ include include/asm-generic/Kbuild.asm header-y += break.h +header-y += cmpxchg.h header-y += fpu.h header-y += gcc_intrin.h header-y += ia64regs.h diff --git a/arch/ia64/include/asm/irq_remapping.h b/arch/ia64/include/asm/irq_remapping.h new file mode 100644 index 000000000000..a8687b1d8906 --- /dev/null +++ b/arch/ia64/include/asm/irq_remapping.h @@ -0,0 +1,4 @@ +#ifndef __IA64_INTR_REMAPPING_H +#define __IA64_INTR_REMAPPING_H +#define irq_remapping_enabled 0 +#endif diff --git a/arch/ia64/include/asm/processor.h b/arch/ia64/include/asm/processor.h index 483f6c6a4238..832dd3789e9d 100644 --- a/arch/ia64/include/asm/processor.h +++ b/arch/ia64/include/asm/processor.h @@ -34,8 +34,7 @@ * each (assuming 8KB page size), for a total of 8TB of user virtual * address space. */ -#define TASK_SIZE_OF(tsk) ((tsk)->thread.task_size) -#define TASK_SIZE TASK_SIZE_OF(current) +#define TASK_SIZE DEFAULT_TASK_SIZE /* * This decides where the kernel will search for a free chunk of vm @@ -280,7 +279,6 @@ struct thread_struct { __u8 pad[3]; __u64 ksp; /* kernel stack pointer */ __u64 map_base; /* base address for get_unmapped_area() */ - __u64 task_size; /* limit for task size */ __u64 rbs_bot; /* the base address for the RBS */ int last_fph_cpu; /* CPU that may hold the contents of f32-f127 */ @@ -303,7 +301,6 @@ struct thread_struct { .ksp = 0, \ .map_base = DEFAULT_MAP_BASE, \ .rbs_bot = STACK_TOP - DEFAULT_USER_STACK_SIZE, \ - .task_size = DEFAULT_TASK_SIZE, \ .last_fph_cpu = -1, \ INIT_THREAD_PM \ .dbr = {0, }, \ @@ -343,9 +340,6 @@ struct task_struct; */ #define release_thread(dead_task) -/* Prepare to copy thread state - unlazy all lazy status */ -#define prepare_to_copy(tsk) do { } while (0) - /* * This is the mechanism for creating a new kernel thread. * @@ -723,7 +717,6 @@ extern unsigned long boot_option_idle_override; enum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_FORCE_MWAIT, IDLE_NOMWAIT, IDLE_POLL}; -void cpu_idle_wait(void); void default_idle(void); #define ia64_platform_is(x) (strcmp(x, platform_name) == 0) diff --git a/arch/ia64/include/asm/thread_info.h b/arch/ia64/include/asm/thread_info.h index e054bcc4273c..310d9734f02d 100644 --- a/arch/ia64/include/asm/thread_info.h +++ b/arch/ia64/include/asm/thread_info.h @@ -54,8 +54,6 @@ struct thread_info { }, \ } -#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR - #ifndef ASM_OFFSETS_C /* how to get the thread information struct from C */ #define current_thread_info() ((struct thread_info *) ((char *) current + IA64_TASK_SIZE)) @@ -84,7 +82,6 @@ struct thread_info { #endif #define end_of_stack(p) (unsigned long *)((void *)(p) + IA64_RBS_OFFSET) -#define __HAVE_ARCH_TASK_STRUCT_ALLOCATOR #define alloc_task_struct_node(node) \ ({ \ struct page *page = alloc_pages_node(node, GFP_KERNEL | __GFP_COMP, \ diff --git a/arch/ia64/include/asm/topology.h b/arch/ia64/include/asm/topology.h index 09f646753d1a..a2496e449b75 100644 --- a/arch/ia64/include/asm/topology.h +++ b/arch/ia64/include/asm/topology.h @@ -70,31 +70,6 @@ void build_cpu_to_node_map(void); .nr_balance_failed = 0, \ } -/* sched_domains SD_NODE_INIT for IA64 NUMA machines */ -#define SD_NODE_INIT (struct sched_domain) { \ - .parent = NULL, \ - .child = NULL, \ - .groups = NULL, \ - .min_interval = 8, \ - .max_interval = 8*(min(num_online_cpus(), 32U)), \ - .busy_factor = 64, \ - .imbalance_pct = 125, \ - .cache_nice_tries = 2, \ - .busy_idx = 3, \ - .idle_idx = 2, \ - .newidle_idx = 0, \ - .wake_idx = 0, \ - .forkexec_idx = 0, \ - .flags = SD_LOAD_BALANCE \ - | SD_BALANCE_NEWIDLE \ - | SD_BALANCE_EXEC \ - | SD_BALANCE_FORK \ - | SD_SERIALIZE, \ - .last_balance = jiffies, \ - .balance_interval = 64, \ - .nr_balance_failed = 0, \ -} - #endif /* CONFIG_NUMA */ #ifdef CONFIG_SMP diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S index cc26edac0ec6..e662f178b990 100644 --- a/arch/ia64/kernel/fsys.S +++ b/arch/ia64/kernel/fsys.S @@ -372,175 +372,6 @@ ENTRY(fsys_clock_gettime) END(fsys_clock_gettime) /* - * long fsys_rt_sigprocmask (int how, sigset_t *set, sigset_t *oset, size_t sigsetsize). - */ -#if _NSIG_WORDS != 1 -# error Sorry, fsys_rt_sigprocmask() needs to be updated for _NSIG_WORDS != 1. -#endif -ENTRY(fsys_rt_sigprocmask) - .prologue - .altrp b6 - .body - - add r2=IA64_TASK_BLOCKED_OFFSET,r16 - add r9=TI_FLAGS+IA64_TASK_SIZE,r16 - cmp4.ltu p6,p0=SIG_SETMASK,r32 - - cmp.ne p15,p0=r0,r34 // oset != NULL? - tnat.nz p8,p0=r34 - add r31=IA64_TASK_SIGHAND_OFFSET,r16 - ;; - ld8 r3=[r2] // read/prefetch current->blocked - ld4 r9=[r9] - tnat.nz.or p6,p0=r35 - - cmp.ne.or p6,p0=_NSIG_WORDS*8,r35 - tnat.nz.or p6,p0=r32 -(p6) br.spnt.few .fail_einval // fail with EINVAL - ;; -#ifdef CONFIG_SMP - ld8 r31=[r31] // r31 <- current->sighand -#endif - and r9=TIF_ALLWORK_MASK,r9 - tnat.nz.or p8,p0=r33 - ;; - cmp.ne p7,p0=0,r9 - cmp.eq p6,p0=r0,r33 // set == NULL? - add r31=IA64_SIGHAND_SIGLOCK_OFFSET,r31 // r31 <- current->sighand->siglock -(p8) br.spnt.few .fail_efault // fail with EFAULT -(p7) br.spnt.many fsys_fallback_syscall // got pending kernel work... -(p6) br.dpnt.many .store_mask // -> short-circuit to just reading the signal mask - - /* Argh, we actually have to do some work and _update_ the signal mask: */ - -EX(.fail_efault, probe.r.fault r33, 3) // verify user has read-access to *set -EX(.fail_efault, ld8 r14=[r33]) // r14 <- *set - mov r17=(1 << (SIGKILL - 1)) | (1 << (SIGSTOP - 1)) - ;; - - RSM_PSR_I(p0, r18, r19) // mask interrupt delivery - andcm r14=r14,r17 // filter out SIGKILL & SIGSTOP - mov r8=EINVAL // default to EINVAL - -#ifdef CONFIG_SMP - // __ticket_spin_trylock(r31) - ld4 r17=[r31] - ;; - mov.m ar.ccv=r17 - extr.u r9=r17,17,15 - adds r19=1,r17 - extr.u r18=r17,0,15 - ;; - cmp.eq p6,p7=r9,r18 - ;; -(p6) cmpxchg4.acq r9=[r31],r19,ar.ccv -(p6) dep.z r20=r19,1,15 // next serving ticket for unlock -(p7) br.cond.spnt.many .lock_contention - ;; - cmp4.eq p0,p7=r9,r17 - adds r31=2,r31 -(p7) br.cond.spnt.many .lock_contention - ld8 r3=[r2] // re-read current->blocked now that we hold the lock - ;; -#else - ld8 r3=[r2] // re-read current->blocked now that we hold the lock -#endif - add r18=IA64_TASK_PENDING_OFFSET+IA64_SIGPENDING_SIGNAL_OFFSET,r16 - add r19=IA64_TASK_SIGNAL_OFFSET,r16 - cmp4.eq p6,p0=SIG_BLOCK,r32 - ;; - ld8 r19=[r19] // r19 <- current->signal - cmp4.eq p7,p0=SIG_UNBLOCK,r32 - cmp4.eq p8,p0=SIG_SETMASK,r32 - ;; - ld8 r18=[r18] // r18 <- current->pending.signal - .pred.rel.mutex p6,p7,p8 -(p6) or r14=r3,r14 // SIG_BLOCK -(p7) andcm r14=r3,r14 // SIG_UNBLOCK - -(p8) mov r14=r14 // SIG_SETMASK -(p6) mov r8=0 // clear error code - // recalc_sigpending() - add r17=IA64_SIGNAL_GROUP_STOP_COUNT_OFFSET,r19 - - add r19=IA64_SIGNAL_SHARED_PENDING_OFFSET+IA64_SIGPENDING_SIGNAL_OFFSET,r19 - ;; - ld4 r17=[r17] // r17 <- current->signal->group_stop_count -(p7) mov r8=0 // clear error code - - ld8 r19=[r19] // r19 <- current->signal->shared_pending - ;; - cmp4.gt p6,p7=r17,r0 // p6/p7 <- (current->signal->group_stop_count > 0)? -(p8) mov r8=0 // clear error code - - or r18=r18,r19 // r18 <- current->pending | current->signal->shared_pending - ;; - // r18 <- (current->pending | current->signal->shared_pending) & ~current->blocked: - andcm r18=r18,r14 - add r9=TI_FLAGS+IA64_TASK_SIZE,r16 - ;; - -(p7) cmp.ne.or.andcm p6,p7=r18,r0 // p6/p7 <- signal pending - mov r19=0 // i must not leak kernel bits... -(p6) br.cond.dpnt.many .sig_pending - ;; - -1: ld4 r17=[r9] // r17 <- current->thread_info->flags - ;; - mov ar.ccv=r17 - and r18=~_TIF_SIGPENDING,r17 // r18 <- r17 & ~(1 << TIF_SIGPENDING) - ;; - - st8 [r2]=r14 // update current->blocked with new mask - cmpxchg4.acq r8=[r9],r18,ar.ccv // current->thread_info->flags <- r18 - ;; - cmp.ne p6,p0=r17,r8 // update failed? -(p6) br.cond.spnt.few 1b // yes -> retry - -#ifdef CONFIG_SMP - // __ticket_spin_unlock(r31) - st2.rel [r31]=r20 - mov r20=0 // i must not leak kernel bits... -#endif - SSM_PSR_I(p0, p9, r31) - ;; - - srlz.d // ensure psr.i is set again - mov r18=0 // i must not leak kernel bits... - -.store_mask: -EX(.fail_efault, (p15) probe.w.fault r34, 3) // verify user has write-access to *oset -EX(.fail_efault, (p15) st8 [r34]=r3) - mov r2=0 // i must not leak kernel bits... - mov r3=0 // i must not leak kernel bits... - mov r8=0 // return 0 - mov r9=0 // i must not leak kernel bits... - mov r14=0 // i must not leak kernel bits... - mov r17=0 // i must not leak kernel bits... - mov r31=0 // i must not leak kernel bits... - FSYS_RETURN - -.sig_pending: -#ifdef CONFIG_SMP - // __ticket_spin_unlock(r31) - st2.rel [r31]=r20 // release the lock -#endif - SSM_PSR_I(p0, p9, r17) - ;; - srlz.d - br.sptk.many fsys_fallback_syscall // with signal pending, do the heavy-weight syscall - -#ifdef CONFIG_SMP -.lock_contention: - /* Rather than spinning here, fall back on doing a heavy-weight syscall. */ - SSM_PSR_I(p0, p9, r17) - ;; - srlz.d - br.sptk.many fsys_fallback_syscall -#endif -END(fsys_rt_sigprocmask) - -/* * fsys_getcpu doesn't use the third parameter in this implementation. It reads * current_thread_info()->cpu and corresponding node in cpu_to_node_map. */ @@ -559,11 +390,15 @@ ENTRY(fsys_getcpu) ;; tnat.nz p7,p0 = r33 // I guard against NaT argument (p7) br.cond.spnt.few .fail_einval // B + ;; + cmp.ne p6,p0=r32,r0 + cmp.ne p7,p0=r33,r0 + ;; #ifdef CONFIG_NUMA movl r17=cpu_to_node_map ;; -EX(.fail_efault, probe.w.fault r32, 3) // M This takes 5 cycles -EX(.fail_efault, probe.w.fault r33, 3) // M This takes 5 cycles +EX(.fail_efault, (p6) probe.w.fault r32, 3) // M This takes 5 cycles +EX(.fail_efault, (p7) probe.w.fault r33, 3) // M This takes 5 cycles shladd r18=r3,1,r17 ;; ld2 r20=[r18] // r20 = cpu_to_node_map[cpu] @@ -573,20 +408,20 @@ EX(.fail_efault, probe.w.fault r33, 3) // M This takes 5 cycles (p8) br.spnt.many fsys_fallback_syscall ;; ;; -EX(.fail_efault, st4 [r32] = r3) -EX(.fail_efault, st2 [r33] = r20) +EX(.fail_efault, (p6) st4 [r32] = r3) +EX(.fail_efault, (p7) st2 [r33] = r20) mov r8=0 ;; #else -EX(.fail_efault, probe.w.fault r32, 3) // M This takes 5 cycles -EX(.fail_efault, probe.w.fault r33, 3) // M This takes 5 cycles +EX(.fail_efault, (p6) probe.w.fault r32, 3) // M This takes 5 cycles +EX(.fail_efault, (p7) probe.w.fault r33, 3) // M This takes 5 cycles and r2 = TIF_ALLWORK_MASK,r2 ;; cmp.ne p8,p0=0,r2 (p8) br.spnt.many fsys_fallback_syscall ;; -EX(.fail_efault, st4 [r32] = r3) -EX(.fail_efault, st2 [r33] = r0) +EX(.fail_efault, (p6) st4 [r32] = r3) +EX(.fail_efault, (p7) st2 [r33] = r0) mov r8=0 ;; #endif @@ -916,7 +751,7 @@ paravirt_fsyscall_table: data8 0 // sigaltstack data8 0 // rt_sigaction data8 0 // rt_sigpending - data8 fsys_rt_sigprocmask // rt_sigprocmask + data8 0 // rt_sigprocmask data8 0 // rt_sigqueueinfo // 1180 data8 0 // rt_sigreturn data8 0 // rt_sigsuspend diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index ce74e143aea3..5e0e86ddb12f 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -273,26 +273,6 @@ static inline void play_dead(void) } #endif /* CONFIG_HOTPLUG_CPU */ -static void do_nothing(void *unused) -{ -} - -/* - * cpu_idle_wait - Used to ensure that all the CPUs discard old value of - * pm_idle and update to new pm_idle value. Required while changing pm_idle - * handler on SMP systems. - * - * Caller must have changed pm_idle to the new value before the call. Old - * pm_idle value will not be used by any CPU after the return of this function. - */ -void cpu_idle_wait(void) -{ - smp_mb(); - /* kick all the CPUs so that they exit out of pm_idle */ - smp_call_function(do_nothing, NULL, 1); -} -EXPORT_SYMBOL_GPL(cpu_idle_wait); - void __attribute__((noreturn)) cpu_idle (void) { diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c index 7bdafc8788bd..7523501d3bc0 100644 --- a/arch/ia64/kernel/signal.c +++ b/arch/ia64/kernel/signal.c @@ -201,13 +201,7 @@ ia64_rt_sigreturn (struct sigscratch *scr) goto give_sigsegv; sigdelsetmask(&set, ~_BLOCKABLE); - - spin_lock_irq(¤t->sighand->siglock); - { - current->blocked = set; - recalc_sigpending(); - } - spin_unlock_irq(¤t->sighand->siglock); + set_current_blocked(&set); if (restore_sigcontext(sc, scr)) goto give_sigsegv; @@ -427,12 +421,7 @@ handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigse if (!setup_frame(sig, ka, info, oldset, scr)) return 0; - spin_lock_irq(¤t->sighand->siglock); - sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); - if (!(ka->sa.sa_flags & SA_NODEFER)) - sigaddset(¤t->blocked, sig); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + block_sigmask(ka, sig); /* * Let tracing know that we've done the handler setup. diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 796f6a5b966a..1113b8aba07f 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c @@ -75,13 +75,6 @@ #endif /* - * Store all idle threads, this can be reused instead of creating - * a new thread. Also avoids complicated thread destroy functionality - * for idle threads. - */ -struct task_struct *idle_thread_array[NR_CPUS]; - -/* * Global array allocated for NR_CPUS at boot time */ struct sal_to_os_boot sal_boot_rendez_state[NR_CPUS]; @@ -94,13 +87,7 @@ struct sal_to_os_boot *sal_state_for_booting_cpu = &sal_boot_rendez_state[0]; #define set_brendez_area(x) (sal_state_for_booting_cpu = &sal_boot_rendez_state[(x)]); -#define get_idle_for_cpu(x) (idle_thread_array[(x)]) -#define set_idle_for_cpu(x,p) (idle_thread_array[(x)] = (p)) - #else - -#define get_idle_for_cpu(x) (NULL) -#define set_idle_for_cpu(x,p) #define set_brendez_area(x) #endif @@ -480,54 +467,12 @@ struct pt_regs * __cpuinit idle_regs(struct pt_regs *regs) return NULL; } -struct create_idle { - struct work_struct work; - struct task_struct *idle; - struct completion done; - int cpu; -}; - -void __cpuinit -do_fork_idle(struct work_struct *work) -{ - struct create_idle *c_idle = - container_of(work, struct create_idle, work); - - c_idle->idle = fork_idle(c_idle->cpu); - complete(&c_idle->done); -} - static int __cpuinit -do_boot_cpu (int sapicid, int cpu) +do_boot_cpu (int sapicid, int cpu, struct task_struct *idle) { int timeout; - struct create_idle c_idle = { - .work = __WORK_INITIALIZER(c_idle.work, do_fork_idle), - .cpu = cpu, - .done = COMPLETION_INITIALIZER(c_idle.done), - }; - - /* - * We can't use kernel_thread since we must avoid to - * reschedule the child. - */ - c_idle.idle = get_idle_for_cpu(cpu); - if (c_idle.idle) { - init_idle(c_idle.idle, cpu); - goto do_rest; - } - - schedule_work(&c_idle.work); - wait_for_completion(&c_idle.done); - - if (IS_ERR(c_idle.idle)) - panic("failed fork for CPU %d", cpu); - - set_idle_for_cpu(cpu, c_idle.idle); - -do_rest: - task_for_booting_cpu = c_idle.idle; + task_for_booting_cpu = idle; Dprintk("Sending wakeup vector %lu to AP 0x%x/0x%x.\n", ap_wakeup_vector, cpu, sapicid); set_brendez_area(cpu); @@ -793,7 +738,7 @@ set_cpu_sibling_map(int cpu) } int __cpuinit -__cpu_up (unsigned int cpu) +__cpu_up(unsigned int cpu, struct task_struct *tidle) { int ret; int sapicid; @@ -811,7 +756,7 @@ __cpu_up (unsigned int cpu) per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; /* Processor goes to start_secondary(), sets online flag */ - ret = do_boot_cpu(sapicid, cpu); + ret = do_boot_cpu(sapicid, cpu, tidle); if (ret < 0) return ret; diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index f5104b7c52cd..463fb3bbe11e 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c @@ -1174,7 +1174,7 @@ out: bool kvm_vcpu_compatible(struct kvm_vcpu *vcpu) { - return irqchip_in_kernel(vcpu->kcm) == (vcpu->arch.apic != NULL); + return irqchip_in_kernel(vcpu->kvm) == (vcpu->arch.apic != NULL); } int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) |