aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r--arch/mips/kernel/kspd.c33
-rw-r--r--arch/mips/kernel/rtlx.c15
-rw-r--r--arch/mips/kernel/smp.c14
-rw-r--r--arch/mips/kernel/smtc.c5
-rw-r--r--arch/mips/kernel/vpe.c77
5 files changed, 75 insertions, 69 deletions
diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c
index f2397f00db43..ad4e017ed2f3 100644
--- a/arch/mips/kernel/kspd.c
+++ b/arch/mips/kernel/kspd.c
@@ -172,13 +172,20 @@ static unsigned int translate_open_flags(int flags)
172} 172}
173 173
174 174
175static void sp_setfsuidgid( uid_t uid, gid_t gid) 175static int sp_setfsuidgid(uid_t uid, gid_t gid)
176{ 176{
177 current->cred->fsuid = uid; 177 struct cred *new;
178 current->cred->fsgid = gid;
179 178
180 key_fsuid_changed(current); 179 new = prepare_creds();
181 key_fsgid_changed(current); 180 if (!new)
181 return -ENOMEM;
182
183 new->fsuid = uid;
184 new->fsgid = gid;
185
186 commit_creds(new);
187
188 return 0;
182} 189}
183 190
184/* 191/*
@@ -196,7 +203,7 @@ void sp_work_handle_request(void)
196 mm_segment_t old_fs; 203 mm_segment_t old_fs;
197 struct timeval tv; 204 struct timeval tv;
198 struct timezone tz; 205 struct timezone tz;
199 int cmd; 206 int err, cmd;
200 207
201 char *vcwd; 208 char *vcwd;
202 int size; 209 int size;
@@ -225,8 +232,11 @@ void sp_work_handle_request(void)
225 /* Run the syscall at the privilege of the user who loaded the 232 /* Run the syscall at the privilege of the user who loaded the
226 SP program */ 233 SP program */
227 234
228 if (vpe_getuid(tclimit)) 235 if (vpe_getuid(tclimit)) {
229 sp_setfsuidgid(vpe_getuid(tclimit), vpe_getgid(tclimit)); 236 err = sp_setfsuidgid(vpe_getuid(tclimit), vpe_getgid(tclimit));
237 if (!err)
238 pr_err("Change of creds failed\n");
239 }
230 240
231 switch (sc.cmd) { 241 switch (sc.cmd) {
232 /* needs the flags argument translating from SDE kit to 242 /* needs the flags argument translating from SDE kit to
@@ -283,8 +293,11 @@ void sp_work_handle_request(void)
283 break; 293 break;
284 } /* switch */ 294 } /* switch */
285 295
286 if (vpe_getuid(tclimit)) 296 if (vpe_getuid(tclimit)) {
287 sp_setfsuidgid( 0, 0); 297 err = sp_setfsuidgid(0, 0);
298 if (!err)
299 pr_err("restoring old creds failed\n");
300 }
288 301
289 old_fs = get_fs(); 302 old_fs = get_fs();
290 set_fs(KERNEL_DS); 303 set_fs(KERNEL_DS);
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
index a10ebfdc28ae..364f066cb497 100644
--- a/arch/mips/kernel/rtlx.c
+++ b/arch/mips/kernel/rtlx.c
@@ -72,8 +72,9 @@ static void rtlx_dispatch(void)
72*/ 72*/
73static irqreturn_t rtlx_interrupt(int irq, void *dev_id) 73static irqreturn_t rtlx_interrupt(int irq, void *dev_id)
74{ 74{
75 unsigned int vpeflags;
76 unsigned long flags;
75 int i; 77 int i;
76 unsigned int flags, vpeflags;
77 78
78 /* Ought not to be strictly necessary for SMTC builds */ 79 /* Ought not to be strictly necessary for SMTC builds */
79 local_irq_save(flags); 80 local_irq_save(flags);
@@ -392,20 +393,12 @@ out:
392 393
393static int file_open(struct inode *inode, struct file *filp) 394static int file_open(struct inode *inode, struct file *filp)
394{ 395{
395 int minor = iminor(inode); 396 return rtlx_open(iminor(inode), (filp->f_flags & O_NONBLOCK) ? 0 : 1);
396 int err;
397
398 lock_kernel();
399 err = rtlx_open(minor, (filp->f_flags & O_NONBLOCK) ? 0 : 1);
400 unlock_kernel();
401 return err;
402} 397}
403 398
404static int file_release(struct inode *inode, struct file *filp) 399static int file_release(struct inode *inode, struct file *filp)
405{ 400{
406 int minor = iminor(inode); 401 return rtlx_release(iminor(inode));
407
408 return rtlx_release(minor);
409} 402}
410 403
411static unsigned int file_poll(struct file *file, poll_table * wait) 404static unsigned int file_poll(struct file *file, poll_table * wait)
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 4eb106c6a3ec..e72e6844d134 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -32,7 +32,6 @@
32#include <linux/cpumask.h> 32#include <linux/cpumask.h>
33#include <linux/cpu.h> 33#include <linux/cpu.h>
34#include <linux/err.h> 34#include <linux/err.h>
35#include <linux/smp.h>
36 35
37#include <asm/atomic.h> 36#include <asm/atomic.h>
38#include <asm/cpu.h> 37#include <asm/cpu.h>
@@ -128,19 +127,6 @@ asmlinkage __cpuinit void start_secondary(void)
128 cpu_idle(); 127 cpu_idle();
129} 128}
130 129
131void arch_send_call_function_ipi_mask(const struct cpumask *mask)
132{
133 mp_ops->send_ipi_mask(mask, SMP_CALL_FUNCTION);
134}
135
136/*
137 * We reuse the same vector for the single IPI
138 */
139void arch_send_call_function_single_ipi(int cpu)
140{
141 mp_ops->send_ipi_mask(cpumask_of_cpu(cpu), SMP_CALL_FUNCTION);
142}
143
144/* 130/*
145 * Call into both interrupt handlers, as we share the IPI for them 131 * Call into both interrupt handlers, as we share the IPI for them
146 */ 132 */
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index 67153a0dc267..4d181df44a40 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -1098,9 +1098,8 @@ static void ipi_irq_dispatch(void)
1098 1098
1099static struct irqaction irq_ipi = { 1099static struct irqaction irq_ipi = {
1100 .handler = ipi_interrupt, 1100 .handler = ipi_interrupt,
1101 .flags = IRQF_DISABLED, 1101 .flags = IRQF_DISABLED | IRQF_PERCPU,
1102 .name = "SMTC_IPI", 1102 .name = "SMTC_IPI"
1103 .flags = IRQF_PERCPU
1104}; 1103};
1105 1104
1106static void setup_cross_vpe_interrupts(unsigned int nvpe) 1105static void setup_cross_vpe_interrupts(unsigned int nvpe)
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index eb6c4c5b7fbe..03092ab2a296 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -144,14 +144,15 @@ struct tc {
144}; 144};
145 145
146struct { 146struct {
147 /* Virtual processing elements */ 147 spinlock_t vpe_list_lock;
148 struct list_head vpe_list; 148 struct list_head vpe_list; /* Virtual processing elements */
149 149 spinlock_t tc_list_lock;
150 /* Thread contexts */ 150 struct list_head tc_list; /* Thread contexts */
151 struct list_head tc_list;
152} vpecontrol = { 151} vpecontrol = {
153 .vpe_list = LIST_HEAD_INIT(vpecontrol.vpe_list), 152 .vpe_list_lock = SPIN_LOCK_UNLOCKED,
154 .tc_list = LIST_HEAD_INIT(vpecontrol.tc_list) 153 .vpe_list = LIST_HEAD_INIT(vpecontrol.vpe_list),
154 .tc_list_lock = SPIN_LOCK_UNLOCKED,
155 .tc_list = LIST_HEAD_INIT(vpecontrol.tc_list)
155}; 156};
156 157
157static void release_progmem(void *ptr); 158static void release_progmem(void *ptr);
@@ -159,28 +160,38 @@ static void release_progmem(void *ptr);
159/* get the vpe associated with this minor */ 160/* get the vpe associated with this minor */
160static struct vpe *get_vpe(int minor) 161static struct vpe *get_vpe(int minor)
161{ 162{
162 struct vpe *v; 163 struct vpe *res, *v;
163 164
164 if (!cpu_has_mipsmt) 165 if (!cpu_has_mipsmt)
165 return NULL; 166 return NULL;
166 167
168 res = NULL;
169 spin_lock(&vpecontrol.vpe_list_lock);
167 list_for_each_entry(v, &vpecontrol.vpe_list, list) { 170 list_for_each_entry(v, &vpecontrol.vpe_list, list) {
168 if (v->minor == minor) 171 if (v->minor == minor) {
169 return v; 172 res = v;
173 break;
174 }
170 } 175 }
176 spin_unlock(&vpecontrol.vpe_list_lock);
171 177
172 return NULL; 178 return res;
173} 179}
174 180
175/* get the vpe associated with this minor */ 181/* get the vpe associated with this minor */
176static struct tc *get_tc(int index) 182static struct tc *get_tc(int index)
177{ 183{
178 struct tc *t; 184 struct tc *res, *t;
179 185
186 res = NULL;
187 spin_lock(&vpecontrol.tc_list_lock);
180 list_for_each_entry(t, &vpecontrol.tc_list, list) { 188 list_for_each_entry(t, &vpecontrol.tc_list, list) {
181 if (t->index == index) 189 if (t->index == index) {
182 return t; 190 res = t;
191 break;
192 }
183 } 193 }
194 spin_unlock(&vpecontrol.tc_list_lock);
184 195
185 return NULL; 196 return NULL;
186} 197}
@@ -190,15 +201,17 @@ static struct vpe *alloc_vpe(int minor)
190{ 201{
191 struct vpe *v; 202 struct vpe *v;
192 203
193 if ((v = kzalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL) { 204 if ((v = kzalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL)
194 return NULL; 205 return NULL;
195 }
196 206
197 INIT_LIST_HEAD(&v->tc); 207 INIT_LIST_HEAD(&v->tc);
208 spin_lock(&vpecontrol.vpe_list_lock);
198 list_add_tail(&v->list, &vpecontrol.vpe_list); 209 list_add_tail(&v->list, &vpecontrol.vpe_list);
210 spin_unlock(&vpecontrol.vpe_list_lock);
199 211
200 INIT_LIST_HEAD(&v->notify); 212 INIT_LIST_HEAD(&v->notify);
201 v->minor = minor; 213 v->minor = minor;
214
202 return v; 215 return v;
203} 216}
204 217
@@ -212,7 +225,10 @@ static struct tc *alloc_tc(int index)
212 225
213 INIT_LIST_HEAD(&tc->tc); 226 INIT_LIST_HEAD(&tc->tc);
214 tc->index = index; 227 tc->index = index;
228
229 spin_lock(&vpecontrol.tc_list_lock);
215 list_add_tail(&tc->list, &vpecontrol.tc_list); 230 list_add_tail(&tc->list, &vpecontrol.tc_list);
231 spin_unlock(&vpecontrol.tc_list_lock);
216 232
217out: 233out:
218 return tc; 234 return tc;
@@ -227,7 +243,7 @@ static void release_vpe(struct vpe *v)
227 kfree(v); 243 kfree(v);
228} 244}
229 245
230static void dump_mtregs(void) 246static void __maybe_unused dump_mtregs(void)
231{ 247{
232 unsigned long val; 248 unsigned long val;
233 249
@@ -1048,20 +1064,19 @@ static int vpe_open(struct inode *inode, struct file *filp)
1048 enum vpe_state state; 1064 enum vpe_state state;
1049 struct vpe_notifications *not; 1065 struct vpe_notifications *not;
1050 struct vpe *v; 1066 struct vpe *v;
1051 int ret, err = 0; 1067 int ret;
1052 1068
1053 lock_kernel();
1054 if (minor != iminor(inode)) { 1069 if (minor != iminor(inode)) {
1055 /* assume only 1 device at the moment. */ 1070 /* assume only 1 device at the moment. */
1056 printk(KERN_WARNING "VPE loader: only vpe1 is supported\n"); 1071 pr_warning("VPE loader: only vpe1 is supported\n");
1057 err = -ENODEV; 1072
1058 goto out; 1073 return -ENODEV;
1059 } 1074 }
1060 1075
1061 if ((v = get_vpe(tclimit)) == NULL) { 1076 if ((v = get_vpe(tclimit)) == NULL) {
1062 printk(KERN_WARNING "VPE loader: unable to get vpe\n"); 1077 pr_warning("VPE loader: unable to get vpe\n");
1063 err = -ENODEV; 1078
1064 goto out; 1079 return -ENODEV;
1065 } 1080 }
1066 1081
1067 state = xchg(&v->state, VPE_STATE_INUSE); 1082 state = xchg(&v->state, VPE_STATE_INUSE);
@@ -1101,8 +1116,8 @@ static int vpe_open(struct inode *inode, struct file *filp)
1101 v->shared_ptr = NULL; 1116 v->shared_ptr = NULL;
1102 v->__start = 0; 1117 v->__start = 0;
1103 1118
1104out:
1105 unlock_kernel(); 1119 unlock_kernel();
1120
1106 return 0; 1121 return 0;
1107} 1122}
1108 1123
@@ -1594,14 +1609,14 @@ static void __exit vpe_module_exit(void)
1594{ 1609{
1595 struct vpe *v, *n; 1610 struct vpe *v, *n;
1596 1611
1612 device_del(&vpe_device);
1613 unregister_chrdev(major, module_name);
1614
1615 /* No locking needed here */
1597 list_for_each_entry_safe(v, n, &vpecontrol.vpe_list, list) { 1616 list_for_each_entry_safe(v, n, &vpecontrol.vpe_list, list) {
1598 if (v->state != VPE_STATE_UNUSED) { 1617 if (v->state != VPE_STATE_UNUSED)
1599 release_vpe(v); 1618 release_vpe(v);
1600 }
1601 } 1619 }
1602
1603 device_del(&vpe_device);
1604 unregister_chrdev(major, module_name);
1605} 1620}
1606 1621
1607module_init(vpe_module_init); 1622module_init(vpe_module_init);