Commit 27706c90 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.1.42pre2

parent 8ed6b77e
...@@ -58,24 +58,23 @@ struct mmap_arg_struct { ...@@ -58,24 +58,23 @@ struct mmap_arg_struct {
asmlinkage int old_mmap(struct mmap_arg_struct *arg) asmlinkage int old_mmap(struct mmap_arg_struct *arg)
{ {
int error = -EFAULT;
struct file * file = NULL; struct file * file = NULL;
struct mmap_arg_struct a; struct mmap_arg_struct a;
lock_kernel();
if (copy_from_user(&a, arg, sizeof(a))) if (copy_from_user(&a, arg, sizeof(a)))
return -EFAULT; goto out;
if (!(a.flags & MAP_ANONYMOUS)) { if (!(a.flags & MAP_ANONYMOUS)) {
error = -EBADF;
if (a.fd >= NR_OPEN || !(file = current->files->fd[a.fd])) if (a.fd >= NR_OPEN || !(file = current->files->fd[a.fd]))
return -EBADF; goto out;
} }
a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
{ error = do_mmap(file, a.addr, a.len, a.prot, a.flags, a.offset);
unsigned long retval; out:
struct semaphore *sem = &current->mm->mmap_sem; unlock_kernel();
down(sem); return error;
retval = do_mmap(file, a.addr, a.len, a.prot, a.flags, a.offset);
up(sem);
return retval;
}
} }
extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *); extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
......
...@@ -83,10 +83,6 @@ int __verify_write(const void * addr, unsigned long size) ...@@ -83,10 +83,6 @@ int __verify_write(const void * addr, unsigned long size)
* bit 0 == 0 means no page found, 1 means protection fault * bit 0 == 0 means no page found, 1 means protection fault
* bit 1 == 0 means read, 1 means write * bit 1 == 0 means read, 1 means write
* bit 2 == 0 means kernel, 1 means user-mode * bit 2 == 0 means kernel, 1 means user-mode
*
* NOTE! This all needs to be SMP-safe. Happily, we're only really touching
* per-thread data that we can know is valid (except for the "mm" structure
* that is shared - which is protected by the mm->mmap_sem semaphore).
*/ */
asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
{ {
...@@ -98,6 +94,8 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) ...@@ -98,6 +94,8 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
unsigned long fixup; unsigned long fixup;
int write; int write;
lock_kernel();
/* get the address */ /* get the address */
__asm__("movl %%cr2,%0":"=r" (address)); __asm__("movl %%cr2,%0":"=r" (address));
down(&mm->mmap_sem); down(&mm->mmap_sem);
...@@ -154,7 +152,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) ...@@ -154,7 +152,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
if (bit < 32) if (bit < 32)
tsk->tss.screen_bitmap |= 1 << bit; tsk->tss.screen_bitmap |= 1 << bit;
} }
return; goto out;
/* /*
* Something tried to access memory that isn't in our memory map.. * Something tried to access memory that isn't in our memory map..
...@@ -170,7 +168,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) ...@@ -170,7 +168,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
regs->eip, regs->eip,
fixup); fixup);
regs->eip = fixup; regs->eip = fixup;
return; goto out;
} }
if (error_code & 4) { if (error_code & 4) {
...@@ -178,7 +176,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) ...@@ -178,7 +176,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
tsk->tss.error_code = error_code; tsk->tss.error_code = error_code;
tsk->tss.trap_no = 14; tsk->tss.trap_no = 14;
force_sig(SIGSEGV, tsk); force_sig(SIGSEGV, tsk);
return; goto out;
} }
/* /*
* Oops. The kernel tried to access some bad page. We'll have to * Oops. The kernel tried to access some bad page. We'll have to
...@@ -190,7 +188,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) ...@@ -190,7 +188,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
wp_works_ok = 1; wp_works_ok = 1;
pg0[0] = pte_val(mk_pte(0, PAGE_SHARED)); pg0[0] = pte_val(mk_pte(0, PAGE_SHARED));
flush_tlb(); flush_tlb();
return; goto out;
} }
if (address < PAGE_SIZE) { if (address < PAGE_SIZE) {
printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference"); printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
...@@ -211,4 +209,6 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) ...@@ -211,4 +209,6 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
} }
die_if_kernel("Oops", regs, error_code); die_if_kernel("Oops", regs, error_code);
do_exit(SIGKILL); do_exit(SIGKILL);
out:
unlock_kernel();
} }
This diff is collapsed.
/* $Id: advansys.h,v 1.5 1997/01/19 23:07:10 davem Exp $ */ /* $Id: advansys.h,v 1997/05/28 00:23:06 bobf Exp bobf $ */
/* /*
* advansys.h - Linux Host Driver for AdvanSys SCSI Adapters * advansys.h - Linux Host Driver for AdvanSys SCSI Adapters
* *
* Copyright (c) 1995-1996 Advanced System Products, Inc. * Copyright (c) 1995-1997 Advanced System Products, Inc.
* All Rights Reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that redistributions of source * modification, are permitted provided that redistributions of source
* code retain the above copyright notice and this comment without * code retain the above copyright notice and this comment without
* modification. * modification.
* *
* The latest version of this driver is available at the AdvanSys * There is an AdvanSys Linux WWW page at:
* FTP and BBS sites listed below. * http://www.advansys.com/linux.html
*
* The latest version of the AdvanSys driver is available at:
* ftp://ftp.advansys.com/pub/linux
* *
* Please send questions, comments, and bug reports to: * Please send questions, comments, bug reports to:
* bobf@advansys.com (Bob Frey) * bobf@advansys.com (Bob Frey)
*/ */
...@@ -57,7 +62,7 @@ void advansys_setup(char *, int *); ...@@ -57,7 +62,7 @@ void advansys_setup(char *, int *);
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0) #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
#define ADVANSYS { \ #define ADVANSYS { \
NULL, /* struct SHT *next */ \ NULL, /* struct SHT *next */ \
NULL, /* struct module *module */ \ NULL, /* int *usage_count */ \
"advansys", /* char *name */ \ "advansys", /* char *name */ \
advansys_detect, /* int (*detect)(struct SHT *) */ \ advansys_detect, /* int (*detect)(struct SHT *) */ \
advansys_release, /* int (*release)(struct Scsi_Host *) */ \ advansys_release, /* int (*release)(struct Scsi_Host *) */ \
...@@ -95,7 +100,9 @@ void advansys_setup(char *, int *); ...@@ -95,7 +100,9 @@ void advansys_setup(char *, int *);
#else /* version >= v1.3.0 */ #else /* version >= v1.3.0 */
#define ADVANSYS { \ #define ADVANSYS { \
NULL, /* struct SHT *next */ \ NULL, /* struct SHT *next */ \
NULL, /* struct module *module */ \ NULL, \
/* version < v2.1.23 long *usage_count */ \
/* version >= v2.1.23 struct module * */ \
&proc_scsi_advansys, /* struct proc_dir_entry *proc_dir */ \ &proc_scsi_advansys, /* struct proc_dir_entry *proc_dir */ \
advansys_proc_info, \ advansys_proc_info, \
/* int (*proc_info)(char *, char **, off_t, int, int, int) */ \ /* int (*proc_info)(char *, char **, off_t, int, int, int) */ \
......
...@@ -275,14 +275,13 @@ extern void si_meminfo(struct sysinfo * val); ...@@ -275,14 +275,13 @@ extern void si_meminfo(struct sysinfo * val);
/* mmap.c */ /* mmap.c */
extern void vma_init(void); extern void vma_init(void);
extern unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags, unsigned long off);
extern void merge_segments(struct mm_struct *, unsigned long, unsigned long); extern void merge_segments(struct mm_struct *, unsigned long, unsigned long);
extern void insert_vm_struct(struct mm_struct *, struct vm_area_struct *); extern void insert_vm_struct(struct mm_struct *, struct vm_area_struct *);
extern void exit_mmap(struct mm_struct *); extern void exit_mmap(struct mm_struct *);
extern unsigned long get_unmapped_area(unsigned long, unsigned long);
extern unsigned long do_mmap(struct file *, unsigned long, unsigned long,
unsigned long, unsigned long, unsigned long);
extern int do_munmap(unsigned long, size_t); extern int do_munmap(unsigned long, size_t);
extern unsigned long get_unmapped_area(unsigned long, unsigned long);
/* filemap.c */ /* filemap.c */
extern unsigned long page_unuse(unsigned long); extern unsigned long page_unuse(unsigned long);
......
...@@ -136,7 +136,7 @@ asmlinkage int sys_shmget (key_t key, int size, int shmflg) ...@@ -136,7 +136,7 @@ asmlinkage int sys_shmget (key_t key, int size, int shmflg)
struct shmid_ds *shp; struct shmid_ds *shp;
int err, id = 0; int err, id = 0;
down(&current->mm->mmap_sem); lock_kernel();
if (size < 0 || size > SHMMAX) { if (size < 0 || size > SHMMAX) {
err = -EINVAL; err = -EINVAL;
} else if (key == IPC_PRIVATE) { } else if (key == IPC_PRIVATE) {
...@@ -159,7 +159,7 @@ asmlinkage int sys_shmget (key_t key, int size, int shmflg) ...@@ -159,7 +159,7 @@ asmlinkage int sys_shmget (key_t key, int size, int shmflg)
else else
err = (int) shp->shm_perm.seq * SHMMNI + id; err = (int) shp->shm_perm.seq * SHMMNI + id;
} }
up(&current->mm->mmap_sem); unlock_kernel();
return err; return err;
} }
...@@ -482,7 +482,7 @@ asmlinkage int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr) ...@@ -482,7 +482,7 @@ asmlinkage int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr)
unsigned long addr; unsigned long addr;
unsigned long len; unsigned long len;
down(&current->mm->mmap_sem); lock_kernel();
if (shmid < 0) { if (shmid < 0) {
/* printk("shmat() -> EINVAL because shmid = %d < 0\n",shmid); */ /* printk("shmat() -> EINVAL because shmid = %d < 0\n",shmid); */
goto out; goto out;
...@@ -575,7 +575,7 @@ asmlinkage int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr) ...@@ -575,7 +575,7 @@ asmlinkage int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr)
*raddr = addr; *raddr = addr;
err = 0; err = 0;
out: out:
up(&current->mm->mmap_sem); unlock_kernel();
return err; return err;
} }
...@@ -626,14 +626,12 @@ asmlinkage int sys_shmdt (char *shmaddr) ...@@ -626,14 +626,12 @@ asmlinkage int sys_shmdt (char *shmaddr)
{ {
struct vm_area_struct *shmd, *shmdnext; struct vm_area_struct *shmd, *shmdnext;
down(&current->mm->mmap_sem);
for (shmd = current->mm->mmap; shmd; shmd = shmdnext) { for (shmd = current->mm->mmap; shmd; shmd = shmdnext) {
shmdnext = shmd->vm_next; shmdnext = shmd->vm_next;
if (shmd->vm_ops == &shm_vm_ops if (shmd->vm_ops == &shm_vm_ops
&& shmd->vm_start - shmd->vm_offset == (ulong) shmaddr) && shmd->vm_start - shmd->vm_offset == (ulong) shmaddr)
do_munmap(shmd->vm_start, shmd->vm_end - shmd->vm_start); do_munmap(shmd->vm_start, shmd->vm_end - shmd->vm_start);
} }
up(&current->mm->mmap_sem);
return 0; return 0;
} }
......
...@@ -1210,9 +1210,7 @@ static int msync_interval(struct vm_area_struct * vma, ...@@ -1210,9 +1210,7 @@ static int msync_interval(struct vm_area_struct * vma,
return 0; return 0;
if (vma->vm_ops->sync) { if (vma->vm_ops->sync) {
int error; int error;
lock_kernel(); /* Horrible */
error = vma->vm_ops->sync(vma, start, end-start, flags); error = vma->vm_ops->sync(vma, start, end-start, flags);
unlock_kernel(); /* Horrible */
if (error) if (error)
return error; return error;
if (flags & MS_SYNC) if (flags & MS_SYNC)
...@@ -1228,7 +1226,7 @@ asmlinkage int sys_msync(unsigned long start, size_t len, int flags) ...@@ -1228,7 +1226,7 @@ asmlinkage int sys_msync(unsigned long start, size_t len, int flags)
struct vm_area_struct * vma; struct vm_area_struct * vma;
int unmapped_error, error = -EINVAL; int unmapped_error, error = -EINVAL;
down(&current->mm->mmap_sem); lock_kernel();
if (start & ~PAGE_MASK) if (start & ~PAGE_MASK)
goto out; goto out;
len = (len + ~PAGE_MASK) & PAGE_MASK; len = (len + ~PAGE_MASK) & PAGE_MASK;
...@@ -1274,7 +1272,7 @@ asmlinkage int sys_msync(unsigned long start, size_t len, int flags) ...@@ -1274,7 +1272,7 @@ asmlinkage int sys_msync(unsigned long start, size_t len, int flags)
vma = vma->vm_next; vma = vma->vm_next;
} }
out: out:
up(&current->mm->mmap_sem); unlock_kernel();
return error; return error;
} }
......
...@@ -44,8 +44,6 @@ ...@@ -44,8 +44,6 @@
#include <linux/mman.h> #include <linux/mman.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/swap.h> #include <linux/swap.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -865,9 +863,6 @@ static inline void handle_pte_fault(struct task_struct *tsk, ...@@ -865,9 +863,6 @@ static inline void handle_pte_fault(struct task_struct *tsk,
do_wp_page(tsk, vma, address, write_access, pte); do_wp_page(tsk, vma, address, write_access, pte);
} }
/*
* By the time we get here, we already have the mm semaphore.
*/
void handle_mm_fault(struct task_struct *tsk, struct vm_area_struct * vma, void handle_mm_fault(struct task_struct *tsk, struct vm_area_struct * vma,
unsigned long address, int write_access) unsigned long address, int write_access)
{ {
...@@ -882,10 +877,8 @@ void handle_mm_fault(struct task_struct *tsk, struct vm_area_struct * vma, ...@@ -882,10 +877,8 @@ void handle_mm_fault(struct task_struct *tsk, struct vm_area_struct * vma,
pte = pte_alloc(pmd, address); pte = pte_alloc(pmd, address);
if (!pte) if (!pte)
goto no_memory; goto no_memory;
lock_kernel(); /* Horrible */
handle_pte_fault(tsk, vma, address, write_access, pte); handle_pte_fault(tsk, vma, address, write_access, pte);
update_mmu_cache(vma, address, *pte); update_mmu_cache(vma, address, *pte);
unlock_kernel(); /* Horrible */
return; return;
no_memory: no_memory:
oom(tsk); oom(tsk);
......
...@@ -191,7 +191,7 @@ asmlinkage int sys_mlock(unsigned long start, size_t len) ...@@ -191,7 +191,7 @@ asmlinkage int sys_mlock(unsigned long start, size_t len)
unsigned long lock_limit; unsigned long lock_limit;
int error = -ENOMEM; int error = -ENOMEM;
down(&current->mm->mmap_sem); lock_kernel();
len = (len + (start & ~PAGE_MASK) + ~PAGE_MASK) & PAGE_MASK; len = (len + (start & ~PAGE_MASK) + ~PAGE_MASK) & PAGE_MASK;
start &= PAGE_MASK; start &= PAGE_MASK;
...@@ -212,7 +212,7 @@ asmlinkage int sys_mlock(unsigned long start, size_t len) ...@@ -212,7 +212,7 @@ asmlinkage int sys_mlock(unsigned long start, size_t len)
error = do_mlock(start, len, 1); error = do_mlock(start, len, 1);
out: out:
up(&current->mm->mmap_sem); unlock_kernel();
return error; return error;
} }
...@@ -220,11 +220,11 @@ asmlinkage int sys_munlock(unsigned long start, size_t len) ...@@ -220,11 +220,11 @@ asmlinkage int sys_munlock(unsigned long start, size_t len)
{ {
int ret; int ret;
down(&current->mm->mmap_sem); lock_kernel();
len = (len + (start & ~PAGE_MASK) + ~PAGE_MASK) & PAGE_MASK; len = (len + (start & ~PAGE_MASK) + ~PAGE_MASK) & PAGE_MASK;
start &= PAGE_MASK; start &= PAGE_MASK;
ret = do_mlock(start, len, 0); ret = do_mlock(start, len, 0);
up(&current->mm->mmap_sem); unlock_kernel();
return ret; return ret;
} }
...@@ -262,7 +262,7 @@ asmlinkage int sys_mlockall(int flags) ...@@ -262,7 +262,7 @@ asmlinkage int sys_mlockall(int flags)
unsigned long lock_limit; unsigned long lock_limit;
int ret = -EINVAL; int ret = -EINVAL;
down(&current->mm->mmap_sem); lock_kernel();
if (!flags || (flags & ~(MCL_CURRENT | MCL_FUTURE))) if (!flags || (flags & ~(MCL_CURRENT | MCL_FUTURE)))
goto out; goto out;
...@@ -280,7 +280,7 @@ asmlinkage int sys_mlockall(int flags) ...@@ -280,7 +280,7 @@ asmlinkage int sys_mlockall(int flags)
ret = do_mlockall(flags); ret = do_mlockall(flags);
out: out:
up(&current->mm->mmap_sem); unlock_kernel();
return ret; return ret;
} }
...@@ -288,8 +288,8 @@ asmlinkage int sys_munlockall(void) ...@@ -288,8 +288,8 @@ asmlinkage int sys_munlockall(void)
{ {
int ret; int ret;
down(&current->mm->mmap_sem); lock_kernel();
ret = do_mlockall(0); ret = do_mlockall(0);
up(&current->mm->mmap_sem); unlock_kernel();
return ret; return ret;
} }
...@@ -91,7 +91,7 @@ asmlinkage unsigned long sys_brk(unsigned long brk) ...@@ -91,7 +91,7 @@ asmlinkage unsigned long sys_brk(unsigned long brk)
unsigned long newbrk, oldbrk; unsigned long newbrk, oldbrk;
struct mm_struct *mm = current->mm; struct mm_struct *mm = current->mm;
down(&mm->mmap_sem); lock_kernel();
retval = mm->brk; retval = mm->brk;
if (brk < mm->end_code) if (brk < mm->end_code)
goto out; goto out;
...@@ -126,13 +126,13 @@ asmlinkage unsigned long sys_brk(unsigned long brk) ...@@ -126,13 +126,13 @@ asmlinkage unsigned long sys_brk(unsigned long brk)
goto out; goto out;
/* Ok, looks good - let it rip. */ /* Ok, looks good - let it rip. */
if (do_mmap(NULL, oldbrk, newbrk-oldbrk, if(do_mmap(NULL, oldbrk, newbrk-oldbrk,
PROT_READ|PROT_WRITE|PROT_EXEC, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_FIXED|MAP_PRIVATE, 0) == oldbrk) MAP_FIXED|MAP_PRIVATE, 0) == oldbrk)
mm->brk = brk; mm->brk = brk;
retval = mm->brk; retval = mm->brk;
out: out:
up(&mm->mmap_sem); unlock_kernel();
return retval; return retval;
} }
...@@ -158,8 +158,7 @@ static inline unsigned long vm_flags(unsigned long prot, unsigned long flags) ...@@ -158,8 +158,7 @@ static inline unsigned long vm_flags(unsigned long prot, unsigned long flags)
#undef _trans #undef _trans
} }
unsigned long do_mmap(struct file * file, unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len,
unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags, unsigned long off) unsigned long prot, unsigned long flags, unsigned long off)
{ {
struct mm_struct * mm = current->mm; struct mm_struct * mm = current->mm;
...@@ -318,15 +317,6 @@ unsigned long do_mmap(struct file * file, ...@@ -318,15 +317,6 @@ unsigned long do_mmap(struct file * file,
if ((flags & VM_LOCKED) && !(flags & VM_IO)) { if ((flags & VM_LOCKED) && !(flags & VM_IO)) {
unsigned long start = addr; unsigned long start = addr;
mm->locked_vm += len >> PAGE_SHIFT; mm->locked_vm += len >> PAGE_SHIFT;
/*
* This used to be just ugly, now it's downright broken - we can't do
* this when we're holding the mm semaphore (because the page fault
* will also try to get the semaphore - quite correctly). Besides, this
* never worked correctly anyway (we may not have read permission to
* the area in the first place).
*/
#if 0
do { do {
char c; char c;
get_user(c,(char *) start); get_user(c,(char *) start);
...@@ -334,7 +324,6 @@ unsigned long do_mmap(struct file * file, ...@@ -334,7 +324,6 @@ unsigned long do_mmap(struct file * file,
start += PAGE_SIZE; start += PAGE_SIZE;
__asm__ __volatile__("": :"r" (c)); __asm__ __volatile__("": :"r" (c));
} while (len > 0); } while (len > 0);
#endif
} }
return addr; return addr;
} }
...@@ -441,6 +430,16 @@ static void unmap_fixup(struct vm_area_struct *area, ...@@ -441,6 +430,16 @@ static void unmap_fixup(struct vm_area_struct *area,
insert_vm_struct(current->mm, mpnt); insert_vm_struct(current->mm, mpnt);
} }
asmlinkage int sys_munmap(unsigned long addr, size_t len)
{
int ret;
lock_kernel();
ret = do_munmap(addr, len);
unlock_kernel();
return ret;
}
/* Munmap is split into 2 main parts -- this part which finds /* Munmap is split into 2 main parts -- this part which finds
* what needs doing, and the areas themselves, which do the * what needs doing, and the areas themselves, which do the
* work. This now handles partial unmappings. * work. This now handles partial unmappings.
...@@ -519,16 +518,6 @@ int do_munmap(unsigned long addr, size_t len) ...@@ -519,16 +518,6 @@ int do_munmap(unsigned long addr, size_t len)
return 0; return 0;
} }
asmlinkage int sys_munmap(unsigned long addr, size_t len)
{
int ret;
down(&current->mm->mmap_sem);
ret = do_munmap(addr, len);
up(&current->mm->mmap_sem);
return ret;
}
/* Release all mmaps. */ /* Release all mmaps. */
void exit_mmap(struct mm_struct * mm) void exit_mmap(struct mm_struct * mm)
{ {
...@@ -601,6 +590,8 @@ void merge_segments (struct mm_struct * mm, unsigned long start_addr, unsigned l ...@@ -601,6 +590,8 @@ void merge_segments (struct mm_struct * mm, unsigned long start_addr, unsigned l
{ {
struct vm_area_struct *prev, *mpnt, *next; struct vm_area_struct *prev, *mpnt, *next;
down(&mm->mmap_sem);
prev = NULL; prev = NULL;
mpnt = mm->mmap; mpnt = mm->mmap;
while(mpnt && mpnt->vm_end <= start_addr) { while(mpnt && mpnt->vm_end <= start_addr) {
...@@ -608,7 +599,7 @@ void merge_segments (struct mm_struct * mm, unsigned long start_addr, unsigned l ...@@ -608,7 +599,7 @@ void merge_segments (struct mm_struct * mm, unsigned long start_addr, unsigned l
mpnt = mpnt->vm_next; mpnt = mpnt->vm_next;
} }
if (!mpnt) if (!mpnt)
return; goto no_vma;
next = mpnt->vm_next; next = mpnt->vm_next;
...@@ -660,6 +651,8 @@ void merge_segments (struct mm_struct * mm, unsigned long start_addr, unsigned l ...@@ -660,6 +651,8 @@ void merge_segments (struct mm_struct * mm, unsigned long start_addr, unsigned l
mpnt = prev; mpnt = prev;
} }
mm->mmap_cache = NULL; /* Kill the cache. */ mm->mmap_cache = NULL; /* Kill the cache. */
no_vma:
up(&mm->mmap_sem);
} }
__initfunc(void vma_init(void)) __initfunc(void vma_init(void))
......
...@@ -206,20 +206,20 @@ asmlinkage int sys_mprotect(unsigned long start, size_t len, unsigned long prot) ...@@ -206,20 +206,20 @@ asmlinkage int sys_mprotect(unsigned long start, size_t len, unsigned long prot)
{ {
unsigned long nstart, end, tmp; unsigned long nstart, end, tmp;
struct vm_area_struct * vma, * next; struct vm_area_struct * vma, * next;
int error; int error = -EINVAL;
lock_kernel();
if (start & ~PAGE_MASK) if (start & ~PAGE_MASK)
return -EINVAL; goto out;
len = (len + ~PAGE_MASK) & PAGE_MASK; len = (len + ~PAGE_MASK) & PAGE_MASK;
end = start + len; end = start + len;
if (end < start) if (end < start)
return -EINVAL; goto out;
if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC)) if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
return -EINVAL; goto out;
error = 0;
if (end == start) if (end == start)
return 0; goto out;
down(&current->mm->mmap_sem);
vma = find_vma(current->mm, start); vma = find_vma(current->mm, start);
error = -EFAULT; error = -EFAULT;
if (!vma || vma->vm_start > start) if (!vma || vma->vm_start > start)
...@@ -255,6 +255,6 @@ asmlinkage int sys_mprotect(unsigned long start, size_t len, unsigned long prot) ...@@ -255,6 +255,6 @@ asmlinkage int sys_mprotect(unsigned long start, size_t len, unsigned long prot)
} }
merge_segments(current->mm, start, end); merge_segments(current->mm, start, end);
out: out:
up(&current->mm->mmap_sem); unlock_kernel();
return error; return error;
} }
...@@ -21,8 +21,6 @@ ...@@ -21,8 +21,6 @@
#include <asm/system.h> #include <asm/system.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
extern int do_munmap(unsigned long addr, size_t len);
static inline pte_t *get_one_pte(struct mm_struct *mm, unsigned long addr) static inline pte_t *get_one_pte(struct mm_struct *mm, unsigned long addr)
{ {
pgd_t * pgd; pgd_t * pgd;
...@@ -168,7 +166,7 @@ asmlinkage unsigned long sys_mremap(unsigned long addr, ...@@ -168,7 +166,7 @@ asmlinkage unsigned long sys_mremap(unsigned long addr,
struct vm_area_struct *vma; struct vm_area_struct *vma;
unsigned long ret = -EINVAL; unsigned long ret = -EINVAL;
down(&current->mm->mmap_sem); lock_kernel();
if (addr & ~PAGE_MASK) if (addr & ~PAGE_MASK)
goto out; goto out;
old_len = PAGE_ALIGN(old_len); old_len = PAGE_ALIGN(old_len);
...@@ -233,6 +231,6 @@ asmlinkage unsigned long sys_mremap(unsigned long addr, ...@@ -233,6 +231,6 @@ asmlinkage unsigned long sys_mremap(unsigned long addr,
else else
ret = -ENOMEM; ret = -ENOMEM;
out: out:
up(&current->mm->mmap_sem); unlock_kernel();
return ret; return ret;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment