2
0
Fork 0
ibcs/iBCSemul/mmap.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(&current->mm->mmap_sem);
ret = do_mmap(file, vaddr, vsize, prot, flags | MAP_FIXED, file_offset);
up_mmap_sem(&current->mm->mmap_sem);
if (file) fput(file);
return (ret == vaddr ? 0 : ret);
}
down_mmap_sem(&current->mm->mmap_sem);
error = do_mmap(file, vaddr, vsize, prot, flags & 0x7fffffff, file_offset);
up_mmap_sem(&current->mm->mmap_sem);
if (file) fput(file);
return error;
#endif
}