Make HZ_TO_STD macro name lowercase.
[linux-2.6/linux-mips.git] / kernel / exec_domain.c
blob1daf64cc19b65a70096ca06ffedfdec617fa33c9
1 #include <linux/mm.h>
2 #include <linux/smp_lock.h>
3 #include <linux/module.h>
5 static asmlinkage void no_lcall7(int segment, struct pt_regs * regs);
8 static unsigned long ident_map[32] = {
9 0, 1, 2, 3, 4, 5, 6, 7,
10 8, 9, 10, 11, 12, 13, 14, 15,
11 16, 17, 18, 19, 20, 21, 22, 23,
12 24, 25, 26, 27, 28, 29, 30, 31
15 struct exec_domain default_exec_domain = {
16 "Linux", /* name */
17 no_lcall7, /* lcall7 causes a seg fault. */
18 0, 0xff, /* All personalities. */
19 ident_map, /* Identity map signals. */
20 ident_map, /* - both ways. */
21 NULL, /* No usage counter. */
22 NULL /* Nothing after this in the list. */
25 static struct exec_domain *exec_domains = &default_exec_domain;
26 static rwlock_t exec_domains_lock = RW_LOCK_UNLOCKED;
28 static asmlinkage void no_lcall7(int segment, struct pt_regs * regs)
31 * This may have been a static linked SVr4 binary, so we would have the
32 * personality set incorrectly. Check to see whether SVr4 is available,
33 * and use it, otherwise give the user a SEGV.
35 set_personality(PER_SVR4);
37 if (current->exec_domain && current->exec_domain->handler
38 && current->exec_domain->handler != no_lcall7) {
39 current->exec_domain->handler(segment, regs);
40 return;
43 send_sig(SIGSEGV, current, 1);
46 static struct exec_domain *lookup_exec_domain(unsigned long personality)
48 unsigned long pers = personality & PER_MASK;
49 struct exec_domain *it;
51 read_lock(&exec_domains_lock);
52 for (it=exec_domains; it; it=it->next)
53 if (pers >= it->pers_low && pers <= it->pers_high) {
54 if (!try_inc_mod_count(it->module))
55 continue;
56 read_unlock(&exec_domains_lock);
57 return it;
59 read_unlock(&exec_domains_lock);
61 /* Should never get this far. */
62 printk(KERN_ERR "No execution domain for personality 0x%02lx\n", pers);
63 return NULL;
66 int register_exec_domain(struct exec_domain *it)
68 struct exec_domain *tmp;
70 if (!it)
71 return -EINVAL;
72 if (it->next)
73 return -EBUSY;
74 write_lock(&exec_domains_lock);
75 for (tmp=exec_domains; tmp; tmp=tmp->next)
76 if (tmp == it) {
77 write_unlock(&exec_domains_lock);
78 return -EBUSY;
80 it->next = exec_domains;
81 exec_domains = it;
82 write_unlock(&exec_domains_lock);
83 return 0;
86 int unregister_exec_domain(struct exec_domain *it)
88 struct exec_domain ** tmp;
90 tmp = &exec_domains;
91 write_lock(&exec_domains_lock);
92 while (*tmp) {
93 if (it == *tmp) {
94 *tmp = it->next;
95 it->next = NULL;
96 write_unlock(&exec_domains_lock);
97 return 0;
99 tmp = &(*tmp)->next;
101 write_unlock(&exec_domains_lock);
102 return -EINVAL;
105 void __set_personality(unsigned long personality)
107 struct exec_domain *it, *prev;
109 it = lookup_exec_domain(personality);
110 if (it == current->exec_domain) {
111 current->personality = personality;
112 return;
114 if (!it)
115 return;
116 if (atomic_read(&current->fs->count) != 1) {
117 struct fs_struct *new = copy_fs_struct(current->fs);
118 struct fs_struct *old;
119 if (!new) {
120 put_exec_domain(it);
121 return;
123 task_lock(current);
124 old = current->fs;
125 current->fs = new;
126 task_unlock(current);
127 put_fs_struct(old);
130 * At that point we are guaranteed to be the sole owner of
131 * current->fs.
133 current->personality = personality;
134 prev = current->exec_domain;
135 current->exec_domain = it;
136 set_fs_altroot();
137 put_exec_domain(prev);
140 asmlinkage long sys_personality(unsigned long personality)
142 int ret = current->personality;
143 if (personality != 0xffffffff) {
144 set_personality(personality);
145 if (current->personality != personality)
146 ret = -EINVAL;
148 return ret;
151 int get_exec_domain_list(char * page)
153 int len = 0;
154 struct exec_domain * e;
156 read_lock(&exec_domains_lock);
157 for (e=exec_domains; e && len < PAGE_SIZE - 80; e=e->next)
158 len += sprintf(page+len, "%d-%d\t%-16s\t[%s]\n",
159 e->pers_low, e->pers_high, e->name,
160 e->module ? e->module->name : "kernel");
161 read_unlock(&exec_domains_lock);
162 return len;