OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [x86_64/] [ia32/] [ipc32.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
#include <linux/kernel.h>
2
#include <linux/sched.h>
3
#include <linux/fs.h> 
4
#include <linux/file.h> 
5
#include <linux/sem.h>
6
#include <linux/msg.h>
7
#include <linux/mm.h>
8
#include <linux/shm.h>
9
#include <linux/slab.h>
10
#include <linux/ipc.h>
11
#include <asm/mman.h>
12
#include <asm/types.h>
13
#include <asm/uaccess.h>
14
#include <asm/semaphore.h>
15
#include <asm/ipc.h>
16
 
17
#include <asm/ia32.h>
18
 
19
extern int sem_ctls[];
20
 
21
/*
22
 * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
23
 *
24
 * This is really horribly ugly.
25
 */
26
 
27
struct msgbuf32 {
28
        s32 mtype;
29
        char mtext[1];
30
};
31
 
32
struct ipc_perm32 {
33
        int key;
34
        __kernel_uid_t32 uid;
35
        __kernel_gid_t32 gid;
36
        __kernel_uid_t32 cuid;
37
        __kernel_gid_t32 cgid;
38
        unsigned short mode;
39
        unsigned short seq;
40
};
41
 
42
struct ipc64_perm32 {
43
        unsigned key;
44
        __kernel_uid32_t32 uid;
45
        __kernel_gid32_t32 gid;
46
        __kernel_uid32_t32 cuid;
47
        __kernel_gid32_t32 cgid;
48
        unsigned short mode;
49
        unsigned short __pad1;
50
        unsigned short seq;
51
        unsigned short __pad2;
52
        unsigned int unused1;
53
        unsigned int unused2;
54
};
55
 
56
struct semid_ds32 {
57
        struct ipc_perm32 sem_perm;               /* permissions .. see ipc.h */
58
        __kernel_time_t32 sem_otime;              /* last semop time */
59
        __kernel_time_t32 sem_ctime;              /* last change time */
60
        u32 sem_base;              /* ptr to first semaphore in array */
61
        u32 sem_pending;          /* pending operations to be processed */
62
        u32 sem_pending_last;    /* last pending operation */
63
        u32 undo;                  /* undo requests on this array */
64
        unsigned short  sem_nsems;              /* no. of semaphores in array */
65
};
66
 
67
struct semid64_ds32 {
68
        struct ipc64_perm32 sem_perm;
69
        __kernel_time_t32 sem_otime;
70
        unsigned int __unused1;
71
        __kernel_time_t32 sem_ctime;
72
        unsigned int __unused2;
73
        unsigned int sem_nsems;
74
        unsigned int __unused3;
75
        unsigned int __unused4;
76
};
77
 
78
struct msqid_ds32 {
79
        struct ipc_perm32 msg_perm;
80
        u32 msg_first;
81
        u32 msg_last;
82
        __kernel_time_t32 msg_stime;
83
        __kernel_time_t32 msg_rtime;
84
        __kernel_time_t32 msg_ctime;
85
        u32 wwait;
86
        u32 rwait;
87
        unsigned short msg_cbytes;
88
        unsigned short msg_qnum;
89
        unsigned short msg_qbytes;
90
        __kernel_ipc_pid_t32 msg_lspid;
91
        __kernel_ipc_pid_t32 msg_lrpid;
92
};
93
 
94
struct msqid64_ds32 {
95
        struct ipc64_perm32 msg_perm;
96
        __kernel_time_t32 msg_stime;
97
        unsigned int __unused1;
98
        __kernel_time_t32 msg_rtime;
99
        unsigned int __unused2;
100
        __kernel_time_t32 msg_ctime;
101
        unsigned int __unused3;
102
        unsigned int msg_cbytes;
103
        unsigned int msg_qnum;
104
        unsigned int msg_qbytes;
105
        __kernel_pid_t32 msg_lspid;
106
        __kernel_pid_t32 msg_lrpid;
107
        unsigned int __unused4;
108
        unsigned int __unused5;
109
};
110
 
111
struct shmid_ds32 {
112
        struct ipc_perm32 shm_perm;
113
        int shm_segsz;
114
        __kernel_time_t32 shm_atime;
115
        __kernel_time_t32 shm_dtime;
116
        __kernel_time_t32 shm_ctime;
117
        __kernel_ipc_pid_t32 shm_cpid;
118
        __kernel_ipc_pid_t32 shm_lpid;
119
        unsigned short shm_nattch;
120
};
121
 
122
struct shmid64_ds32 {
123
        struct ipc64_perm32 shm_perm;
124
        __kernel_size_t32 shm_segsz;
125
        __kernel_time_t32 shm_atime;
126
        unsigned int __unused1;
127
        __kernel_time_t32 shm_dtime;
128
        unsigned int __unused2;
129
        __kernel_time_t32 shm_ctime;
130
        unsigned int __unused3;
131
        __kernel_pid_t32 shm_cpid;
132
        __kernel_pid_t32 shm_lpid;
133
        unsigned int shm_nattch;
134
        unsigned int __unused4;
135
        unsigned int __unused5;
136
};
137
 
138
struct shminfo64_32 {
139
        unsigned int shmmax;
140
        unsigned int shmmin;
141
        unsigned int shmmni;
142
        unsigned int shmseg;
143
        unsigned int shmall;
144
        unsigned int __unused1;
145
        unsigned int __unused2;
146
        unsigned int __unused3;
147
        unsigned int __unused4;
148
};
149
 
150
struct shm_info32 {
151
        int used_ids;
152
        u32 shm_tot, shm_rss, shm_swp;
153
        u32 swap_attempts, swap_successes;
154
};
155
 
156
struct ipc_kludge {
157
        u32 msgp;
158
        s32 msgtyp;
159
};
160
 
161
 
162
#define A(__x)          ((unsigned long)(__x))
163
#define AA(__x)         ((unsigned long)(__x))
164
 
165
#define SEMOP            1
166
#define SEMGET           2
167
#define SEMCTL           3
168
#define SEMTIMEDOP       4
169
#define MSGSND          11
170
#define MSGRCV          12
171
#define MSGGET          13
172
#define MSGCTL          14
173
#define SHMAT           21
174
#define SHMDT           22
175
#define SHMGET          23
176
#define SHMCTL          24
177
 
178
#define IPCOP_MASK(__x) (1UL << (__x))
179
 
180
static int
181
ipc_parse_version32 (int *cmd)
182
{
183
        if (*cmd & IPC_64) {
184
                *cmd ^= IPC_64;
185
                return IPC_64;
186
        } else {
187
                return IPC_OLD;
188
        }
189
}
190
 
191
static int put_semid(void *user_semid, struct semid64_ds *s, int version)
192
{
193
        int err2;
194
        switch (version) {
195
        case IPC_64: {
196
                struct semid64_ds32 *usp64 = (struct semid64_ds32 *) user_semid;
197
 
198
                if (!access_ok(VERIFY_WRITE, usp64, sizeof(*usp64))) {
199
                        err2 = -EFAULT;
200
                        break;
201
                }
202
                err2 = __put_user(s->sem_perm.key, &usp64->sem_perm.key);
203
                err2 |= __put_user(s->sem_perm.uid, &usp64->sem_perm.uid);
204
                err2 |= __put_user(s->sem_perm.gid, &usp64->sem_perm.gid);
205
                err2 |= __put_user(s->sem_perm.cuid, &usp64->sem_perm.cuid);
206
                err2 |= __put_user(s->sem_perm.cgid, &usp64->sem_perm.cgid);
207
                err2 |= __put_user(s->sem_perm.mode, &usp64->sem_perm.mode);
208
                err2 |= __put_user(s->sem_perm.seq, &usp64->sem_perm.seq);
209
                err2 |= __put_user(s->sem_otime, &usp64->sem_otime);
210
                err2 |= __put_user(s->sem_ctime, &usp64->sem_ctime);
211
                err2 |= __put_user(s->sem_nsems, &usp64->sem_nsems);
212
                break;
213
        }
214
        default: {
215
                struct semid_ds32 *usp32 = (struct semid_ds32 *) user_semid;
216
 
217
                if (!access_ok(VERIFY_WRITE, usp32, sizeof(*usp32))) {
218
                        err2 = -EFAULT;
219
                        break;
220
                }
221
                err2 = __put_user(s->sem_perm.key, &usp32->sem_perm.key);
222
                err2 |= __put_user(s->sem_perm.uid, &usp32->sem_perm.uid);
223
                err2 |= __put_user(s->sem_perm.gid, &usp32->sem_perm.gid);
224
                err2 |= __put_user(s->sem_perm.cuid, &usp32->sem_perm.cuid);
225
                err2 |= __put_user(s->sem_perm.cgid, &usp32->sem_perm.cgid);
226
                err2 |= __put_user(s->sem_perm.mode, &usp32->sem_perm.mode);
227
                err2 |= __put_user(s->sem_perm.seq, &usp32->sem_perm.seq);
228
                err2 |= __put_user(s->sem_otime, &usp32->sem_otime);
229
                err2 |= __put_user(s->sem_ctime, &usp32->sem_ctime);
230
                err2 |= __put_user(s->sem_nsems, &usp32->sem_nsems);
231
                break;
232
        }
233
        }
234
        return err2;
235
}
236
 
237
static int
238
semctl32 (int first, int second, int third, void *uptr)
239
{
240
        union semun fourth;
241
        u32 pad;
242
        int err = 0;
243
        struct semid64_ds s;
244
        mm_segment_t old_fs;
245
        int version = ipc_parse_version32(&third);
246
 
247
        if (!uptr)
248
                return -EINVAL;
249
        if (get_user(pad, (u32 *)uptr))
250
                return -EFAULT;
251
        if (third == SETVAL)
252
                fourth.val = (int)pad;
253
        else
254
                fourth.__pad = (void *)A(pad);
255
        switch (third) {
256
              case IPC_INFO:
257
              case IPC_RMID:
258
              case IPC_SET:
259
              case SEM_INFO:
260
              case GETVAL:
261
              case GETPID:
262
              case GETNCNT:
263
              case GETZCNT:
264
              case GETALL:
265
              case SETVAL:
266
              case SETALL:
267
                err = sys_semctl(first, second, third, fourth);
268
                break;
269
 
270
              case IPC_STAT:
271
              case SEM_STAT:
272
                fourth.__pad = &s;
273
                old_fs = get_fs();
274
                set_fs(KERNEL_DS);
275
                err = sys_semctl(first, second, third|IPC_64, fourth);
276
                set_fs(old_fs);
277
 
278
                if (!err)
279
                        err = put_semid((void *)A(pad), &s, version);
280
 
281
                break;
282
        default:
283
                err = -EINVAL;
284
                break;
285
        }
286
        return err;
287
}
288
 
289
#define MAXBUF (64*1024)
290
 
291
static int
292
do_sys32_msgsnd (int first, int second, int third, void *uptr)
293
{
294
        struct msgbuf *p;
295
        struct msgbuf32 *up = (struct msgbuf32 *)uptr;
296
        mm_segment_t old_fs;
297
        int err;
298
 
299
        if (second >= MAXBUF-sizeof(struct msgbuf))
300
                return -EINVAL;
301
        p = kmalloc(second + sizeof(struct msgbuf), GFP_USER);
302
        if (!p)
303
                return -ENOMEM;
304
        err = get_user(p->mtype, &up->mtype);
305
        err |= (copy_from_user(p->mtext, &up->mtext, second) ? -EFAULT : 0);
306
        if (err)
307
                goto out;
308
        old_fs = get_fs();
309
        set_fs(KERNEL_DS);
310
        err = sys_msgsnd(first, p, second, third);
311
        set_fs(old_fs);
312
  out:
313
        kfree(p);
314
        return err;
315
}
316
 
317
static int
318
do_sys32_msgrcv (int first, int second, int msgtyp, int third, int version, void *uptr)
319
{
320
        struct msgbuf32 *up;
321
        struct msgbuf *p;
322
        mm_segment_t old_fs;
323
        int err;
324
 
325
        if (!version) {
326
                struct ipc_kludge *uipck = (struct ipc_kludge *)uptr;
327
                struct ipc_kludge ipck;
328
 
329
                err = -EINVAL;
330
                if (!uptr)
331
                        goto out;
332
                err = -EFAULT;
333
                if (copy_from_user(&ipck, uipck, sizeof(struct ipc_kludge)))
334
                        goto out;
335
                uptr = (void *)A(ipck.msgp);
336
                msgtyp = ipck.msgtyp;
337
        }
338
        if (second >= MAXBUF-sizeof(struct msgbuf))
339
                return -EINVAL;
340
        err = -ENOMEM;
341
        p = kmalloc(second + sizeof(struct msgbuf), GFP_USER);
342
        if (!p)
343
                goto out;
344
        old_fs = get_fs();
345
        set_fs(KERNEL_DS);
346
        err = sys_msgrcv(first, p, second, msgtyp, third);
347
        set_fs(old_fs);
348
        if (err < 0)
349
                goto free_then_out;
350
        up = (struct msgbuf32 *)uptr;
351
        if (put_user(p->mtype, &up->mtype) || copy_to_user(&up->mtext, p->mtext, err))
352
                err = -EFAULT;
353
free_then_out:
354
        kfree(p);
355
out:
356
        return err;
357
}
358
 
359
static int
360
msgctl32 (int first, int second, void *uptr)
361
{
362
        int err = -EINVAL, err2;
363
        struct msqid_ds m;
364
        struct msqid64_ds m64;
365
        struct msqid_ds32 *up32 = (struct msqid_ds32 *)uptr;
366
        struct msqid64_ds32 *up64 = (struct msqid64_ds32 *)uptr;
367
        mm_segment_t old_fs;
368
        int version = ipc_parse_version32(&second);
369
 
370
        switch (second) {
371
              case IPC_INFO:
372
              case IPC_RMID:
373
              case MSG_INFO:
374
                err = sys_msgctl(first, second, (struct msqid_ds *)uptr);
375
                break;
376
 
377
              case IPC_SET:
378
                if (version == IPC_64) {
379
                        err = get_user(m.msg_perm.uid, &up64->msg_perm.uid);
380
                        err |= get_user(m.msg_perm.gid, &up64->msg_perm.gid);
381
                        err |= get_user(m.msg_perm.mode, &up64->msg_perm.mode);
382
                        err |= get_user(m.msg_qbytes, &up64->msg_qbytes);
383
                } else {
384
                        err = get_user(m.msg_perm.uid, &up32->msg_perm.uid);
385
                        err |= get_user(m.msg_perm.gid, &up32->msg_perm.gid);
386
                        err |= get_user(m.msg_perm.mode, &up32->msg_perm.mode);
387
                        err |= get_user(m.msg_qbytes, &up32->msg_qbytes);
388
                }
389
                if (err)
390
                        break;
391
                old_fs = get_fs();
392
                set_fs(KERNEL_DS);
393
                err = sys_msgctl(first, second, &m);
394
                set_fs(old_fs);
395
                break;
396
 
397
              case IPC_STAT:
398
              case MSG_STAT:
399
                old_fs = get_fs();
400
                set_fs(KERNEL_DS);
401
                err = sys_msgctl(first, second|IPC_64, (void *) &m64);
402
                set_fs(old_fs);
403
 
404
                if (version == IPC_64) {
405
                        if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) {
406
                                err = -EFAULT;
407
                                break;
408
                        }
409
                        err2 = __put_user(m64.msg_perm.key, &up64->msg_perm.key);
410
                        err2 |= __put_user(m64.msg_perm.uid, &up64->msg_perm.uid);
411
                        err2 |= __put_user(m64.msg_perm.gid, &up64->msg_perm.gid);
412
                        err2 |= __put_user(m64.msg_perm.cuid, &up64->msg_perm.cuid);
413
                        err2 |= __put_user(m64.msg_perm.cgid, &up64->msg_perm.cgid);
414
                        err2 |= __put_user(m64.msg_perm.mode, &up64->msg_perm.mode);
415
                        err2 |= __put_user(m64.msg_perm.seq, &up64->msg_perm.seq);
416
                        err2 |= __put_user(m64.msg_stime, &up64->msg_stime);
417
                        err2 |= __put_user(m64.msg_rtime, &up64->msg_rtime);
418
                        err2 |= __put_user(m64.msg_ctime, &up64->msg_ctime);
419
                        err2 |= __put_user(m64.msg_cbytes, &up64->msg_cbytes);
420
                        err2 |= __put_user(m64.msg_qnum, &up64->msg_qnum);
421
                        err2 |= __put_user(m64.msg_qbytes, &up64->msg_qbytes);
422
                        err2 |= __put_user(m64.msg_lspid, &up64->msg_lspid);
423
                        err2 |= __put_user(m64.msg_lrpid, &up64->msg_lrpid);
424
                        if (err2)
425
                                err = -EFAULT;
426
                } else {
427
                        if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) {
428
                                err = -EFAULT;
429
                                break;
430
                        }
431
                        err2 = __put_user(m64.msg_perm.key, &up32->msg_perm.key);
432
                        err2 |= __put_user(m64.msg_perm.uid, &up32->msg_perm.uid);
433
                        err2 |= __put_user(m64.msg_perm.gid, &up32->msg_perm.gid);
434
                        err2 |= __put_user(m64.msg_perm.cuid, &up32->msg_perm.cuid);
435
                        err2 |= __put_user(m64.msg_perm.cgid, &up32->msg_perm.cgid);
436
                        err2 |= __put_user(m64.msg_perm.mode, &up32->msg_perm.mode);
437
                        err2 |= __put_user(m64.msg_perm.seq, &up32->msg_perm.seq);
438
                        err2 |= __put_user(m64.msg_stime, &up32->msg_stime);
439
                        err2 |= __put_user(m64.msg_rtime, &up32->msg_rtime);
440
                        err2 |= __put_user(m64.msg_ctime, &up32->msg_ctime);
441
                        err2 |= __put_user(m64.msg_cbytes, &up32->msg_cbytes);
442
                        err2 |= __put_user(m64.msg_qnum, &up32->msg_qnum);
443
                        err2 |= __put_user(m64.msg_qbytes, &up32->msg_qbytes);
444
                        err2 |= __put_user(m64.msg_lspid, &up32->msg_lspid);
445
                        err2 |= __put_user(m64.msg_lrpid, &up32->msg_lrpid);
446
                        if (err2)
447
                                err = -EFAULT;
448
                }
449
                break;
450
        }
451
        return err;
452
}
453
 
454
static int
455
shmat32 (int first, int second, int third, int version, void *uptr)
456
{
457
        unsigned long raddr;
458
        u32 *uaddr = (u32 *)A((u32)third);
459
        int err;
460
 
461
        if (version == 1)
462
                return -EINVAL; /* iBCS2 emulator entry point: unsupported */
463
        err = sys_shmat(first, uptr, second, &raddr);
464
        if (err)
465
                return err;
466
        return put_user(raddr, uaddr);
467
}
468
 
469
static int put_shmid64(struct shmid64_ds *s64p, void *uptr, int version)
470
{
471
        int err2;
472
#define s64 (*s64p)
473
        if (version == IPC_64) {
474
                struct shmid64_ds32 *up64 = (struct shmid64_ds32 *)uptr;
475
 
476
                if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64)))
477
                        return -EFAULT;
478
 
479
                err2 = __put_user(s64.shm_perm.key, &up64->shm_perm.key);
480
                err2 |= __put_user(s64.shm_perm.uid, &up64->shm_perm.uid);
481
                err2 |= __put_user(s64.shm_perm.gid, &up64->shm_perm.gid);
482
                err2 |= __put_user(s64.shm_perm.cuid, &up64->shm_perm.cuid);
483
                err2 |= __put_user(s64.shm_perm.cgid, &up64->shm_perm.cgid);
484
                err2 |= __put_user(s64.shm_perm.mode, &up64->shm_perm.mode);
485
                err2 |= __put_user(s64.shm_perm.seq, &up64->shm_perm.seq);
486
                err2 |= __put_user(s64.shm_atime, &up64->shm_atime);
487
                err2 |= __put_user(s64.shm_dtime, &up64->shm_dtime);
488
                err2 |= __put_user(s64.shm_ctime, &up64->shm_ctime);
489
                err2 |= __put_user(s64.shm_segsz, &up64->shm_segsz);
490
                err2 |= __put_user(s64.shm_nattch, &up64->shm_nattch);
491
                err2 |= __put_user(s64.shm_cpid, &up64->shm_cpid);
492
                err2 |= __put_user(s64.shm_lpid, &up64->shm_lpid);
493
        } else {
494
                struct shmid_ds32 *up32 = (struct shmid_ds32 *)uptr;
495
 
496
                if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32)))
497
                        return -EFAULT;
498
 
499
                err2 = __put_user(s64.shm_perm.key, &up32->shm_perm.key);
500
                err2 |= __put_user(s64.shm_perm.uid, &up32->shm_perm.uid);
501
                err2 |= __put_user(s64.shm_perm.gid, &up32->shm_perm.gid);
502
                err2 |= __put_user(s64.shm_perm.cuid, &up32->shm_perm.cuid);
503
                err2 |= __put_user(s64.shm_perm.cgid, &up32->shm_perm.cgid);
504
                err2 |= __put_user(s64.shm_perm.mode, &up32->shm_perm.mode);
505
                err2 |= __put_user(s64.shm_perm.seq, &up32->shm_perm.seq);
506
                err2 |= __put_user(s64.shm_atime, &up32->shm_atime);
507
                err2 |= __put_user(s64.shm_dtime, &up32->shm_dtime);
508
                err2 |= __put_user(s64.shm_ctime, &up32->shm_ctime);
509
                err2 |= __put_user(s64.shm_segsz, &up32->shm_segsz);
510
                err2 |= __put_user(s64.shm_nattch, &up32->shm_nattch);
511
                err2 |= __put_user(s64.shm_cpid, &up32->shm_cpid);
512
                err2 |= __put_user(s64.shm_lpid, &up32->shm_lpid);
513
        }
514
#undef s64
515
        return err2 ? -EFAULT : 0;
516
}
517
static int
518
shmctl32 (int first, int second, void *uptr)
519
{
520
        int err = -EFAULT, err2;
521
        struct shmid_ds s;
522
        struct shmid64_ds s64;
523
        mm_segment_t old_fs;
524
        struct shm_info32 *uip = (struct shm_info32 *)uptr;
525
        struct shm_info si;
526
        int version = ipc_parse_version32(&second);
527
        struct shminfo64 smi;
528
        struct shminfo *usi32 = (struct shminfo *) uptr;
529
        struct shminfo64_32 *usi64 = (struct shminfo64_32 *) uptr;
530
 
531
        switch (second) {
532
              case IPC_INFO:
533
                old_fs = get_fs();
534
                set_fs(KERNEL_DS);
535
                err = sys_shmctl(first, second|IPC_64, (struct shmid_ds *)&smi);
536
                set_fs(old_fs);
537
 
538
                if (version == IPC_64) {
539
                        if (!access_ok(VERIFY_WRITE, usi64, sizeof(*usi64))) {
540
                                err = -EFAULT;
541
                                break;
542
                        }
543
                        err2 = __put_user(smi.shmmax, &usi64->shmmax);
544
                        err2 |= __put_user(smi.shmmin, &usi64->shmmin);
545
                        err2 |= __put_user(smi.shmmni, &usi64->shmmni);
546
                        err2 |= __put_user(smi.shmseg, &usi64->shmseg);
547
                        err2 |= __put_user(smi.shmall, &usi64->shmall);
548
                } else {
549
                        if (!access_ok(VERIFY_WRITE, usi32, sizeof(*usi32))) {
550
                                err = -EFAULT;
551
                                break;
552
                        }
553
                        err2 = __put_user(smi.shmmax, &usi32->shmmax);
554
                        err2 |= __put_user(smi.shmmin, &usi32->shmmin);
555
                        err2 |= __put_user(smi.shmmni, &usi32->shmmni);
556
                        err2 |= __put_user(smi.shmseg, &usi32->shmseg);
557
                        err2 |= __put_user(smi.shmall, &usi32->shmall);
558
                }
559
                if (err2)
560
                        err = -EFAULT;
561
                break;
562
 
563
              case IPC_RMID:
564
              case SHM_LOCK:
565
              case SHM_UNLOCK:
566
                err = sys_shmctl(first, second, (struct shmid_ds *)uptr);
567
                break;
568
 
569
              case IPC_SET:
570
                if (version == IPC_64) {
571
                        struct shmid64_ds32 *up64 = (struct shmid64_ds32 *)uptr;
572
                        err = get_user(s.shm_perm.uid, &up64->shm_perm.uid);
573
                        err |= get_user(s.shm_perm.gid, &up64->shm_perm.gid);
574
                        err |= get_user(s.shm_perm.mode, &up64->shm_perm.mode);
575
                } else {
576
                        struct shmid_ds32 *up32 = (struct shmid_ds32 *)uptr;
577
                        err = get_user(s.shm_perm.uid, &up32->shm_perm.uid);
578
                        err |= get_user(s.shm_perm.gid, &up32->shm_perm.gid);
579
                        err |= get_user(s.shm_perm.mode, &up32->shm_perm.mode);
580
                }
581
                if (err)
582
                        break;
583
                old_fs = get_fs();
584
                set_fs(KERNEL_DS);
585
                err = sys_shmctl(first, second, &s);
586
                set_fs(old_fs);
587
                break;
588
 
589
              case IPC_STAT:
590
              case SHM_STAT:
591
                old_fs = get_fs();
592
                set_fs(KERNEL_DS);
593
                err = sys_shmctl(first, second|IPC_64, (void *) &s64);
594
                set_fs(old_fs);
595
 
596
                if (err < 0)
597
                        break;
598
                err2 = put_shmid64(&s64, uptr, version);
599
                if (err2)
600
                        err = err2;
601
                break;
602
 
603
              case SHM_INFO:
604
                old_fs = get_fs();
605
                set_fs(KERNEL_DS);
606
                err = sys_shmctl(first, second, (void *)&si);
607
                set_fs(old_fs);
608
                if (err < 0)
609
                        break;
610
 
611
                if (!access_ok(VERIFY_WRITE, uip, sizeof(*uip))) {
612
                        err = -EFAULT;
613
                        break;
614
                }
615
                err2 = __put_user(si.used_ids, &uip->used_ids);
616
                err2 |= __put_user(si.shm_tot, &uip->shm_tot);
617
                err2 |= __put_user(si.shm_rss, &uip->shm_rss);
618
                err2 |= __put_user(si.shm_swp, &uip->shm_swp);
619
                err2 |= __put_user(si.swap_attempts, &uip->swap_attempts);
620
                err2 |= __put_user(si.swap_successes, &uip->swap_successes);
621
                if (err2)
622
                        err = -EFAULT;
623
                break;
624
 
625
        default:
626
                err = -EINVAL;
627
                break;
628
 
629
        }
630
        return err;
631
}
632
 
633
asmlinkage long
634
sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
635
{
636
        int version;
637
 
638
        version = call >> 16; /* hack for backward compatibility */
639
        call &= 0xffff;
640
 
641
        switch (call) {
642
              case SEMOP:
643
                /* struct sembuf is the same on 32 and 64bit :)) */
644
                return sys_semtimedop(first, (struct sembuf *)AA(ptr), second, NULL);
645
              case SEMTIMEDOP: {
646
                int err;
647
                mm_segment_t oldfs = get_fs();
648
                struct timespec32 *ts32 = (struct timespec32 *)AA(fifth);
649
                struct timespec ts;
650
                if ((unsigned)second > sem_ctls[2])
651
                        return -EINVAL;
652
                if (ts32) {
653
                        if (get_user(ts.tv_sec, &ts32->tv_sec) ||
654
                                __get_user(ts.tv_nsec, &ts32->tv_nsec) ||
655
                                verify_area(VERIFY_READ, (void *)AA(ptr),
656
                                                                second*sizeof(struct sembuf)))
657
                                        return -EFAULT;
658
                }
659
                set_fs(KERNEL_DS);
660
                err = sys_semtimedop(first, (struct sembuf *)AA(ptr), second,
661
                                        ts32 ? &ts : NULL);
662
                set_fs(oldfs);
663
                return err;
664
              }
665
              case SEMGET:
666
                return sys_semget(first, second, third);
667
              case SEMCTL:
668
                return semctl32(first, second, third, (void *)AA(ptr));
669
 
670
              case MSGSND:
671
                return do_sys32_msgsnd(first, second, third, (void *)AA(ptr));
672
              case MSGRCV:
673
                return do_sys32_msgrcv(first, second, fifth, third, version, (void *)AA(ptr));
674
              case MSGGET:
675
                return sys_msgget((key_t) first, second);
676
              case MSGCTL:
677
                return msgctl32(first, second, (void *)AA(ptr));
678
 
679
              case SHMAT:
680
                return shmat32(first, second, third, version, (void *)AA(ptr));
681
                break;
682
              case SHMDT:
683
                return sys_shmdt((char *)AA(ptr));
684
              case SHMGET:
685
                return sys_shmget(first, second, third);
686
              case SHMCTL:
687
                return shmctl32(first, second, (void *)AA(ptr));
688
 
689
        }
690
        return -ENOSYS;
691
}
692
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.