/** * reparent_to_init() - Reparent the calling kernel thread to the init task. * * If a kernel thread is launched as a result of a system call, or if * it ever exits, it should generally reparent itself to init so that * it is correctly cleaned up on exit. * * The various task state such as scheduling policy and priority may have * been inherited from a user process, so we reset them to sane values here. * * NOTE that reparent_to_init() gives the caller full capabilities. */ void reparent_to_init(void) { write_lock_irq(&tasklist_lock); /* Reparent to init */ REMOVE_LINKS(current); current->p_pptr = child_reaper; current->p_opptr = child_reaper; SET_LINKS(current); /* Set the exit signal to SIGCHLD so we signal init on exit */ current->exit_signal = SIGCHLD; current->ptrace = 0; if ((current->policy == SCHED_OTHER) && (task_nice(current) < 0)) set_user_nice(current, 0); /* cpus_allowed? */ /* rt_priority? */ /* signals? */ current->cap_effective = CAP_INIT_EFF_SET; current->cap_inheritable = CAP_INIT_INH_SET; current->cap_permitted = CAP_FULL_SET; current->keep_capabilities = 0; memcpy(current->rlim, init_task.rlim, sizeof(*(current->rlim))); current->user = INIT_USER; write_unlock_irq(&tasklist_lock); }
static void nice_record(struct lttng_ctx_field *field, struct lib_ring_buffer_ctx *ctx, struct lttng_channel *chan) { int nice; nice = task_nice(current); lib_ring_buffer_align_ctx(ctx, lttng_alignof(nice)); chan->ops->event_write(ctx, &nice, sizeof(nice)); }
int gr_handle_chroot_setpriority(struct task_struct *p, const int niceval) { #ifdef CONFIG_GRKERNSEC_CHROOT_NICE if (grsec_enable_chroot_nice && (niceval < task_nice(p)) && proc_is_chrooted(current)) { gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid); return -EACCES; } #endif return 0; }
static int badness(struct task_struct *p) { int points, cpu_time, run_time; if (!p->mm) return 0; /* * The memory size of the process is the basis for the badness. */ points = p->mm->total_vm; /* * CPU time is in seconds and run time is in minutes. There is no * particular reason for this other than that it turned out to work * very well in practice. This is not safe against jiffie wraps * but we don't care _that_ much... */ cpu_time = (p->times.tms_utime + p->times.tms_stime) >> (SHIFT_HZ + 3); run_time = (jiffies - p->start_time) >> (SHIFT_HZ + 10); points /= int_sqrt(cpu_time); points /= int_sqrt(int_sqrt(run_time)); /* * Niced processes are most likely less important, so double * their badness points. */ if (task_nice(p) > 0) points *= 2; /* * Superuser processes are usually more important, so we make it * less likely that we kill those. */ if (cap_t(p->cap_effective) & CAP_TO_MASK(CAP_SYS_ADMIN) || p->uid == 0 || p->euid == 0) points /= 4; /* * We don't want to kill a process with direct hardware access. * Not only could that mess up the hardware, but usually users * tend to only have this flag set on applications they think * of as important. */ if (cap_t(p->cap_effective) & CAP_TO_MASK(CAP_SYS_RAWIO)) points /= 4; #ifdef DEBUG printk(KERN_DEBUG "OOMkill: task %d (%s) got %d points\n", p->pid, p->comm, points); #endif return points; }
void Body (void * arg) { int i ; task_nice (prioridade); prioridade += 2 ; for (i=0; i<10; i++) { printf ("%s %d\n", (char *) arg, i) ; task_yield (); } printf ("%s FIM\n", (char *) arg) ; task_exit (0) ; }
void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk) { const struct cred *tcred; struct timespec uptime, ts; u64 ac_etime; BUILD_BUG_ON(TS_COMM_LEN < TASK_COMM_LEN); do_posix_clock_monotonic_gettime(&uptime); ts = timespec_sub(uptime, tsk->start_time); ac_etime = timespec_to_ns(&ts); do_div(ac_etime, NSEC_PER_USEC); stats->ac_etime = ac_etime; stats->ac_btime = get_seconds() - ts.tv_sec; if (thread_group_leader(tsk)) { stats->ac_exitcode = tsk->exit_code; if (tsk->flags & PF_FORKNOEXEC) stats->ac_flag |= AFORK; } if (tsk->flags & PF_SUPERPRIV) stats->ac_flag |= ASU; if (tsk->flags & PF_DUMPCORE) stats->ac_flag |= ACORE; if (tsk->flags & PF_SIGNALED) stats->ac_flag |= AXSIG; stats->ac_nice = task_nice(tsk); stats->ac_sched = tsk->policy; stats->ac_pid = tsk->pid; rcu_read_lock(); tcred = __task_cred(tsk); stats->ac_uid = tcred->uid; stats->ac_gid = tcred->gid; stats->ac_ppid = pid_alive(tsk) ? rcu_dereference(tsk->real_parent)->tgid : 0; rcu_read_unlock(); stats->ac_utime = cputime_to_msecs(tsk->utime) * USEC_PER_MSEC; stats->ac_stime = cputime_to_msecs(tsk->stime) * USEC_PER_MSEC; stats->ac_utimescaled = cputime_to_msecs(tsk->utimescaled) * USEC_PER_MSEC; stats->ac_stimescaled = cputime_to_msecs(tsk->stimescaled) * USEC_PER_MSEC; stats->ac_minflt = tsk->min_flt; stats->ac_majflt = tsk->maj_flt; strncpy(stats->ac_comm, tsk->comm, sizeof(stats->ac_comm)); }
/* * Account user cpu time to a process. * @p: the process that the cpu time gets accounted to * @cputime: the cpu time spent in user space since the last update */ void account_user_time(struct task_struct *p, u64 cputime) { int index; /* Add user time to process. */ p->utime += cputime; account_group_user_time(p, cputime); index = (task_nice(p) > 0) ? CPUTIME_NICE : CPUTIME_USER; /* Add user time to cpustat. */ task_group_account_field(p, index, cputime); /* Account for user time used */ acct_account_cputime(p); }
/* * Account guest cpu time to a process. * @p: the process that the cpu time gets accounted to * @cputime: the cpu time spent in virtual machine since the last update */ void account_guest_time(struct task_struct *p, u64 cputime) { u64 *cpustat = kcpustat_this_cpu->cpustat; /* Add guest time to process. */ p->utime += cputime; account_group_user_time(p, cputime); p->gtime += cputime; /* Add guest time to cpustat. */ if (task_nice(p) > 0) { cpustat[CPUTIME_NICE] += cputime; cpustat[CPUTIME_GUEST_NICE] += cputime; } else { cpustat[CPUTIME_USER] += cputime; cpustat[CPUTIME_GUEST] += cputime; } }
/* * Ugh. To avoid negative return values, "getpriority()" will * not return the normal nice-value, but a negated value that * has been offset by 20 (ie it returns 40..1 instead of -20..19) * to stay compatible. */ asmlinkage long sys_getpriority(int which, int who) { struct task_struct *p; long retval = -ESRCH; if (which > 2 || which < 0) return -EINVAL; read_lock(&tasklist_lock); for_each_task (p) { long niceval; if (!proc_sel(p, which, who)) continue; niceval = 20 - task_nice(p); if (niceval > retval) retval = niceval; } read_unlock(&tasklist_lock); return retval; }
static long __estimate_accuracy(struct timespec *tv) { long slack; int divfactor = 1000; if (tv->tv_sec < 0) return 0; if (task_nice(current) > 0) divfactor = divfactor / 5; if (tv->tv_sec > MAX_SLACK / (NSEC_PER_SEC/divfactor)) return MAX_SLACK; slack = tv->tv_nsec / divfactor; slack += tv->tv_sec * (NSEC_PER_SEC/divfactor); if (slack > MAX_SLACK) return MAX_SLACK; return slack; }
asmlinkage long sys_setpriority(int which, int who, int niceval) { struct task_struct *p; int error; if (which > 2 || which < 0) return -EINVAL; /* normalize: avoid signed division (rounding problems) */ error = -ESRCH; if (niceval < -20) niceval = -20; if (niceval > 19) niceval = 19; read_lock(&tasklist_lock); for_each_task(p) { if (!proc_sel(p, which, who)) continue; if (p->uid != current->euid && p->uid != current->uid && !capable(CAP_SYS_NICE)) { error = -EPERM; continue; } if (error == -ESRCH) error = 0; if (niceval < task_nice(p) && !capable(CAP_SYS_NICE)) error = -EACCES; else { set_user_nice(p, niceval); } } read_unlock(&tasklist_lock); return error; }
static int set_one_prio(struct task_struct *p, int niceval, int error) { int no_nice; if (p->uid != current->euid && p->euid != current->euid && !capable(CAP_SYS_NICE)) { error = -EPERM; goto out; } if (niceval < task_nice(p) && !can_nice(p, niceval)) { error = -EACCES; goto out; } no_nice = security_task_setnice(p, niceval); if (no_nice) { error = no_nice; goto out; } if (error == -ESRCH) error = 0; set_user_nice(p, niceval); out: return error; }
/* * Actual dumper * * This is a two-pass process; first we find the offsets of the bits, * and then they are actually written out. If we run out of core limit * we just truncate. */ static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file) { int has_dumped = 0; mm_segment_t fs; int segs; size_t size = 0; int i; struct vm_area_struct *vma; struct elfhdr elf; off_t offset = 0, dataoff; unsigned long limit = current->rlim[RLIMIT_CORE].rlim_cur; int numnote = 4; struct memelfnote notes[4]; struct elf_prstatus prstatus; /* NT_PRSTATUS */ elf_fpregset_t fpu; /* NT_PRFPREG */ struct elf_prpsinfo psinfo; /* NT_PRPSINFO */ /* first copy the parameters from user space */ memset(&psinfo, 0, sizeof(psinfo)); { unsigned int i, len; len = current->mm->arg_end - current->mm->arg_start; if (len >= ELF_PRARGSZ) len = ELF_PRARGSZ-1; copy_from_user(&psinfo.pr_psargs, (const char *)current->mm->arg_start, len); for(i = 0; i < len; i++) if (psinfo.pr_psargs[i] == 0) psinfo.pr_psargs[i] = ' '; psinfo.pr_psargs[len] = 0; } memset(&prstatus, 0, sizeof(prstatus)); /* * This transfers the registers from regs into the standard * coredump arrangement, whatever that is. */ #ifdef ELF_CORE_COPY_REGS ELF_CORE_COPY_REGS(prstatus.pr_reg, regs) #else if (sizeof(elf_gregset_t) != sizeof(struct pt_regs)) { printk("sizeof(elf_gregset_t) (%ld) != sizeof(struct pt_regs) (%ld)\n", (long)sizeof(elf_gregset_t), (long)sizeof(struct pt_regs)); } else *(struct pt_regs *)&prstatus.pr_reg = *regs; #endif /* now stop all vm operations */ down_write(¤t->mm->mmap_sem); segs = current->mm->map_count; #ifdef DEBUG printk("elf_core_dump: %d segs %lu limit\n", segs, limit); #endif /* Set up header */ memcpy(elf.e_ident, ELFMAG, SELFMAG); elf.e_ident[EI_CLASS] = ELF_CLASS; elf.e_ident[EI_DATA] = ELF_DATA; elf.e_ident[EI_VERSION] = EV_CURRENT; memset(elf.e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD); elf.e_type = ET_CORE; elf.e_machine = ELF_ARCH; elf.e_version = EV_CURRENT; elf.e_entry = 0; elf.e_phoff = sizeof(elf); elf.e_shoff = 0; #ifdef ELF_CORE_EFLAGS elf.e_flags = ELF_CORE_EFLAGS; #else elf.e_flags = 0; #endif elf.e_ehsize = sizeof(elf); elf.e_phentsize = sizeof(struct elf_phdr); elf.e_phnum = segs+1; /* Include notes */ elf.e_shentsize = 0; elf.e_shnum = 0; elf.e_shstrndx = 0; fs = get_fs(); set_fs(KERNEL_DS); has_dumped = 1; current->flags |= PF_DUMPCORE; DUMP_WRITE(&elf, sizeof(elf)); offset += sizeof(elf); /* Elf header */ offset += (segs+1) * sizeof(struct elf_phdr); /* Program headers */ /* * Set up the notes in similar form to SVR4 core dumps made * with info from their /proc. */ notes[0].name = "CORE"; notes[0].type = NT_PRSTATUS; notes[0].datasz = sizeof(prstatus); notes[0].data = &prstatus; prstatus.pr_info.si_signo = prstatus.pr_cursig = signr; prstatus.pr_sigpend = current->pending.signal.sig[0]; prstatus.pr_sighold = current->blocked.sig[0]; psinfo.pr_pid = prstatus.pr_pid = current->pid; psinfo.pr_ppid = prstatus.pr_ppid = current->p_pptr->pid; psinfo.pr_pgrp = prstatus.pr_pgrp = current->pgrp; psinfo.pr_sid = prstatus.pr_sid = current->session; prstatus.pr_utime.tv_sec = CT_TO_SECS(current->times.tms_utime); prstatus.pr_utime.tv_usec = CT_TO_USECS(current->times.tms_utime); prstatus.pr_stime.tv_sec = CT_TO_SECS(current->times.tms_stime); prstatus.pr_stime.tv_usec = CT_TO_USECS(current->times.tms_stime); prstatus.pr_cutime.tv_sec = CT_TO_SECS(current->times.tms_cutime); prstatus.pr_cutime.tv_usec = CT_TO_USECS(current->times.tms_cutime); prstatus.pr_cstime.tv_sec = CT_TO_SECS(current->times.tms_cstime); prstatus.pr_cstime.tv_usec = CT_TO_USECS(current->times.tms_cstime); #ifdef DEBUG dump_regs("Passed in regs", (elf_greg_t *)regs); dump_regs("prstatus regs", (elf_greg_t *)&prstatus.pr_reg); #endif notes[1].name = "CORE"; notes[1].type = NT_PRPSINFO; notes[1].datasz = sizeof(psinfo); notes[1].data = &psinfo; i = current->state ? ffz(~current->state) + 1 : 0; psinfo.pr_state = i; psinfo.pr_sname = (i < 0 || i > 5) ? '.' : "RSDZTD"[i]; psinfo.pr_zomb = psinfo.pr_sname == 'Z'; psinfo.pr_nice = task_nice(current); psinfo.pr_flag = current->flags; psinfo.pr_uid = NEW_TO_OLD_UID(current->uid); psinfo.pr_gid = NEW_TO_OLD_GID(current->gid); strncpy(psinfo.pr_fname, current->comm, sizeof(psinfo.pr_fname)); notes[2].name = "CORE"; notes[2].type = NT_TASKSTRUCT; notes[2].datasz = sizeof(*current); notes[2].data = current; /* Try to dump the FPU. */ prstatus.pr_fpvalid = dump_fpu (regs, &fpu); if (!prstatus.pr_fpvalid) { numnote--; } else { notes[3].name = "CORE"; notes[3].type = NT_PRFPREG; notes[3].datasz = sizeof(fpu); notes[3].data = &fpu; } /* Write notes phdr entry */ { struct elf_phdr phdr; int sz = 0; for(i = 0; i < numnote; i++) sz += notesize(¬es[i]); phdr.p_type = PT_NOTE; phdr.p_offset = offset; phdr.p_vaddr = 0; phdr.p_paddr = 0; phdr.p_filesz = sz; phdr.p_memsz = 0; phdr.p_flags = 0; phdr.p_align = 0; offset += phdr.p_filesz; DUMP_WRITE(&phdr, sizeof(phdr)); } /* Page-align dumped data */ dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE); /* Write program headers for segments dump */ for(vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) { struct elf_phdr phdr; size_t sz; sz = vma->vm_end - vma->vm_start; phdr.p_type = PT_LOAD; phdr.p_offset = offset; phdr.p_vaddr = vma->vm_start; phdr.p_paddr = 0; phdr.p_filesz = maydump(vma) ? sz : 0; phdr.p_memsz = sz; offset += phdr.p_filesz; phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0; if (vma->vm_flags & VM_WRITE) phdr.p_flags |= PF_W; if (vma->vm_flags & VM_EXEC) phdr.p_flags |= PF_X; phdr.p_align = ELF_EXEC_PAGESIZE; DUMP_WRITE(&phdr, sizeof(phdr)); } for(i = 0; i < numnote; i++) if (!writenote(¬es[i], file)) goto end_coredump; DUMP_SEEK(dataoff); for(vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) { unsigned long addr; if (!maydump(vma)) continue; #ifdef DEBUG printk("elf_core_dump: writing %08lx-%08lx\n", vma->vm_start, vma->vm_end); #endif for (addr = vma->vm_start; addr < vma->vm_end; addr += PAGE_SIZE) { struct page* page; struct vm_area_struct *vma; if (get_user_pages(current, current->mm, addr, 1, 0, 1, &page, &vma) <= 0) { DUMP_SEEK (file->f_pos + PAGE_SIZE); } else { if (page == ZERO_PAGE(addr)) { DUMP_SEEK (file->f_pos + PAGE_SIZE); } else { void *kaddr; flush_cache_page(vma, addr); kaddr = kmap(page); DUMP_WRITE(kaddr, PAGE_SIZE); flush_page_to_ram(page); kunmap(page); } put_page(page); } } } if ((off_t) file->f_pos != offset) { /* Sanity check */ printk("elf_core_dump: file->f_pos (%ld) != offset (%ld)\n", (off_t) file->f_pos, offset); } end_coredump: set_fs(fs); up_write(¤t->mm->mmap_sem); return has_dumped; }
/* Actual dumper. * * This is a two-pass process; first we find the offsets of the bits, * and then they are actually written out. If we run out of core limit * we just truncate. */ static int irix_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit) { int has_dumped = 0; mm_segment_t fs; int segs; int i; size_t size; struct vm_area_struct *vma; struct elfhdr elf; off_t offset = 0, dataoff; int numnote = 3; struct memelfnote notes[3]; struct elf_prstatus prstatus; /* NT_PRSTATUS */ elf_fpregset_t fpu; /* NT_PRFPREG */ struct elf_prpsinfo psinfo; /* NT_PRPSINFO */ /* Count what's needed to dump, up to the limit of coredump size. */ segs = 0; size = 0; for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) { if (maydump(vma)) { int sz = vma->vm_end-vma->vm_start; if (size+sz >= limit) break; else size += sz; } segs++; } pr_debug("irix_core_dump: %d segs taking %d bytes\n", segs, size); /* Set up header. */ memcpy(elf.e_ident, ELFMAG, SELFMAG); elf.e_ident[EI_CLASS] = ELFCLASS32; elf.e_ident[EI_DATA] = ELFDATA2LSB; elf.e_ident[EI_VERSION] = EV_CURRENT; elf.e_ident[EI_OSABI] = ELF_OSABI; memset(elf.e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD); elf.e_type = ET_CORE; elf.e_machine = ELF_ARCH; elf.e_version = EV_CURRENT; elf.e_entry = 0; elf.e_phoff = sizeof(elf); elf.e_shoff = 0; elf.e_flags = 0; elf.e_ehsize = sizeof(elf); elf.e_phentsize = sizeof(struct elf_phdr); elf.e_phnum = segs+1; /* Include notes. */ elf.e_shentsize = 0; elf.e_shnum = 0; elf.e_shstrndx = 0; fs = get_fs(); set_fs(KERNEL_DS); has_dumped = 1; current->flags |= PF_DUMPCORE; DUMP_WRITE(&elf, sizeof(elf)); offset += sizeof(elf); /* Elf header. */ offset += (segs+1) * sizeof(struct elf_phdr); /* Program headers. */ /* Set up the notes in similar form to SVR4 core dumps made * with info from their /proc. */ memset(&psinfo, 0, sizeof(psinfo)); memset(&prstatus, 0, sizeof(prstatus)); notes[0].name = "CORE"; notes[0].type = NT_PRSTATUS; notes[0].datasz = sizeof(prstatus); notes[0].data = &prstatus; prstatus.pr_info.si_signo = prstatus.pr_cursig = signr; prstatus.pr_sigpend = current->pending.signal.sig[0]; prstatus.pr_sighold = current->blocked.sig[0]; psinfo.pr_pid = prstatus.pr_pid = task_pid_vnr(current); psinfo.pr_ppid = prstatus.pr_ppid = task_pid_vnr(current->parent); psinfo.pr_pgrp = prstatus.pr_pgrp = task_pgrp_vnr(current); psinfo.pr_sid = prstatus.pr_sid = task_session_vnr(current); if (thread_group_leader(current)) { /* * This is the record for the group leader. Add in the * cumulative times of previous dead threads. This total * won't include the time of each live thread whose state * is included in the core dump. The final total reported * to our parent process when it calls wait4 will include * those sums as well as the little bit more time it takes * this and each other thread to finish dying after the * core dump synchronization phase. */ jiffies_to_timeval(current->utime + current->signal->utime, &prstatus.pr_utime); jiffies_to_timeval(current->stime + current->signal->stime, &prstatus.pr_stime); } else { jiffies_to_timeval(current->utime, &prstatus.pr_utime); jiffies_to_timeval(current->stime, &prstatus.pr_stime); } jiffies_to_timeval(current->signal->cutime, &prstatus.pr_cutime); jiffies_to_timeval(current->signal->cstime, &prstatus.pr_cstime); if (sizeof(elf_gregset_t) != sizeof(struct pt_regs)) { printk("sizeof(elf_gregset_t) (%d) != sizeof(struct pt_regs) " "(%d)\n", sizeof(elf_gregset_t), sizeof(struct pt_regs)); } else { *(struct pt_regs *)&prstatus.pr_reg = *regs; } notes[1].name = "CORE"; notes[1].type = NT_PRPSINFO; notes[1].datasz = sizeof(psinfo); notes[1].data = &psinfo; i = current->state ? ffz(~current->state) + 1 : 0; psinfo.pr_state = i; psinfo.pr_sname = (i < 0 || i > 5) ? '.' : "RSDZTD"[i]; psinfo.pr_zomb = psinfo.pr_sname == 'Z'; psinfo.pr_nice = task_nice(current); psinfo.pr_flag = current->flags; psinfo.pr_uid = current->uid; psinfo.pr_gid = current->gid; { int i, len; set_fs(fs); len = current->mm->arg_end - current->mm->arg_start; len = len >= ELF_PRARGSZ ? ELF_PRARGSZ : len; (void *) copy_from_user(&psinfo.pr_psargs, (const char __user *)current->mm->arg_start, len); for (i = 0; i < len; i++) if (psinfo.pr_psargs[i] == 0) psinfo.pr_psargs[i] = ' '; psinfo.pr_psargs[len] = 0; set_fs(KERNEL_DS); } strlcpy(psinfo.pr_fname, current->comm, sizeof(psinfo.pr_fname)); /* Try to dump the FPU. */ prstatus.pr_fpvalid = dump_fpu(regs, &fpu); if (!prstatus.pr_fpvalid) { numnote--; } else { notes[2].name = "CORE"; notes[2].type = NT_PRFPREG; notes[2].datasz = sizeof(fpu); notes[2].data = &fpu; } /* Write notes phdr entry. */ { struct elf_phdr phdr; int sz = 0; for (i = 0; i < numnote; i++) sz += notesize(¬es[i]); phdr.p_type = PT_NOTE; phdr.p_offset = offset; phdr.p_vaddr = 0; phdr.p_paddr = 0; phdr.p_filesz = sz; phdr.p_memsz = 0; phdr.p_flags = 0; phdr.p_align = 0; offset += phdr.p_filesz; DUMP_WRITE(&phdr, sizeof(phdr)); } /* Page-align dumped data. */ dataoff = offset = roundup(offset, PAGE_SIZE); /* Write program headers for segments dump. */ for (vma = current->mm->mmap, i = 0; i < segs && vma != NULL; vma = vma->vm_next) { struct elf_phdr phdr; size_t sz; i++; sz = vma->vm_end - vma->vm_start; phdr.p_type = PT_LOAD; phdr.p_offset = offset; phdr.p_vaddr = vma->vm_start; phdr.p_paddr = 0; phdr.p_filesz = maydump(vma) ? sz : 0; phdr.p_memsz = sz; offset += phdr.p_filesz; phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0; if (vma->vm_flags & VM_WRITE) phdr.p_flags |= PF_W; if (vma->vm_flags & VM_EXEC) phdr.p_flags |= PF_X; phdr.p_align = PAGE_SIZE; DUMP_WRITE(&phdr, sizeof(phdr)); } for (i = 0; i < numnote; i++) if (!writenote(¬es[i], file)) goto end_coredump; set_fs(fs); DUMP_SEEK(dataoff); for (i = 0, vma = current->mm->mmap; i < segs && vma != NULL; vma = vma->vm_next) { unsigned long addr = vma->vm_start; unsigned long len = vma->vm_end - vma->vm_start; if (!maydump(vma)) continue; i++; pr_debug("elf_core_dump: writing %08lx %lx\n", addr, len); DUMP_WRITE((void __user *)addr, len); } if ((off_t) file->f_pos != offset) { /* Sanity check. */ printk("elf_core_dump: file->f_pos (%ld) != offset (%ld)\n", (off_t) file->f_pos, offset); } end_coredump: set_fs(fs); return has_dumped; }
static int mipi_dsi_on(struct platform_device *pdev) { int ret = 0; u32 clk_rate; struct msm_fb_data_type *mfd; struct fb_info *fbi; struct fb_var_screeninfo *var; struct msm_panel_info *pinfo; struct mipi_panel_info *mipi; u32 hbp, hfp, vbp, vfp, hspw, vspw, width, height; u32 ystride, bpp, data; u32 dummy_xres, dummy_yres; u32 tmp; int target_type = 0; int old_nice; pr_debug("%s+:\n", __func__); mfd = platform_get_drvdata(pdev); fbi = mfd->fbi; var = &fbi->var; pinfo = &mfd->panel_info; /* * Now first priority is to turn on LCD quickly for better * user experience. We set current task to higher priority * and restore it after panel is on. */ old_nice = task_nice(current); if (old_nice > -20) set_user_nice(current, -20); if (mipi_dsi_pdata && mipi_dsi_pdata->dsi_power_save) mipi_dsi_pdata->dsi_power_save(1); #if defined(CONFIG_FB_MSM_MIPI_PANEL_POWERON_LP11) /* * Fix for floating state of VDD line in toshiba chip * */ if (mipi_dsi_pdata && mipi_dsi_pdata->dsi_client_power_save) mipi_dsi_pdata->dsi_client_power_save(1); #endif /* CONFIG_FB_MSM_MIPI_PANEL_POWERON_LP11 */ cont_splash_clk_ctrl(0); mipi_dsi_prepare_ahb_clocks(); mipi_dsi_ahb_ctrl(1); clk_rate = mfd->fbi->var.pixclock; clk_rate = min(clk_rate, mfd->panel_info.clk_max); mipi_dsi_phy_ctrl(1); if (mdp_rev == MDP_REV_42 && mipi_dsi_pdata) target_type = mipi_dsi_pdata->target_type; mipi_dsi_phy_init(0, &(mfd->panel_info), target_type); mipi_dsi_clk_enable(); MIPI_OUTP(MIPI_DSI_BASE + 0x114, 1); MIPI_OUTP(MIPI_DSI_BASE + 0x114, 0); hbp = var->left_margin; hfp = var->right_margin; vbp = var->upper_margin; vfp = var->lower_margin; hspw = var->hsync_len; vspw = var->vsync_len; width = mfd->panel_info.xres; height = mfd->panel_info.yres; mipi = &mfd->panel_info.mipi; if (mfd->panel_info.type == MIPI_VIDEO_PANEL) { dummy_xres = mfd->panel_info.lcdc.xres_pad; dummy_yres = mfd->panel_info.lcdc.yres_pad; if (mdp_rev >= MDP_REV_41) { MIPI_OUTP(MIPI_DSI_BASE + 0x20, ((hspw + hbp + width + dummy_xres) << 16 | (hspw + hbp))); MIPI_OUTP(MIPI_DSI_BASE + 0x24, ((vspw + vbp + height + dummy_yres) << 16 | (vspw + vbp))); MIPI_OUTP(MIPI_DSI_BASE + 0x28, (vspw + vbp + height + dummy_yres + vfp - 1) << 16 | (hspw + hbp + width + dummy_xres + hfp - 1)); } else { /* DSI_LAN_SWAP_CTRL */ MIPI_OUTP(MIPI_DSI_BASE + 0x00ac, mipi->dlane_swap); MIPI_OUTP(MIPI_DSI_BASE + 0x20, ((hbp + width + dummy_xres) << 16 | (hbp))); MIPI_OUTP(MIPI_DSI_BASE + 0x24, ((vbp + height + dummy_yres) << 16 | (vbp))); MIPI_OUTP(MIPI_DSI_BASE + 0x28, (vbp + height + dummy_yres + vfp) << 16 | (hbp + width + dummy_xres + hfp)); } MIPI_OUTP(MIPI_DSI_BASE + 0x2c, (hspw << 16)); MIPI_OUTP(MIPI_DSI_BASE + 0x30, 0); MIPI_OUTP(MIPI_DSI_BASE + 0x34, (vspw << 16)); } else { /* command mode */ if (mipi->dst_format == DSI_CMD_DST_FORMAT_RGB888) bpp = 3; else if (mipi->dst_format == DSI_CMD_DST_FORMAT_RGB666) bpp = 3; else if (mipi->dst_format == DSI_CMD_DST_FORMAT_RGB565) bpp = 2; else bpp = 3; /* Default format set to RGB888 */ ystride = width * bpp + 1; /* DSI_COMMAND_MODE_MDP_STREAM_CTRL */ data = (ystride << 16) | (mipi->vc << 8) | DTYPE_DCS_LWRITE; MIPI_OUTP(MIPI_DSI_BASE + 0x5c, data); MIPI_OUTP(MIPI_DSI_BASE + 0x54, data); /* DSI_COMMAND_MODE_MDP_STREAM_TOTAL */ data = height << 16 | width; MIPI_OUTP(MIPI_DSI_BASE + 0x60, data); MIPI_OUTP(MIPI_DSI_BASE + 0x58, data); } mipi_dsi_host_init(mipi); #if defined(CONFIG_FB_MSM_MIPI_PANEL_POWERON_LP11) /* * For TC358764 D2L IC, one of the requirement for power on * is to maintain an LP11 state in data and clock lanes during * power enabling and reset assertion. This change is to * achieve that. * */ if (mipi_dsi_pdata && mipi_dsi_pdata->dsi_client_power_save) { u32 tmp_reg0c, tmp_rega8; mipi_dsi_pdata->dsi_client_reset(); udelay(200); /* backup register values */ tmp_reg0c = MIPI_INP(MIPI_DSI_BASE + 0x000c); tmp_rega8 = MIPI_INP(MIPI_DSI_BASE + 0xA8); /* Clear HS mode assertion and related flags */ MIPI_OUTP(MIPI_DSI_BASE + 0x0c, 0x8000); MIPI_OUTP(MIPI_DSI_BASE + 0xA8, 0x0); wmb(); mdelay(5); /* restore previous values */ MIPI_OUTP(MIPI_DSI_BASE + 0x0c, tmp_reg0c); MIPI_OUTP(MIPI_DSI_BASE + 0xa8, tmp_rega8); wmb(); } #endif /* CONFIG_FB_MSM_MIPI_PANEL_POWERON_LP11 */ #if defined(CONFIG_FB_MSM_MIPI_MAGNA_OLED_VIDEO_WVGA_PT) /* LP11 */ tmp = MIPI_INP(MIPI_DSI_BASE + 0xA8); tmp &= ~(1<<28); MIPI_OUTP(MIPI_DSI_BASE + 0xA8, tmp); wmb(); /* LP11 */ usleep(5000); if (mipi_dsi_pdata && mipi_dsi_pdata->active_reset) mipi_dsi_pdata->active_reset(); /* high */ usleep(10000); #endif if (mipi->force_clk_lane_hs) { tmp = MIPI_INP(MIPI_DSI_BASE + 0xA8); tmp |= (1<<28); MIPI_OUTP(MIPI_DSI_BASE + 0xA8, tmp); wmb(); } if (mdp_rev >= MDP_REV_41) mutex_lock(&mfd->dma->ov_mutex); else down(&mfd->dma->mutex); ret = panel_next_on(pdev); mipi_dsi_op_mode_config(mipi->mode); if (mfd->panel_info.type == MIPI_CMD_PANEL) { if (pinfo->lcd.vsync_enable) { if (pinfo->lcd.hw_vsync_mode && vsync_gpio >= 0) { if (mdp_rev >= MDP_REV_41) { if (gpio_request(vsync_gpio, "MDP_VSYNC") == 0) gpio_direction_input( vsync_gpio); else pr_err("%s: unable to \ request gpio=%d\n", __func__, vsync_gpio); } else if (mdp_rev == MDP_REV_303) { if (!tlmm_settings && gpio_request( vsync_gpio, "MDP_VSYNC") == 0) { ret = gpio_tlmm_config( GPIO_CFG( vsync_gpio, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), GPIO_CFG_ENABLE); if (ret) { pr_err( "%s: unable to config \ tlmm = %d\n", __func__, vsync_gpio); } tlmm_settings = TRUE; gpio_direction_input( vsync_gpio); } else { if (!tlmm_settings) { pr_err( "%s: unable to request \ gpio=%d\n", __func__, vsync_gpio); } } }
static int tzdd_proxy_thread(void *data) { tzdd_dev_t *dev; tee_msg_head_t *tee_msg_send_head = NULL; uint32_t nice; uint32_t res_size = 0; uint32_t msg_flag; uint32_t ret; bool list_ret; bool is_lpm_blocked = false; set_cpus_allowed_ptr(current, cpumask_of(0)); TZDD_DBG("tzdd_proxy_thread on cpu %d\n", smp_processor_id()); nice = task_nice(current); TZDD_DBG("tzdd_proxy_thread: nice = %d\n", nice); dev = (tzdd_dev_t *) data; while (1) { while (tzdd_get_first_req(&tee_msg_send_head)) { TZDD_DBG ("%s: tee_msg_send_head (0x%08x) =\ {magic (%c%c%c%c),\ size (0x%08x)},\ cmd (0x%x)\n",\ __func__, (uint32_t) tee_msg_send_head, tee_msg_send_head->magic[0], tee_msg_send_head->magic[1], tee_msg_send_head->magic[2], tee_msg_send_head->magic[3], tee_msg_send_head->msg_sz, *((uint32_t *) (tee_msg_send_head) + 8)); list_ret = tzdd_del_node_from_req_list(& (tee_msg_send_head-> node)); OSA_ASSERT(list_ret); tzdd_pt_send(tee_msg_send_head); if (false == is_lpm_blocked) { /* block LPM D1P and deeper than D1P */ osa_wait_for_sem(dev->pm_lock, INFINITE); pm_qos_update_request(&(dev->tzdd_lpm_cons), dev->tzdd_lpm); is_lpm_blocked = true; } tee_add_time_record_point("npct"); /* Call IPI to TW */ #ifdef TEE_DEBUG_ENALBE_PROC_FS_LOG g_pre_ipi_num++; #endif tee_cm_smi(CALL_IPI); #ifdef TEE_DEBUG_ENALBE_PROC_FS_LOG g_pst_ipi_num++; #endif tee_add_time_record_point("npbt"); _g_tzdd_send_num++; #ifdef TEE_DEBUG_ENALBE_PROC_FS_LOG g_msg_sent++; #endif } res_size = tee_cm_get_data_size(); while (res_size) { msg_flag = tzdd_pt_recv(); if (msg_flag == TEE_MSG_IGNORE_COUNTER) { /* do nothing */ #ifdef TEE_DEBUG_ENALBE_PROC_FS_LOG g_msg_ignd++; #endif } else { /* TEE_MSG_FAKE && TEE_MSG_NORMAL */ #ifdef TEE_DEBUG_ENALBE_PROC_FS_LOG if (TEE_MSG_NORMAL == msg_flag) g_msg_recv++; else if (TEE_MSG_FAKE == msg_flag) g_msg_fake++; else OSA_ASSERT(0); #endif _g_tzdd_send_num--; } res_size = tee_cm_get_data_size(); } tee_add_time_record_point("nprm"); if (_g_tzdd_send_num) { #ifdef TEE_DEBUG_ENALBE_PROC_FS_LOG g_pre_dmy_num++; #endif tee_cm_smi(0); #ifdef TEE_DEBUG_ENALBE_PROC_FS_LOG g_pst_dmy_num++; #endif } else { /* release D1P LPM constraint */ if (true == is_lpm_blocked) { pm_qos_update_request(&(dev->tzdd_lpm_cons), PM_QOS_CPUIDLE_BLOCK_DEFAULT_VALUE); osa_release_sem(dev->pm_lock); is_lpm_blocked = false; } tee_add_time_record_point("npwa"); ret = osa_wait_for_sem(dev->pt_sem, INFINITE); OSA_ASSERT(!ret); if (true == _g_pt_thread_stop_flag) { TZDD_DBG("tzdd_proxy_thread(),P-break\n"); break; } tee_add_time_record_point("npet"); } }
static int mipi_dsi_on(struct platform_device *pdev) { int ret = 0; u32 clk_rate; struct msm_fb_data_type *mfd; struct fb_info *fbi; struct fb_var_screeninfo *var; struct msm_panel_info *pinfo; struct mipi_panel_info *mipi; u32 hbp, hfp, vbp, vfp, hspw, vspw, width, height; u32 ystride, bpp, data; u32 dummy_xres, dummy_yres; int target_type = 0; int old_nice; mfd = platform_get_drvdata(pdev); fbi = mfd->fbi; var = &fbi->var; pinfo = &mfd->panel_info; /* * Now first priority is to turn on LCD quickly for better * user experience. We set current task to higher priority * and restore it after panel is on. */ old_nice = task_nice(current); if (old_nice > -20) set_user_nice(current, -20); if (mipi_dsi_pdata && mipi_dsi_pdata->dsi_power_save) mipi_dsi_pdata->dsi_power_save(1); cont_splash_clk_ctrl(); mipi_dsi_ahb_ctrl(1); clk_rate = mfd->fbi->var.pixclock; clk_rate = min(clk_rate, mfd->panel_info.clk_max); mipi = &mfd->panel_info.mipi; /* Clean up the force clk lane to enter HS from previous boot */ if ((mfd->panel_info.type == MIPI_VIDEO_PANEL) && mipi->force_clk_lane_hs) MIPI_OUTP(MIPI_DSI_BASE + 0x00a8, 0); mipi_dsi_phy_ctrl(1); if (mdp_rev == MDP_REV_42 && mipi_dsi_pdata) target_type = mipi_dsi_pdata->target_type; mipi_dsi_phy_init(0, &(mfd->panel_info), target_type); mipi_dsi_clk_enable(); MIPI_OUTP(MIPI_DSI_BASE + 0x114, 1); MIPI_OUTP(MIPI_DSI_BASE + 0x114, 0); hbp = var->left_margin; hfp = var->right_margin; vbp = var->upper_margin; vfp = var->lower_margin; hspw = var->hsync_len; vspw = var->vsync_len; width = mfd->panel_info.xres; height = mfd->panel_info.yres; if (mfd->panel_info.type == MIPI_VIDEO_PANEL) { dummy_xres = mfd->panel_info.mipi.xres_pad; dummy_yres = mfd->panel_info.mipi.yres_pad; if (mdp_rev >= MDP_REV_41) { MIPI_OUTP(MIPI_DSI_BASE + 0x20, ((hspw + hbp + width + dummy_xres) << 16 | (hspw + hbp))); MIPI_OUTP(MIPI_DSI_BASE + 0x24, ((vspw + vbp + height + dummy_yres) << 16 | (vspw + vbp))); MIPI_OUTP(MIPI_DSI_BASE + 0x28, (vspw + vbp + height + dummy_yres + vfp - 1) << 16 | (hspw + hbp + width + dummy_xres + hfp - 1)); } else { /* DSI_LAN_SWAP_CTRL */ MIPI_OUTP(MIPI_DSI_BASE + 0x00ac, mipi->dlane_swap); MIPI_OUTP(MIPI_DSI_BASE + 0x20, ((hbp + width + dummy_xres) << 16 | (hbp))); MIPI_OUTP(MIPI_DSI_BASE + 0x24, ((vbp + height + dummy_yres) << 16 | (vbp))); MIPI_OUTP(MIPI_DSI_BASE + 0x28, (vbp + height + dummy_yres + vfp) << 16 | (hbp + width + dummy_xres + hfp)); } MIPI_OUTP(MIPI_DSI_BASE + 0x2c, (hspw << 16)); MIPI_OUTP(MIPI_DSI_BASE + 0x30, 0); MIPI_OUTP(MIPI_DSI_BASE + 0x34, (vspw << 16)); } else { /* command mode */ if (mipi->dst_format == DSI_CMD_DST_FORMAT_RGB888) bpp = 3; else if (mipi->dst_format == DSI_CMD_DST_FORMAT_RGB666) bpp = 3; else if (mipi->dst_format == DSI_CMD_DST_FORMAT_RGB565) bpp = 2; else bpp = 3; /* Default format set to RGB888 */ ystride = width * bpp + 1; /* DSI_COMMAND_MODE_MDP_STREAM_CTRL */ data = (ystride << 16) | (mipi->vc << 8) | DTYPE_DCS_LWRITE; MIPI_OUTP(MIPI_DSI_BASE + 0x5c, data); MIPI_OUTP(MIPI_DSI_BASE + 0x54, data); /* DSI_COMMAND_MODE_MDP_STREAM_TOTAL */ data = height << 16 | width; MIPI_OUTP(MIPI_DSI_BASE + 0x60, data); MIPI_OUTP(MIPI_DSI_BASE + 0x58, data); } mipi_dsi_host_init(mipi); /* * The MIPI host is done with INIT now, the lines are at LP-11, * and it is safe to turn on the power to the panel and get it out * of reset */ if (mipi_dsi_pdata && mipi_dsi_pdata->panel_power_save) mipi_dsi_pdata->panel_power_save(1); if (mdp_rev >= MDP_REV_41) mutex_lock(&mfd->dma->ov_mutex); else down(&mfd->dma->mutex); if ((mfd->panel_info.type == MIPI_VIDEO_PANEL) && mipi->force_clk_lane_hs) { u32 tmp; tmp = MIPI_INP(MIPI_DSI_BASE + 0xA8); tmp |= (1<<28); MIPI_OUTP(MIPI_DSI_BASE + 0xA8, tmp); wmb(); } ret = panel_next_on(pdev); mipi_dsi_op_mode_config(mipi->mode); if (mfd->panel_info.type == MIPI_CMD_PANEL) { if (pinfo->lcd.vsync_enable) { if (pinfo->lcd.hw_vsync_mode && vsync_gpio >= 0) { if (mdp_rev >= MDP_REV_41) { if (gpio_request(vsync_gpio, "MDP_VSYNC") == 0) gpio_direction_input( vsync_gpio); else pr_err("%s: unable to \ request gpio=%d\n", __func__, vsync_gpio); } else if (mdp_rev == MDP_REV_303) { if (!tlmm_settings && gpio_request( vsync_gpio, "MDP_VSYNC") == 0) { ret = gpio_tlmm_config( GPIO_CFG( vsync_gpio, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), GPIO_CFG_ENABLE); if (ret) { pr_err( "%s: unable to config \ tlmm = %d\n", __func__, vsync_gpio); } tlmm_settings = TRUE; gpio_direction_input( vsync_gpio); } else { if (!tlmm_settings) { pr_err( "%s: unable to request \ gpio=%d\n", __func__, vsync_gpio); } } }