110 lines
2.4 KiB
C
110 lines
2.4 KiB
C
/*
|
|
* linux/ibcs/mmap.c
|
|
*
|
|
* Copyright (C) 1994 Eric Youngdale
|
|
* Copyright (C) 1999 Mike Jagdis
|
|
*
|
|
*/
|
|
#include <linux/config.h>
|
|
|
|
#include <linux/module.h>
|
|
#include <linux/version.h>
|
|
|
|
#include <linux/mm.h>
|
|
#include <linux/errno.h>
|
|
#include <linux/mman.h>
|
|
#include <linux/sched.h>
|
|
#include <linux/major.h>
|
|
#include <linux/file.h>
|
|
|
|
#include <ibcs/ibcs.h>
|
|
#include <asm/unistd.h>
|
|
|
|
#ifdef IBCS_TRACE
|
|
#include <ibcs/trace.h>
|
|
#endif
|
|
|
|
|
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3)
|
|
# define down_mmap_sem(sem) down_write(sem)
|
|
# define up_mmap_sem(sem) up_write(sem)
|
|
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,106)
|
|
# define down_mmap_sem(sem) down(sem)
|
|
# define up_mmap_sem(sem) up(sem)
|
|
#else
|
|
# define down_mmap_sem(sem)
|
|
# define up_mmap_sem(sem)
|
|
#endif
|
|
|
|
|
|
int ibcs_memcntl(unsigned int vaddr, unsigned int vsize, int op, int flags)
|
|
{
|
|
switch (op) {
|
|
case 1: /* msync */
|
|
if ((flags & 1) == 0)
|
|
flags |= MS_SYNC;
|
|
return SYS(msync)(vaddr, vsize, flags);
|
|
|
|
case 2: /* mlock */
|
|
return SYS(mlock)(vaddr, vsize);
|
|
|
|
case 3: /* munlock */
|
|
return SYS(munlock)(vaddr, vsize);
|
|
|
|
case 4: /* madvise */
|
|
return 0; /* yeah, sure... */
|
|
|
|
case 5: /* mlockall */
|
|
return SYS(mlockall)(flags);
|
|
|
|
case 6: /* munlockall */
|
|
return SYS(munlockall)();
|
|
}
|
|
printk(KERN_ERR "iBCS: memcntl(0x%x, 0x%x, %d, 0x%x) unsupported\n",
|
|
vaddr, vsize, op, flags);
|
|
return -EINVAL;
|
|
}
|
|
|
|
|
|
int ibcs_mmap(unsigned int vaddr, unsigned int vsize, int prot, int flags,
|
|
int fd, unsigned int file_offset)
|
|
{
|
|
int error;
|
|
|
|
#ifdef __sparc__
|
|
/* XXX: Why save personality and restore it? */
|
|
int v, op = current->personality;
|
|
|
|
v = sunos_mmap(vaddr, vsize, prot, flags, fd, file_offset);
|
|
#ifdef IBCS_TRACE
|
|
if ((ibcs_trace & TRACE_API) || ibcs_func_p->trace) {
|
|
printk(KERN_DEBUG "iBCS: sunos_mmap returns 0x%x\n", v);
|
|
}
|
|
#endif
|
|
current->personality = op;
|
|
return v;
|
|
#else
|
|
struct file * file = NULL;
|
|
|
|
if (!(flags & MAP_ANONYMOUS)) {
|
|
if (!(file = fget(fd)))
|
|
return -EBADF;
|
|
}
|
|
if (personality(PER_SVR4)
|
|
&& !(flags & 0x80000000) && vaddr) {
|
|
unsigned int ret;
|
|
down_mmap_sem(¤t->mm->mmap_sem);
|
|
ret = do_mmap(file, vaddr, vsize, prot, flags | MAP_FIXED, file_offset);
|
|
up_mmap_sem(¤t->mm->mmap_sem);
|
|
if (file) fput(file);
|
|
return (ret == vaddr ? 0 : ret);
|
|
}
|
|
|
|
down_mmap_sem(¤t->mm->mmap_sem);
|
|
error = do_mmap(file, vaddr, vsize, prot, flags & 0x7fffffff, file_offset);
|
|
up_mmap_sem(¤t->mm->mmap_sem);
|
|
if (file) fput(file);
|
|
return error;
|
|
#endif
|
|
}
|