linux-old/mm/mmap.c
<<
>>
Prefs
   1/*
   2 *      linux/mm/mmap.c
   3 *
   4 * Written by obz.
   5 */
   6#include <linux/slab.h>
   7#include <linux/shm.h>
   8#include <linux/mman.h>
   9#include <linux/pagemap.h>
  10#include <linux/swap.h>
  11#include <linux/swapctl.h>
  12#include <linux/smp_lock.h>
  13#include <linux/init.h>
  14#include <linux/file.h>
  15
  16#include <asm/uaccess.h>
  17#include <asm/pgtable.h>
  18
  19/* description of effects of mapping type and prot in current implementation.
  20 * this is due to the limited x86 page protection hardware.  The expected
  21 * behavior is in parens:
  22 *
  23 * map_type     prot
  24 *              PROT_NONE       PROT_READ       PROT_WRITE      PROT_EXEC
  25 * MAP_SHARED   r: (no) no      r: (yes) yes    r: (no) yes     r: (no) yes
  26 *              w: (no) no      w: (no) no      w: (yes) yes    w: (no) no
  27 *              x: (no) no      x: (no) yes     x: (no) yes     x: (yes) yes
  28 *              
  29 * MAP_PRIVATE  r: (no) no      r: (yes) yes    r: (no) yes     r: (no) yes
  30 *              w: (no) no      w: (no) no      w: (copy) copy  w: (no) no
  31 *              x: (no) no      x: (no) yes     x: (no) yes     x: (yes) yes
  32 *
  33 */
  34pgprot_t protection_map[16] = {
  35        __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
  36        __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
  37};
  38
  39/* SLAB cache for vm_area_struct's. */
  40kmem_cache_t *vm_area_cachep;
  41
  42int sysctl_overcommit_memory;
  43
  44/* Check that a process has enough memory to allocate a
  45 * new virtual mapping.
  46 */
  47int vm_enough_memory(long pages)
  48{
  49        /* Stupid algorithm to decide if we have enough memory: while
  50         * simple, it hopefully works in most obvious cases.. Easy to
  51         * fool it, but this should catch most mistakes.
  52         */
  53        /* 23/11/98 NJC: Somewhat less stupid version of algorithm,
  54         * which tries to do "TheRightThing".  Instead of using half of
  55         * (buffers+cache), use the minimum values.  Allow an extra 2%
  56         * of num_physpages for safety margin.
  57         */
  58
  59        long free;
  60        
  61        /* Sometimes we want to use more memory than we have. */
  62        if (sysctl_overcommit_memory)
  63            return 1;
  64
  65        free = buffermem >> PAGE_SHIFT;
  66        free += page_cache_size;
  67        free += nr_free_pages;
  68        free += nr_swap_pages;
  69        free -= (page_cache.min_percent + buffer_mem.min_percent + 2)*num_physpages/100; 
  70        return free > pages;
  71}
  72
  73/* Remove one vm structure from the inode's i_mmap{,_shared} ring. */
  74static inline void remove_shared_vm_struct(struct vm_area_struct *vma)
  75{
  76        struct file * file = vma->vm_file;
  77
  78        if (file) {
  79                if (vma->vm_flags & VM_DENYWRITE)
  80                        file->f_dentry->d_inode->i_writecount++;
  81                if(vma->vm_next_share)
  82                        vma->vm_next_share->vm_pprev_share = vma->vm_pprev_share;
  83                *vma->vm_pprev_share = vma->vm_next_share;
  84        }
  85}
  86
  87asmlinkage unsigned long sys_brk(unsigned long brk)
  88{
  89        unsigned long rlim, retval;
  90        unsigned long newbrk, oldbrk;
  91        struct mm_struct *mm = current->mm;
  92
  93        down(&mm->mmap_sem);
  94
  95        /*
  96         * This lock-kernel is one of the main contention points for
  97         * certain normal loads.  And it really should not be here: almost
  98         * everything in brk()/mmap()/munmap() is protected sufficiently by
  99         * the mmap semaphore that we got above.
 100         *
 101         * We should move this into the few things that really want the
 102         * lock, namely anything that actually touches a file descriptor
 103         * etc.  We can do all the normal anonymous mapping cases without
 104         * ever getting the lock at all - the actual memory management
 105         * code is already completely thread-safe.
 106         */
 107        lock_kernel();
 108
 109        if (brk < mm->end_code)
 110                goto out;
 111        newbrk = PAGE_ALIGN(brk);
 112        oldbrk = PAGE_ALIGN(mm->brk);
 113        if (oldbrk == newbrk)
 114                goto set_brk;
 115
 116        /* Always allow shrinking brk. */
 117        if (brk <= mm->brk) {
 118                if (!do_munmap(newbrk, oldbrk-newbrk))
 119                        goto set_brk;
 120                goto out;
 121        }
 122
 123        /* Check against rlimit and stack.. */
 124        rlim = current->rlim[RLIMIT_DATA].rlim_cur;
 125        if (rlim < RLIM_INFINITY && brk - mm->end_code > rlim)
 126                goto out;
 127
 128        /* Check against existing mmap mappings. */
 129        if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE))
 130                goto out;
 131
 132        /* Check if we have enough memory.. */
 133        if (!vm_enough_memory((newbrk-oldbrk) >> PAGE_SHIFT))
 134                goto out;
 135
 136        /* Ok, looks good - let it rip. */
 137        if (do_mmap(NULL, oldbrk, newbrk-oldbrk,
 138                   PROT_READ|PROT_WRITE|PROT_EXEC,
 139                   MAP_FIXED|MAP_PRIVATE, 0) != oldbrk)
 140                goto out;
 141set_brk:
 142        mm->brk = brk;
 143out:
 144        retval = mm->brk;
 145        unlock_kernel();
 146        up(&mm->mmap_sem);
 147        return retval;
 148}
 149
 150/* Combine the mmap "prot" and "flags" argument into one "vm_flags" used
 151 * internally. Essentially, translate the "PROT_xxx" and "MAP_xxx" bits
 152 * into "VM_xxx".
 153 */
 154static inline unsigned long vm_flags(unsigned long prot, unsigned long flags)
 155{
 156#define _trans(x,bit1,bit2) \
 157((bit1==bit2)?(x&bit1):(x&bit1)?bit2:0)
 158
 159        unsigned long prot_bits, flag_bits;
 160        prot_bits =
 161                _trans(prot, PROT_READ, VM_READ) |
 162                _trans(prot, PROT_WRITE, VM_WRITE) |
 163                _trans(prot, PROT_EXEC, VM_EXEC);
 164        flag_bits =
 165                _trans(flags, MAP_GROWSDOWN, VM_GROWSDOWN) |
 166                _trans(flags, MAP_DENYWRITE, VM_DENYWRITE) |
 167                _trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE);
 168        return prot_bits | flag_bits;
 169#undef _trans
 170}
 171
 172unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len,
 173        unsigned long prot, unsigned long flags, unsigned long off)
 174{
 175        struct mm_struct * mm = current->mm;
 176        struct vm_area_struct * vma;
 177        int error;
 178
 179        if (file && (!file->f_op || !file->f_op->mmap))
 180                return -ENODEV;
 181
 182        if ((len = PAGE_ALIGN(len)) == 0)
 183                return addr;
 184
 185        if (len > TASK_SIZE || addr > TASK_SIZE-len)
 186                return -EINVAL;
 187
 188        /* offset overflow? */
 189        if (off + len - 1 < off)
 190                return -EINVAL;
 191
 192        /* Too many mappings? */
 193        if (mm->map_count > MAX_MAP_COUNT)
 194                return -ENOMEM;
 195
 196        /* mlock MCL_FUTURE? */
 197        if (mm->def_flags & VM_LOCKED) {
 198                unsigned long locked = mm->locked_vm << PAGE_SHIFT;
 199                locked += len;
 200                if (locked < len)
 201                        return -EAGAIN;
 202                if ((current->rlim[RLIMIT_MEMLOCK].rlim_cur < RLIM_INFINITY) &&
 203                   (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur))
 204                        return -EAGAIN;
 205        }
 206
 207        /* Do simple checking here so the lower-level routines won't have
 208         * to. we assume access permissions have been handled by the open
 209         * of the memory object, so we don't do any here.
 210         */
 211        if (file != NULL) {
 212                switch (flags & MAP_TYPE) {
 213                case MAP_SHARED:
 214                        if ((prot & PROT_WRITE) && !(file->f_mode & 2))
 215                                return -EACCES;
 216
 217                        /* Make sure we don't allow writing to an append-only file.. */
 218                        if (IS_APPEND(file->f_dentry->d_inode) && (file->f_mode & 2))
 219                                return -EACCES;
 220
 221                        /* make sure there are no mandatory locks on the file. */
 222                        if (locks_verify_locked(file->f_dentry->d_inode))
 223                                return -EAGAIN;
 224
 225                        /* fall through */
 226                case MAP_PRIVATE:
 227                        if (!(file->f_mode & 1))
 228                                return -EACCES;
 229                        break;
 230
 231                default:
 232                        return -EINVAL;
 233                }
 234        } else if ((flags & MAP_TYPE) != MAP_PRIVATE)
 235                return -EINVAL;
 236
 237        /* Obtain the address to map to. we verify (or select) it and ensure
 238         * that it represents a valid section of the address space.
 239         */
 240        if (flags & MAP_FIXED) {
 241                if (addr & ~PAGE_MASK)
 242                        return -EINVAL;
 243        } else {
 244                addr = get_unmapped_area(addr, len);
 245                if (!addr)
 246                        return -ENOMEM;
 247        }
 248
 249        /* Determine the object being mapped and call the appropriate
 250         * specific mapper. the address has already been validated, but
 251         * not unmapped, but the maps are removed from the list.
 252         */
 253        vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
 254        if (!vma)
 255                return -ENOMEM;
 256
 257        vma->vm_mm = mm;
 258        vma->vm_start = addr;
 259        vma->vm_end = addr + len;
 260        vma->vm_flags = vm_flags(prot,flags) | mm->def_flags;
 261
 262        if (file) {
 263                if (file->f_mode & 1)
 264                        vma->vm_flags |= VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
 265                if (flags & MAP_SHARED) {
 266                        vma->vm_flags |= VM_SHARED | VM_MAYSHARE;
 267
 268                        /* This looks strange, but when we don't have the file open
 269                         * for writing, we can demote the shared mapping to a simpler
 270                         * private mapping. That also takes care of a security hole
 271                         * with ptrace() writing to a shared mapping without write
 272                         * permissions.
 273                         *
 274                         * We leave the VM_MAYSHARE bit on, just to get correct output
 275                         * from /proc/xxx/maps..
 276                         */
 277                        if (!(file->f_mode & 2))
 278                                vma->vm_flags &= ~(VM_MAYWRITE | VM_SHARED);
 279                }
 280        } else
 281                vma->vm_flags |= VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
 282        vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
 283        vma->vm_ops = NULL;
 284        vma->vm_offset = off;
 285        vma->vm_file = NULL;
 286        vma->vm_pte = 0;
 287
 288        /* Clear old maps */
 289        error = -ENOMEM;
 290        if (do_munmap(addr, len))
 291                goto free_vma;
 292
 293        /* Check against address space limit. */
 294        if ((mm->total_vm << PAGE_SHIFT) + len < len)
 295                goto free_vma;
 296        if ((current->rlim[RLIMIT_AS].rlim_cur < RLIM_INFINITY) &&
 297            ((mm->total_vm << PAGE_SHIFT) + len
 298            > current->rlim[RLIMIT_AS].rlim_cur))
 299                goto free_vma;
 300
 301        /* Private writable mapping? Check memory availability.. */
 302        if ((vma->vm_flags & (VM_SHARED | VM_WRITE)) == VM_WRITE &&
 303            !(flags & MAP_NORESERVE)                             &&
 304            !vm_enough_memory(len >> PAGE_SHIFT))
 305                goto free_vma;
 306
 307        if (file) {
 308                int correct_wcount = 0;
 309                if (vma->vm_flags & VM_DENYWRITE) {
 310                        if (file->f_dentry->d_inode->i_writecount > 0) {
 311                                error = -ETXTBSY;
 312                                goto free_vma;
 313                        }
 314                        /* f_op->mmap might possibly sleep
 315                         * (generic_file_mmap doesn't, but other code
 316                         * might). In any case, this takes care of any
 317                         * race that this might cause.
 318                         */
 319                        file->f_dentry->d_inode->i_writecount--;
 320                        correct_wcount = 1;
 321                }
 322                error = file->f_op->mmap(file, vma);
 323                /* Fix up the count if necessary, then check for an error */
 324                if (correct_wcount)
 325                        file->f_dentry->d_inode->i_writecount++;
 326                if (error)
 327                        goto unmap_and_free_vma;
 328                vma->vm_file = file;
 329                file->f_count++;
 330        }
 331
 332        /*
 333         * merge_segments may merge our vma, so we can't refer to it
 334         * after the call.  Save the values we need now ...
 335         */
 336        flags = vma->vm_flags;
 337        addr = vma->vm_start; /* can addr have changed?? */
 338        insert_vm_struct(mm, vma);
 339        merge_segments(mm, vma->vm_start, vma->vm_end);
 340        
 341        mm->total_vm += len >> PAGE_SHIFT;
 342        if (flags & VM_LOCKED) {
 343                mm->locked_vm += len >> PAGE_SHIFT;
 344                make_pages_present(addr, addr + len);
 345        }
 346        return addr;
 347
 348unmap_and_free_vma:
 349        /* Undo any partial mapping done by a device driver. */
 350        flush_cache_range(mm, vma->vm_start, vma->vm_end);
 351        zap_page_range(mm, vma->vm_start, vma->vm_end - vma->vm_start);
 352        flush_tlb_range(mm, vma->vm_start, vma->vm_end);
 353free_vma:
 354        kmem_cache_free(vm_area_cachep, vma);
 355        return error;
 356}
 357
 358/* Get an address range which is currently unmapped.
 359 * For mmap() without MAP_FIXED and shmat() with addr=0.
 360 * Return value 0 means ENOMEM.
 361 */
 362unsigned long get_unmapped_area(unsigned long addr, unsigned long len)
 363{
 364        struct vm_area_struct * vmm;
 365
 366        if (len > TASK_SIZE)
 367                return 0;
 368        if (!addr)
 369                addr = TASK_UNMAPPED_BASE;
 370        addr = PAGE_ALIGN(addr);
 371
 372        for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
 373                /* At this point:  (!vmm || addr < vmm->vm_end). */
 374                if (TASK_SIZE - len < addr)
 375                        return 0;
 376                if (!vmm || addr + len <= vmm->vm_start)
 377                        return addr;
 378                addr = vmm->vm_end;
 379        }
 380}
 381
 382#define vm_avl_empty    (struct vm_area_struct *) NULL
 383
 384#include "mmap_avl.c"
 385
 386/* Look up the first VMA which satisfies  addr < vm_end,  NULL if none. */
 387struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr)
 388{
 389        struct vm_area_struct *vma = NULL;
 390
 391        if (mm) {
 392                /* Check the cache first. */
 393                /* (Cache hit rate is typically around 35%.) */
 394                vma = mm->mmap_cache;
 395                if (!(vma && vma->vm_end > addr && vma->vm_start <= addr)) {
 396                        if (!mm->mmap_avl) {
 397                                /* Go through the linear list. */
 398                                vma = mm->mmap;
 399                                while (vma && vma->vm_end <= addr)
 400                                        vma = vma->vm_next;
 401                        } else {
 402                                /* Then go through the AVL tree quickly. */
 403                                struct vm_area_struct * tree = mm->mmap_avl;
 404                                vma = NULL;
 405                                for (;;) {
 406                                        if (tree == vm_avl_empty)
 407                                                break;
 408                                        if (tree->vm_end > addr) {
 409                                                vma = tree;
 410                                                if (tree->vm_start <= addr)
 411                                                        break;
 412                                                tree = tree->vm_avl_left;
 413                                        } else
 414                                                tree = tree->vm_avl_right;
 415                                }
 416                        }
 417                        if (vma)
 418                                mm->mmap_cache = vma;
 419                }
 420        }
 421        return vma;
 422}
 423
 424/* Same as find_vma, but also return a pointer to the previous VMA in *pprev. */
 425struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
 426                                      struct vm_area_struct **pprev)
 427{
 428        if (mm) {
 429                if (!mm->mmap_avl) {
 430                        /* Go through the linear list. */
 431                        struct vm_area_struct * prev = NULL;
 432                        struct vm_area_struct * vma = mm->mmap;
 433                        while (vma && vma->vm_end <= addr) {
 434                                prev = vma;
 435                                vma = vma->vm_next;
 436                        }
 437                        *pprev = prev;
 438                        return vma;
 439                } else {
 440                        /* Go through the AVL tree quickly. */
 441                        struct vm_area_struct * vma = NULL;
 442                        struct vm_area_struct * last_turn_right = NULL;
 443                        struct vm_area_struct * prev = NULL;
 444                        struct vm_area_struct * tree = mm->mmap_avl;
 445                        for (;;) {
 446                                if (tree == vm_avl_empty)
 447                                        break;
 448                                if (tree->vm_end > addr) {
 449                                        vma = tree;
 450                                        prev = last_turn_right;
 451                                        if (tree->vm_start <= addr)
 452                                                break;
 453                                        tree = tree->vm_avl_left;
 454                                } else {
 455                                        last_turn_right = tree;
 456                                        tree = tree->vm_avl_right;
 457                                }
 458                        }
 459                        if (vma) {
 460                                if (vma->vm_avl_left != vm_avl_empty) {
 461                                        prev = vma->vm_avl_left;
 462                                        while (prev->vm_avl_right != vm_avl_empty)
 463                                                prev = prev->vm_avl_right;
 464                                }
 465                                if ((prev ? prev->vm_next : mm->mmap) != vma)
 466                                        printk("find_vma_prev: tree inconsistent with list\n");
 467                                *pprev = prev;
 468                                return vma;
 469                        }
 470                }
 471        }
 472        *pprev = NULL;
 473        return NULL;
 474}
 475
 476/* Normal function to fix up a mapping
 477 * This function is the default for when an area has no specific
 478 * function.  This may be used as part of a more specific routine.
 479 * This function works out what part of an area is affected and
 480 * adjusts the mapping information.  Since the actual page
 481 * manipulation is done in do_mmap(), none need be done here,
 482 * though it would probably be more appropriate.
 483 *
 484 * By the time this function is called, the area struct has been
 485 * removed from the process mapping list, so it needs to be
 486 * reinserted if necessary.
 487 *
 488 * The 4 main cases are:
 489 *    Unmapping the whole area
 490 *    Unmapping from the start of the segment to a point in it
 491 *    Unmapping from an intermediate point to the end
 492 *    Unmapping between to intermediate points, making a hole.
 493 *
 494 * Case 4 involves the creation of 2 new areas, for each side of
 495 * the hole.  If possible, we reuse the existing area rather than
 496 * allocate a new one, and the return indicates whether the old
 497 * area was reused.
 498 */
 499static struct vm_area_struct * unmap_fixup(struct vm_area_struct *area,
 500        unsigned long addr, size_t len, struct vm_area_struct *extra)
 501{
 502        struct vm_area_struct *mpnt;
 503        unsigned long end = addr + len;
 504
 505        area->vm_mm->total_vm -= len >> PAGE_SHIFT;
 506        if (area->vm_flags & VM_LOCKED)
 507                area->vm_mm->locked_vm -= len >> PAGE_SHIFT;
 508
 509        /* Unmapping the whole area. */
 510        if (addr == area->vm_start && end == area->vm_end) {
 511                if (area->vm_ops && area->vm_ops->close)
 512                        area->vm_ops->close(area);
 513                if (area->vm_file)
 514                        fput(area->vm_file);
 515                kmem_cache_free(vm_area_cachep, area);
 516                return extra;
 517        }
 518
 519        /* Work out to one of the ends. */
 520        if (end == area->vm_end)
 521                area->vm_end = addr;
 522        else if (addr == area->vm_start) {
 523                area->vm_offset += (end - area->vm_start);
 524                area->vm_start = end;
 525        } else {
 526        /* Unmapping a hole: area->vm_start < addr <= end < area->vm_end */
 527                /* Add end mapping -- leave beginning for below */
 528                mpnt = extra;
 529                extra = NULL;
 530
 531                mpnt->vm_mm = area->vm_mm;
 532                mpnt->vm_start = end;
 533                mpnt->vm_end = area->vm_end;
 534                mpnt->vm_page_prot = area->vm_page_prot;
 535                mpnt->vm_flags = area->vm_flags;
 536                mpnt->vm_ops = area->vm_ops;
 537                mpnt->vm_offset = area->vm_offset + (end - area->vm_start);
 538                mpnt->vm_file = area->vm_file;
 539                mpnt->vm_pte = area->vm_pte;
 540                if (mpnt->vm_file)
 541                        mpnt->vm_file->f_count++;
 542                if (mpnt->vm_ops && mpnt->vm_ops->open)
 543                        mpnt->vm_ops->open(mpnt);
 544                area->vm_end = addr;    /* Truncate area */
 545                insert_vm_struct(current->mm, mpnt);
 546        }
 547
 548        insert_vm_struct(current->mm, area);
 549        return extra;
 550}
 551
 552/*
 553 * Try to free as many page directory entries as we can,
 554 * without having to work very hard at actually scanning
 555 * the page tables themselves.
 556 *
 557 * Right now we try to free page tables if we have a nice
 558 * PGDIR-aligned area that got free'd up. We could be more
 559 * granular if we want to, but this is fast and simple,
 560 * and covers the bad cases.
 561 *
 562 * "prev", if it exists, points to a vma before the one
 563 * we just free'd - but there's no telling how much before.
 564 */
 565static void free_pgtables(struct mm_struct * mm, struct vm_area_struct *prev,
 566        unsigned long start, unsigned long end)
 567{
 568        unsigned long first = start & PGDIR_MASK;
 569        unsigned long last = (end + PGDIR_SIZE - 1) & PGDIR_MASK;
 570
 571        if (!prev) {
 572                prev = mm->mmap;
 573                if (!prev)
 574                        goto no_mmaps;
 575                if (prev->vm_end > start) {
 576                        if (last > prev->vm_start)
 577                                last = prev->vm_start;
 578                        goto no_mmaps;
 579                }
 580        }
 581        for (;;) {
 582                struct vm_area_struct *next = prev->vm_next;
 583
 584                if (next) {
 585                        if (next->vm_start < start) {
 586                                prev = next;
 587                                continue;
 588                        }
 589                        if (last > next->vm_start)
 590                                last = next->vm_start;
 591                }
 592                if (prev->vm_end > first)
 593                        first = prev->vm_end + PGDIR_SIZE - 1;
 594                break;
 595        }
 596no_mmaps:
 597        first = first >> PGDIR_SHIFT;
 598        last = last >> PGDIR_SHIFT;
 599        if (last > first)
 600                clear_page_tables(mm, first, last-first);
 601}
 602
 603/* Munmap is split into 2 main parts -- this part which finds
 604 * what needs doing, and the areas themselves, which do the
 605 * work.  This now handles partial unmappings.
 606 * Jeremy Fitzhardine <jeremy@sw.oz.au>
 607 */
 608int do_munmap(unsigned long addr, size_t len)
 609{
 610        struct mm_struct * mm;
 611        struct vm_area_struct *mpnt, *prev, **npp, *free, *extra;
 612
 613        if ((addr & ~PAGE_MASK) || addr >= TASK_SIZE || len > TASK_SIZE-addr)
 614                return -EINVAL;
 615
 616        if ((len = PAGE_ALIGN(len)) == 0)
 617                return -EINVAL;
 618
 619        /* Check if this memory area is ok - put it on the temporary
 620         * list if so..  The checks here are pretty simple --
 621         * every area affected in some way (by any overlap) is put
 622         * on the list.  If nothing is put on, nothing is affected.
 623         */
 624        mm = current->mm;
 625        mpnt = find_vma_prev(mm, addr, &prev);
 626        if (!mpnt)
 627                return 0;
 628        /* we have  addr < mpnt->vm_end  */
 629
 630        if (mpnt->vm_start >= addr+len)
 631                return 0;
 632
 633        /* If we'll make "hole", check the vm areas limit */
 634        if ((mpnt->vm_start < addr && mpnt->vm_end > addr+len)
 635            && mm->map_count >= MAX_MAP_COUNT)
 636                return -ENOMEM;
 637
 638        /*
 639         * We may need one additional vma to fix up the mappings ... 
 640         * and this is the last chance for an easy error exit.
 641         */
 642        extra = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
 643        if (!extra)
 644                return -ENOMEM;
 645
 646        npp = (prev ? &prev->vm_next : &mm->mmap);
 647        free = NULL;
 648        for ( ; mpnt && mpnt->vm_start < addr+len; mpnt = *npp) {
 649                *npp = mpnt->vm_next;
 650                mpnt->vm_next = free;
 651                free = mpnt;
 652                if (mm->mmap_avl)
 653                        avl_remove(mpnt, &mm->mmap_avl);
 654        }
 655
 656        /* Ok - we have the memory areas we should free on the 'free' list,
 657         * so release them, and unmap the page range..
 658         * If the one of the segments is only being partially unmapped,
 659         * it will put new vm_area_struct(s) into the address space.
 660         */
 661        while ((mpnt = free) != NULL) {
 662                unsigned long st, end, size;
 663
 664                free = free->vm_next;
 665
 666                st = addr < mpnt->vm_start ? mpnt->vm_start : addr;
 667                end = addr+len;
 668                end = end > mpnt->vm_end ? mpnt->vm_end : end;
 669                size = end - st;
 670
 671                if (mpnt->vm_ops && mpnt->vm_ops->unmap)
 672                        mpnt->vm_ops->unmap(mpnt, st, size);
 673
 674                remove_shared_vm_struct(mpnt);
 675                mm->map_count--;
 676
 677                flush_cache_range(mm, st, end);
 678                zap_page_range(mm, st, size);
 679                flush_tlb_range(mm, st, end);
 680
 681                /*
 682                 * Fix the mapping, and free the old area if it wasn't reused.
 683                 */
 684                extra = unmap_fixup(mpnt, st, size, extra);
 685        }
 686
 687        /* Release the extra vma struct if it wasn't used */
 688        if (extra)
 689                kmem_cache_free(vm_area_cachep, extra);
 690
 691        free_pgtables(mm, prev, addr, addr+len);
 692
 693        mm->mmap_cache = NULL;  /* Kill the cache. */
 694        return 0;
 695}
 696
 697asmlinkage int sys_munmap(unsigned long addr, size_t len)
 698{
 699        int ret;
 700
 701        down(&current->mm->mmap_sem);
 702        lock_kernel();
 703        ret = do_munmap(addr, len);
 704        unlock_kernel();
 705        up(&current->mm->mmap_sem);
 706        return ret;
 707}
 708
 709/* Build the AVL tree corresponding to the VMA list. */
 710void build_mmap_avl(struct mm_struct * mm)
 711{
 712        struct vm_area_struct * vma;
 713
 714        mm->mmap_avl = NULL;
 715        for (vma = mm->mmap; vma; vma = vma->vm_next)
 716                avl_insert(vma, &mm->mmap_avl);
 717}
 718
 719/* Release all mmaps. */
 720void exit_mmap(struct mm_struct * mm)
 721{
 722        struct vm_area_struct * mpnt;
 723
 724        mpnt = mm->mmap;
 725        mm->mmap = mm->mmap_avl = mm->mmap_cache = NULL;
 726        mm->rss = 0;
 727        mm->total_vm = 0;
 728        mm->locked_vm = 0;
 729        while (mpnt) {
 730                struct vm_area_struct * next = mpnt->vm_next;
 731                unsigned long start = mpnt->vm_start;
 732                unsigned long end = mpnt->vm_end;
 733                unsigned long size = end - start;
 734
 735                if (mpnt->vm_ops) {
 736                        if (mpnt->vm_ops->unmap)
 737                                mpnt->vm_ops->unmap(mpnt, start, size);
 738                        if (mpnt->vm_ops->close)
 739                                mpnt->vm_ops->close(mpnt);
 740                }
 741                mm->map_count--;
 742                remove_shared_vm_struct(mpnt);
 743                zap_page_range(mm, start, size);
 744                if (mpnt->vm_file)
 745                        fput(mpnt->vm_file);
 746                kmem_cache_free(vm_area_cachep, mpnt);
 747                mpnt = next;
 748        }
 749
 750        /* This is just debugging */
 751        if (mm->map_count)
 752                printk("exit_mmap: map count is %d\n", mm->map_count);
 753
 754        clear_page_tables(mm, 0, USER_PTRS_PER_PGD);
 755}
 756
 757/* Insert vm structure into process list sorted by address
 758 * and into the inode's i_mmap{,_shared} ring.
 759 */
 760void insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vmp)
 761{
 762        struct vm_area_struct **pprev;
 763        struct file * file;
 764
 765        if (!mm->mmap_avl) {
 766                pprev = &mm->mmap;
 767                while (*pprev && (*pprev)->vm_start <= vmp->vm_start)
 768                        pprev = &(*pprev)->vm_next;
 769        } else {
 770                struct vm_area_struct *prev, *next;
 771                avl_insert_neighbours(vmp, &mm->mmap_avl, &prev, &next);
 772                pprev = (prev ? &prev->vm_next : &mm->mmap);
 773                if (*pprev != next)
 774                        printk("insert_vm_struct: tree inconsistent with list\n");
 775        }
 776        vmp->vm_next = *pprev;
 777        *pprev = vmp;
 778
 779        mm->map_count++;
 780        if (mm->map_count >= AVL_MIN_MAP_COUNT && !mm->mmap_avl)
 781                build_mmap_avl(mm);
 782
 783        file = vmp->vm_file;
 784        if (file) {
 785                struct inode * inode = file->f_dentry->d_inode;
 786                struct vm_area_struct **head;
 787
 788                if (vmp->vm_flags & VM_DENYWRITE)
 789                        inode->i_writecount--;
 790      
 791                head = &inode->i_mmap;
 792                if (vmp->vm_flags & VM_SHARED)
 793                        head = &inode->i_mmap_shared;
 794
 795                /* insert vmp into inode's share list */
 796                if((vmp->vm_next_share = *head) != NULL)
 797                        (*head)->vm_pprev_share = &vmp->vm_next_share;
 798                *head = vmp;
 799                vmp->vm_pprev_share = head;
 800        }
 801}
 802
 803/* Merge the list of memory segments if possible.
 804 * Redundant vm_area_structs are freed.
 805 * This assumes that the list is ordered by address.
 806 * We don't need to traverse the entire list, only those segments
 807 * which intersect or are adjacent to a given interval.
 808 *
 809 * We must already hold the mm semaphore when we get here..
 810 */
 811void merge_segments (struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
 812{
 813        struct vm_area_struct *prev, *mpnt, *next, *prev1;
 814
 815        mpnt = find_vma_prev(mm, start_addr, &prev1);
 816        if (!mpnt)
 817                return;
 818
 819        if (prev1) {
 820                prev = prev1;
 821        } else {
 822                prev = mpnt;
 823                mpnt = mpnt->vm_next;
 824        }
 825
 826        /* prev and mpnt cycle through the list, as long as
 827         * start_addr < mpnt->vm_end && prev->vm_start < end_addr
 828         */
 829        for ( ; mpnt && prev->vm_start < end_addr ; prev = mpnt, mpnt = next) {
 830                next = mpnt->vm_next;
 831
 832                /* To share, we must have the same file, operations.. */
 833                if ((mpnt->vm_file != prev->vm_file)||
 834                    (mpnt->vm_pte != prev->vm_pte)      ||
 835                    (mpnt->vm_ops != prev->vm_ops)      ||
 836                    (mpnt->vm_flags != prev->vm_flags)  ||
 837                    (prev->vm_end != mpnt->vm_start))
 838                        continue;
 839
 840                /*
 841                 * If we have a file or it's a shared memory area
 842                 * the offsets must be contiguous..
 843                 */
 844                if ((mpnt->vm_file != NULL) || (mpnt->vm_flags & VM_SHM)) {
 845                        unsigned long off = prev->vm_offset+prev->vm_end-prev->vm_start;
 846                        if (off != mpnt->vm_offset)
 847                                continue;
 848                }
 849
 850                /* merge prev with mpnt and set up pointers so the new
 851                 * big segment can possibly merge with the next one.
 852                 * The old unused mpnt is freed.
 853                 */
 854                if (mm->mmap_avl)
 855                        avl_remove(mpnt, &mm->mmap_avl);
 856                prev->vm_end = mpnt->vm_end;
 857                prev->vm_next = mpnt->vm_next;
 858                if (mpnt->vm_ops && mpnt->vm_ops->close) {
 859                        mpnt->vm_offset += mpnt->vm_end - mpnt->vm_start;
 860                        mpnt->vm_start = mpnt->vm_end;
 861                        mpnt->vm_ops->close(mpnt);
 862                }
 863                mm->map_count--;
 864                remove_shared_vm_struct(mpnt);
 865                if (mpnt->vm_file)
 866                        fput(mpnt->vm_file);
 867                kmem_cache_free(vm_area_cachep, mpnt);
 868                mpnt = prev;
 869        }
 870        mm->mmap_cache = NULL;          /* Kill the cache. */
 871}
 872
 873void __init vma_init(void)
 874{
 875        vm_area_cachep = kmem_cache_create("vm_area_struct",
 876                                           sizeof(struct vm_area_struct),
 877                                           0, SLAB_HWCACHE_ALIGN,
 878                                           NULL, NULL);
 879        if(!vm_area_cachep)
 880                panic("vma_init: Cannot alloc vm_area_struct cache.");
 881
 882        mm_cachep = kmem_cache_create("mm_struct",
 883                                      sizeof(struct mm_struct),
 884                                      0, SLAB_HWCACHE_ALIGN,
 885                                      NULL, NULL);
 886        if(!mm_cachep)
 887                panic("vma_init: Cannot alloc mm_struct cache.");
 888}
 889
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.