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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [mm/] [nommu.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 *  linux/mm/nommu.c
3
 *
4
 *  Replacement code for mm functions to support CPU's that don't
5
 *  have any form of memory management unit (thus no virtual memory).
6
 *
7
 *  See Documentation/nommu-mmap.txt
8
 *
9
 *  Copyright (c) 2004-2005 David Howells <dhowells@redhat.com>
10
 *  Copyright (c) 2000-2003 David McCullough <davidm@snapgear.com>
11
 *  Copyright (c) 2000-2001 D Jeff Dionne <jeff@uClinux.org>
12
 *  Copyright (c) 2002      Greg Ungerer <gerg@snapgear.com>
13
 */
14
 
15
#include <linux/module.h>
16
#include <linux/mm.h>
17
#include <linux/mman.h>
18
#include <linux/swap.h>
19
#include <linux/file.h>
20
#include <linux/highmem.h>
21
#include <linux/pagemap.h>
22
#include <linux/slab.h>
23
#include <linux/vmalloc.h>
24
#include <linux/ptrace.h>
25
#include <linux/blkdev.h>
26
#include <linux/backing-dev.h>
27
#include <linux/mount.h>
28
#include <linux/personality.h>
29
#include <linux/security.h>
30
#include <linux/syscalls.h>
31
 
32
#include <asm/uaccess.h>
33
#include <asm/tlb.h>
34
#include <asm/tlbflush.h>
35
 
36
void *high_memory;
37
struct page *mem_map;
38
unsigned long max_mapnr;
39
unsigned long num_physpages;
40
unsigned long askedalloc, realalloc;
41
atomic_t vm_committed_space = ATOMIC_INIT(0);
42
int sysctl_overcommit_memory = OVERCOMMIT_GUESS; /* heuristic overcommit */
43
int sysctl_overcommit_ratio = 50; /* default is 50% */
44
int sysctl_max_map_count = DEFAULT_MAX_MAP_COUNT;
45
int heap_stack_gap = 0;
46
 
47
EXPORT_SYMBOL(mem_map);
48
EXPORT_SYMBOL(num_physpages);
49
 
50
/* list of shareable VMAs */
51
struct rb_root nommu_vma_tree = RB_ROOT;
52
DECLARE_RWSEM(nommu_vma_sem);
53
 
54
struct vm_operations_struct generic_file_vm_ops = {
55
};
56
 
57
/*
58
 * Handle all mappings that got truncated by a "truncate()"
59
 * system call.
60
 *
61
 * NOTE! We have to be ready to update the memory sharing
62
 * between the file and the memory map for a potential last
63
 * incomplete page.  Ugly, but necessary.
64
 */
65
int vmtruncate(struct inode *inode, loff_t offset)
66
{
67
        struct address_space *mapping = inode->i_mapping;
68
        unsigned long limit;
69
 
70
        if (inode->i_size < offset)
71
                goto do_expand;
72
        i_size_write(inode, offset);
73
 
74
        truncate_inode_pages(mapping, offset);
75
        goto out_truncate;
76
 
77
do_expand:
78
        limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
79
        if (limit != RLIM_INFINITY && offset > limit)
80
                goto out_sig;
81
        if (offset > inode->i_sb->s_maxbytes)
82
                goto out;
83
        i_size_write(inode, offset);
84
 
85
out_truncate:
86
        if (inode->i_op && inode->i_op->truncate)
87
                inode->i_op->truncate(inode);
88
        return 0;
89
out_sig:
90
        send_sig(SIGXFSZ, current, 0);
91
out:
92
        return -EFBIG;
93
}
94
 
95
EXPORT_SYMBOL(vmtruncate);
96
 
97
/*
98
 * Return the total memory allocated for this pointer, not
99
 * just what the caller asked for.
100
 *
101
 * Doesn't have to be accurate, i.e. may have races.
102
 */
103
unsigned int kobjsize(const void *objp)
104
{
105
        struct page *page;
106
 
107
        if (!objp || !((page = virt_to_page(objp))))
108
                return 0;
109
 
110
        if (PageSlab(page))
111
                return ksize(objp);
112
 
113
        BUG_ON(page->index < 0);
114
        BUG_ON(page->index >= MAX_ORDER);
115
 
116
        return (PAGE_SIZE << page->index);
117
}
118
 
119
/*
120
 * get a list of pages in an address range belonging to the specified process
121
 * and indicate the VMA that covers each page
122
 * - this is potentially dodgy as we may end incrementing the page count of a
123
 *   slab page or a secondary page from a compound page
124
 * - don't permit access to VMAs that don't support it, such as I/O mappings
125
 */
126
int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
127
        unsigned long start, int len, int write, int force,
128
        struct page **pages, struct vm_area_struct **vmas)
129
{
130
        struct vm_area_struct *vma;
131
        unsigned long vm_flags;
132
        int i;
133
 
134
        /* calculate required read or write permissions.
135
         * - if 'force' is set, we only require the "MAY" flags.
136
         */
137
        vm_flags  = write ? (VM_WRITE | VM_MAYWRITE) : (VM_READ | VM_MAYREAD);
138
        vm_flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
139
 
140
        for (i = 0; i < len; i++) {
141
                vma = find_vma(mm, start);
142
                if (!vma)
143
                        goto finish_or_fault;
144
 
145
                /* protect what we can, including chardevs */
146
                if (vma->vm_flags & (VM_IO | VM_PFNMAP) ||
147
                    !(vm_flags & vma->vm_flags))
148
                        goto finish_or_fault;
149
 
150
                if (pages) {
151
                        pages[i] = virt_to_page(start);
152
                        if (pages[i])
153
                                page_cache_get(pages[i]);
154
                }
155
                if (vmas)
156
                        vmas[i] = vma;
157
                start += PAGE_SIZE;
158
        }
159
 
160
        return i;
161
 
162
finish_or_fault:
163
        return i ? : -EFAULT;
164
}
165
EXPORT_SYMBOL(get_user_pages);
166
 
167
DEFINE_RWLOCK(vmlist_lock);
168
struct vm_struct *vmlist;
169
 
170
void vfree(void *addr)
171
{
172
        kfree(addr);
173
}
174
EXPORT_SYMBOL(vfree);
175
 
176
void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
177
{
178
        /*
179
         *  You can't specify __GFP_HIGHMEM with kmalloc() since kmalloc()
180
         * returns only a logical address.
181
         */
182
        return kmalloc(size, (gfp_mask | __GFP_COMP) & ~__GFP_HIGHMEM);
183
}
184
EXPORT_SYMBOL(__vmalloc);
185
 
186
struct page * vmalloc_to_page(void *addr)
187
{
188
        return virt_to_page(addr);
189
}
190
EXPORT_SYMBOL(vmalloc_to_page);
191
 
192
unsigned long vmalloc_to_pfn(void *addr)
193
{
194
        return page_to_pfn(virt_to_page(addr));
195
}
196
EXPORT_SYMBOL(vmalloc_to_pfn);
197
 
198
long vread(char *buf, char *addr, unsigned long count)
199
{
200
        memcpy(buf, addr, count);
201
        return count;
202
}
203
 
204
long vwrite(char *buf, char *addr, unsigned long count)
205
{
206
        /* Don't allow overflow */
207
        if ((unsigned long) addr + count < count)
208
                count = -(unsigned long) addr;
209
 
210
        memcpy(addr, buf, count);
211
        return(count);
212
}
213
 
214
/*
215
 *      vmalloc  -  allocate virtually continguos memory
216
 *
217
 *      @size:          allocation size
218
 *
219
 *      Allocate enough pages to cover @size from the page level
220
 *      allocator and map them into continguos kernel virtual space.
221
 *
222
 *      For tight control over page level allocator and protection flags
223
 *      use __vmalloc() instead.
224
 */
225
void *vmalloc(unsigned long size)
226
{
227
       return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL);
228
}
229
EXPORT_SYMBOL(vmalloc);
230
 
231
void *vmalloc_node(unsigned long size, int node)
232
{
233
        return vmalloc(size);
234
}
235
EXPORT_SYMBOL(vmalloc_node);
236
 
237
/**
238
 * vmalloc_32  -  allocate virtually contiguous memory (32bit addressable)
239
 *      @size:          allocation size
240
 *
241
 *      Allocate enough 32bit PA addressable pages to cover @size from the
242
 *      page level allocator and map them into continguos kernel virtual space.
243
 */
244
void *vmalloc_32(unsigned long size)
245
{
246
        return __vmalloc(size, GFP_KERNEL, PAGE_KERNEL);
247
}
248
EXPORT_SYMBOL(vmalloc_32);
249
 
250
/**
251
 * vmalloc_32_user - allocate zeroed virtually contiguous 32bit memory
252
 *      @size:          allocation size
253
 *
254
 * The resulting memory area is 32bit addressable and zeroed so it can be
255
 * mapped to userspace without leaking data.
256
 */
257
void *vmalloc_32_user(unsigned long size)
258
{
259
        return __vmalloc(size, GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL);
260
}
261
EXPORT_SYMBOL(vmalloc_32_user);
262
 
263
void *vmap(struct page **pages, unsigned int count, unsigned long flags, pgprot_t prot)
264
{
265
        BUG();
266
        return NULL;
267
}
268
EXPORT_SYMBOL(vmap);
269
 
270
void vunmap(void *addr)
271
{
272
        BUG();
273
}
274
EXPORT_SYMBOL(vunmap);
275
 
276
/*
277
 * Implement a stub for vmalloc_sync_all() if the architecture chose not to
278
 * have one.
279
 */
280
void  __attribute__((weak)) vmalloc_sync_all(void)
281
{
282
}
283
 
284
int vm_insert_page(struct vm_area_struct *vma, unsigned long addr,
285
                   struct page *page)
286
{
287
        return -EINVAL;
288
}
289
EXPORT_SYMBOL(vm_insert_page);
290
 
291
/*
292
 *  sys_brk() for the most part doesn't need the global kernel
293
 *  lock, except when an application is doing something nasty
294
 *  like trying to un-brk an area that has already been mapped
295
 *  to a regular file.  in this case, the unmapping will need
296
 *  to invoke file system routines that need the global lock.
297
 */
298
asmlinkage unsigned long sys_brk(unsigned long brk)
299
{
300
        struct mm_struct *mm = current->mm;
301
 
302
        if (brk < mm->start_brk || brk > mm->context.end_brk)
303
                return mm->brk;
304
 
305
        if (mm->brk == brk)
306
                return mm->brk;
307
 
308
        /*
309
         * Always allow shrinking brk
310
         */
311
        if (brk <= mm->brk) {
312
                mm->brk = brk;
313
                return brk;
314
        }
315
 
316
        /*
317
         * Ok, looks good - let it rip.
318
         */
319
        return mm->brk = brk;
320
}
321
 
322
#ifdef DEBUG
323
static void show_process_blocks(void)
324
{
325
        struct vm_list_struct *vml;
326
 
327
        printk("Process blocks %d:", current->pid);
328
 
329
        for (vml = &current->mm->context.vmlist; vml; vml = vml->next) {
330
                printk(" %p: %p", vml, vml->vma);
331
                if (vml->vma)
332
                        printk(" (%d @%lx #%d)",
333
                               kobjsize((void *) vml->vma->vm_start),
334
                               vml->vma->vm_start,
335
                               atomic_read(&vml->vma->vm_usage));
336
                printk(vml->next ? " ->" : ".\n");
337
        }
338
}
339
#endif /* DEBUG */
340
 
341
/*
342
 * add a VMA into a process's mm_struct in the appropriate place in the list
343
 * - should be called with mm->mmap_sem held writelocked
344
 */
345
static void add_vma_to_mm(struct mm_struct *mm, struct vm_list_struct *vml)
346
{
347
        struct vm_list_struct **ppv;
348
 
349
        for (ppv = &current->mm->context.vmlist; *ppv; ppv = &(*ppv)->next)
350
                if ((*ppv)->vma->vm_start > vml->vma->vm_start)
351
                        break;
352
 
353
        vml->next = *ppv;
354
        *ppv = vml;
355
}
356
 
357
/*
358
 * look up the first VMA in which addr resides, NULL if none
359
 * - should be called with mm->mmap_sem at least held readlocked
360
 */
361
struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
362
{
363
        struct vm_list_struct *loop, *vml;
364
 
365
        /* search the vm_start ordered list */
366
        vml = NULL;
367
        for (loop = mm->context.vmlist; loop; loop = loop->next) {
368
                if (loop->vma->vm_start > addr)
369
                        break;
370
                vml = loop;
371
        }
372
 
373
        if (vml && vml->vma->vm_end > addr)
374
                return vml->vma;
375
 
376
        return NULL;
377
}
378
EXPORT_SYMBOL(find_vma);
379
 
380
/*
381
 * find a VMA
382
 * - we don't extend stack VMAs under NOMMU conditions
383
 */
384
struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
385
{
386
        return find_vma(mm, addr);
387
}
388
 
389
int expand_stack(struct vm_area_struct *vma, unsigned long address)
390
{
391
        return -ENOMEM;
392
}
393
 
394
/*
395
 * look up the first VMA exactly that exactly matches addr
396
 * - should be called with mm->mmap_sem at least held readlocked
397
 */
398
static inline struct vm_area_struct *find_vma_exact(struct mm_struct *mm,
399
                                                    unsigned long addr)
400
{
401
        struct vm_list_struct *vml;
402
 
403
        /* search the vm_start ordered list */
404
        for (vml = mm->context.vmlist; vml; vml = vml->next) {
405
                if (vml->vma->vm_start == addr)
406
                        return vml->vma;
407
                if (vml->vma->vm_start > addr)
408
                        break;
409
        }
410
 
411
        return NULL;
412
}
413
 
414
/*
415
 * find a VMA in the global tree
416
 */
417
static inline struct vm_area_struct *find_nommu_vma(unsigned long start)
418
{
419
        struct vm_area_struct *vma;
420
        struct rb_node *n = nommu_vma_tree.rb_node;
421
 
422
        while (n) {
423
                vma = rb_entry(n, struct vm_area_struct, vm_rb);
424
 
425
                if (start < vma->vm_start)
426
                        n = n->rb_left;
427
                else if (start > vma->vm_start)
428
                        n = n->rb_right;
429
                else
430
                        return vma;
431
        }
432
 
433
        return NULL;
434
}
435
 
436
/*
437
 * add a VMA in the global tree
438
 */
439
static void add_nommu_vma(struct vm_area_struct *vma)
440
{
441
        struct vm_area_struct *pvma;
442
        struct address_space *mapping;
443
        struct rb_node **p = &nommu_vma_tree.rb_node;
444
        struct rb_node *parent = NULL;
445
 
446
        /* add the VMA to the mapping */
447
        if (vma->vm_file) {
448
                mapping = vma->vm_file->f_mapping;
449
 
450
                flush_dcache_mmap_lock(mapping);
451
                vma_prio_tree_insert(vma, &mapping->i_mmap);
452
                flush_dcache_mmap_unlock(mapping);
453
        }
454
 
455
        /* add the VMA to the master list */
456
        while (*p) {
457
                parent = *p;
458
                pvma = rb_entry(parent, struct vm_area_struct, vm_rb);
459
 
460
                if (vma->vm_start < pvma->vm_start) {
461
                        p = &(*p)->rb_left;
462
                }
463
                else if (vma->vm_start > pvma->vm_start) {
464
                        p = &(*p)->rb_right;
465
                }
466
                else {
467
                        /* mappings are at the same address - this can only
468
                         * happen for shared-mem chardevs and shared file
469
                         * mappings backed by ramfs/tmpfs */
470
                        BUG_ON(!(pvma->vm_flags & VM_SHARED));
471
 
472
                        if (vma < pvma)
473
                                p = &(*p)->rb_left;
474
                        else if (vma > pvma)
475
                                p = &(*p)->rb_right;
476
                        else
477
                                BUG();
478
                }
479
        }
480
 
481
        rb_link_node(&vma->vm_rb, parent, p);
482
        rb_insert_color(&vma->vm_rb, &nommu_vma_tree);
483
}
484
 
485
/*
486
 * delete a VMA from the global list
487
 */
488
static void delete_nommu_vma(struct vm_area_struct *vma)
489
{
490
        struct address_space *mapping;
491
 
492
        /* remove the VMA from the mapping */
493
        if (vma->vm_file) {
494
                mapping = vma->vm_file->f_mapping;
495
 
496
                flush_dcache_mmap_lock(mapping);
497
                vma_prio_tree_remove(vma, &mapping->i_mmap);
498
                flush_dcache_mmap_unlock(mapping);
499
        }
500
 
501
        /* remove from the master list */
502
        rb_erase(&vma->vm_rb, &nommu_vma_tree);
503
}
504
 
505
/*
506
 * determine whether a mapping should be permitted and, if so, what sort of
507
 * mapping we're capable of supporting
508
 */
509
static int validate_mmap_request(struct file *file,
510
                                 unsigned long addr,
511
                                 unsigned long len,
512
                                 unsigned long prot,
513
                                 unsigned long flags,
514
                                 unsigned long pgoff,
515
                                 unsigned long *_capabilities)
516
{
517
        unsigned long capabilities;
518
        unsigned long reqprot = prot;
519
        int ret;
520
 
521
        /* do the simple checks first */
522
        if (flags & MAP_FIXED || addr) {
523
                printk(KERN_DEBUG
524
                       "%d: Can't do fixed-address/overlay mmap of RAM\n",
525
                       current->pid);
526
                return -EINVAL;
527
        }
528
 
529
        if ((flags & MAP_TYPE) != MAP_PRIVATE &&
530
            (flags & MAP_TYPE) != MAP_SHARED)
531
                return -EINVAL;
532
 
533
        if (!len)
534
                return -EINVAL;
535
 
536
        /* Careful about overflows.. */
537
        len = PAGE_ALIGN(len);
538
        if (!len || len > TASK_SIZE)
539
                return -ENOMEM;
540
 
541
        /* offset overflow? */
542
        if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
543
                return -EOVERFLOW;
544
 
545
        if (file) {
546
                /* validate file mapping requests */
547
                struct address_space *mapping;
548
 
549
                /* files must support mmap */
550
                if (!file->f_op || !file->f_op->mmap)
551
                        return -ENODEV;
552
 
553
                /* work out if what we've got could possibly be shared
554
                 * - we support chardevs that provide their own "memory"
555
                 * - we support files/blockdevs that are memory backed
556
                 */
557
                mapping = file->f_mapping;
558
                if (!mapping)
559
                        mapping = file->f_path.dentry->d_inode->i_mapping;
560
 
561
                capabilities = 0;
562
                if (mapping && mapping->backing_dev_info)
563
                        capabilities = mapping->backing_dev_info->capabilities;
564
 
565
                if (!capabilities) {
566
                        /* no explicit capabilities set, so assume some
567
                         * defaults */
568
                        switch (file->f_path.dentry->d_inode->i_mode & S_IFMT) {
569
                        case S_IFREG:
570
                        case S_IFBLK:
571
                                capabilities = BDI_CAP_MAP_COPY;
572
                                break;
573
 
574
                        case S_IFCHR:
575
                                capabilities =
576
                                        BDI_CAP_MAP_DIRECT |
577
                                        BDI_CAP_READ_MAP |
578
                                        BDI_CAP_WRITE_MAP;
579
                                break;
580
 
581
                        default:
582
                                return -EINVAL;
583
                        }
584
                }
585
 
586
                /* eliminate any capabilities that we can't support on this
587
                 * device */
588
                if (!file->f_op->get_unmapped_area)
589
                        capabilities &= ~BDI_CAP_MAP_DIRECT;
590
                if (!file->f_op->read)
591
                        capabilities &= ~BDI_CAP_MAP_COPY;
592
 
593
                if (flags & MAP_SHARED) {
594
                        /* do checks for writing, appending and locking */
595
                        if ((prot & PROT_WRITE) &&
596
                            !(file->f_mode & FMODE_WRITE))
597
                                return -EACCES;
598
 
599
                        if (IS_APPEND(file->f_path.dentry->d_inode) &&
600
                            (file->f_mode & FMODE_WRITE))
601
                                return -EACCES;
602
 
603
                        if (locks_verify_locked(file->f_path.dentry->d_inode))
604
                                return -EAGAIN;
605
 
606
                        if (!(capabilities & BDI_CAP_MAP_DIRECT))
607
                                return -ENODEV;
608
 
609
                        if (((prot & PROT_READ)  && !(capabilities & BDI_CAP_READ_MAP))  ||
610
                            ((prot & PROT_WRITE) && !(capabilities & BDI_CAP_WRITE_MAP)) ||
611
                            ((prot & PROT_EXEC)  && !(capabilities & BDI_CAP_EXEC_MAP))
612
                            ) {
613
                                printk("MAP_SHARED not completely supported on !MMU\n");
614
                                return -EINVAL;
615
                        }
616
 
617
                        /* we mustn't privatise shared mappings */
618
                        capabilities &= ~BDI_CAP_MAP_COPY;
619
                }
620
                else {
621
                        /* we're going to read the file into private memory we
622
                         * allocate */
623
                        if (!(capabilities & BDI_CAP_MAP_COPY))
624
                                return -ENODEV;
625
 
626
                        /* we don't permit a private writable mapping to be
627
                         * shared with the backing device */
628
                        if (prot & PROT_WRITE)
629
                                capabilities &= ~BDI_CAP_MAP_DIRECT;
630
                }
631
 
632
                /* handle executable mappings and implied executable
633
                 * mappings */
634
                if (file->f_path.mnt->mnt_flags & MNT_NOEXEC) {
635
                        if (prot & PROT_EXEC)
636
                                return -EPERM;
637
                }
638
                else if ((prot & PROT_READ) && !(prot & PROT_EXEC)) {
639
                        /* handle implication of PROT_EXEC by PROT_READ */
640
                        if (current->personality & READ_IMPLIES_EXEC) {
641
                                if (capabilities & BDI_CAP_EXEC_MAP)
642
                                        prot |= PROT_EXEC;
643
                        }
644
                }
645
                else if ((prot & PROT_READ) &&
646
                         (prot & PROT_EXEC) &&
647
                         !(capabilities & BDI_CAP_EXEC_MAP)
648
                         ) {
649
                        /* backing file is not executable, try to copy */
650
                        capabilities &= ~BDI_CAP_MAP_DIRECT;
651
                }
652
        }
653
        else {
654
                /* anonymous mappings are always memory backed and can be
655
                 * privately mapped
656
                 */
657
                capabilities = BDI_CAP_MAP_COPY;
658
 
659
                /* handle PROT_EXEC implication by PROT_READ */
660
                if ((prot & PROT_READ) &&
661
                    (current->personality & READ_IMPLIES_EXEC))
662
                        prot |= PROT_EXEC;
663
        }
664
 
665
        /* allow the security API to have its say */
666
        ret = security_file_mmap(file, reqprot, prot, flags, addr, 0);
667
        if (ret < 0)
668
                return ret;
669
 
670
        /* looks okay */
671
        *_capabilities = capabilities;
672
        return 0;
673
}
674
 
675
/*
676
 * we've determined that we can make the mapping, now translate what we
677
 * now know into VMA flags
678
 */
679
static unsigned long determine_vm_flags(struct file *file,
680
                                        unsigned long prot,
681
                                        unsigned long flags,
682
                                        unsigned long capabilities)
683
{
684
        unsigned long vm_flags;
685
 
686
        vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags);
687
        vm_flags |= VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
688
        /* vm_flags |= mm->def_flags; */
689
 
690
        if (!(capabilities & BDI_CAP_MAP_DIRECT)) {
691
                /* attempt to share read-only copies of mapped file chunks */
692
                if (file && !(prot & PROT_WRITE))
693
                        vm_flags |= VM_MAYSHARE;
694
        }
695
        else {
696
                /* overlay a shareable mapping on the backing device or inode
697
                 * if possible - used for chardevs, ramfs/tmpfs/shmfs and
698
                 * romfs/cramfs */
699
                if (flags & MAP_SHARED)
700
                        vm_flags |= VM_MAYSHARE | VM_SHARED;
701
                else if ((((vm_flags & capabilities) ^ vm_flags) & BDI_CAP_VMFLAGS) == 0)
702
                        vm_flags |= VM_MAYSHARE;
703
        }
704
 
705
        /* refuse to let anyone share private mappings with this process if
706
         * it's being traced - otherwise breakpoints set in it may interfere
707
         * with another untraced process
708
         */
709
        if ((flags & MAP_PRIVATE) && (current->ptrace & PT_PTRACED))
710
                vm_flags &= ~VM_MAYSHARE;
711
 
712
        return vm_flags;
713
}
714
 
715
/*
716
 * set up a shared mapping on a file
717
 */
718
static int do_mmap_shared_file(struct vm_area_struct *vma, unsigned long len)
719
{
720
        int ret;
721
 
722
        ret = vma->vm_file->f_op->mmap(vma->vm_file, vma);
723
        if (ret != -ENOSYS)
724
                return ret;
725
 
726
        /* getting an ENOSYS error indicates that direct mmap isn't
727
         * possible (as opposed to tried but failed) so we'll fall
728
         * through to making a private copy of the data and mapping
729
         * that if we can */
730
        return -ENODEV;
731
}
732
 
733
/*
734
 * set up a private mapping or an anonymous shared mapping
735
 */
736
static int do_mmap_private(struct vm_area_struct *vma, unsigned long len)
737
{
738
        void *base;
739
        int ret;
740
 
741
        /* invoke the file's mapping function so that it can keep track of
742
         * shared mappings on devices or memory
743
         * - VM_MAYSHARE will be set if it may attempt to share
744
         */
745
        if (vma->vm_file) {
746
                ret = vma->vm_file->f_op->mmap(vma->vm_file, vma);
747
                if (ret != -ENOSYS) {
748
                        /* shouldn't return success if we're not sharing */
749
                        BUG_ON(ret == 0 && !(vma->vm_flags & VM_MAYSHARE));
750
                        return ret; /* success or a real error */
751
                }
752
 
753
                /* getting an ENOSYS error indicates that direct mmap isn't
754
                 * possible (as opposed to tried but failed) so we'll try to
755
                 * make a private copy of the data and map that instead */
756
        }
757
 
758
        /* allocate some memory to hold the mapping
759
         * - note that this may not return a page-aligned address if the object
760
         *   we're allocating is smaller than a page
761
         */
762
        base = kmalloc(len, GFP_KERNEL|__GFP_COMP);
763
        if (!base)
764
                goto enomem;
765
 
766
        vma->vm_start = (unsigned long) base;
767
        vma->vm_end = vma->vm_start + len;
768
        vma->vm_flags |= VM_MAPPED_COPY;
769
 
770
#ifdef WARN_ON_SLACK
771
        if (len + WARN_ON_SLACK <= kobjsize(result))
772
                printk("Allocation of %lu bytes from process %d has %lu bytes of slack\n",
773
                       len, current->pid, kobjsize(result) - len);
774
#endif
775
 
776
        if (vma->vm_file) {
777
                /* read the contents of a file into the copy */
778
                mm_segment_t old_fs;
779
                loff_t fpos;
780
 
781
                fpos = vma->vm_pgoff;
782
                fpos <<= PAGE_SHIFT;
783
 
784
                old_fs = get_fs();
785
                set_fs(KERNEL_DS);
786
                ret = vma->vm_file->f_op->read(vma->vm_file, base, len, &fpos);
787
                set_fs(old_fs);
788
 
789
                if (ret < 0)
790
                        goto error_free;
791
 
792
                /* clear the last little bit */
793
                if (ret < len)
794
                        memset(base + ret, 0, len - ret);
795
 
796
        } else {
797
                /* if it's an anonymous mapping, then just clear it */
798
                memset(base, 0, len);
799
        }
800
 
801
        return 0;
802
 
803
error_free:
804
        kfree(base);
805
        vma->vm_start = 0;
806
        return ret;
807
 
808
enomem:
809
        printk("Allocation of length %lu from process %d failed\n",
810
               len, current->pid);
811
        show_free_areas();
812
        return -ENOMEM;
813
}
814
 
815
/*
816
 * handle mapping creation for uClinux
817
 */
818
unsigned long do_mmap_pgoff(struct file *file,
819
                            unsigned long addr,
820
                            unsigned long len,
821
                            unsigned long prot,
822
                            unsigned long flags,
823
                            unsigned long pgoff)
824
{
825
        struct vm_list_struct *vml = NULL;
826
        struct vm_area_struct *vma = NULL;
827
        struct rb_node *rb;
828
        unsigned long capabilities, vm_flags;
829
        void *result;
830
        int ret;
831
 
832
        if (!(flags & MAP_FIXED))
833
                addr = round_hint_to_min(addr);
834
 
835
        /* decide whether we should attempt the mapping, and if so what sort of
836
         * mapping */
837
        ret = validate_mmap_request(file, addr, len, prot, flags, pgoff,
838
                                    &capabilities);
839
        if (ret < 0)
840
                return ret;
841
 
842
        /* we've determined that we can make the mapping, now translate what we
843
         * now know into VMA flags */
844
        vm_flags = determine_vm_flags(file, prot, flags, capabilities);
845
 
846
        /* we're going to need to record the mapping if it works */
847
        vml = kzalloc(sizeof(struct vm_list_struct), GFP_KERNEL);
848
        if (!vml)
849
                goto error_getting_vml;
850
 
851
        down_write(&nommu_vma_sem);
852
 
853
        /* if we want to share, we need to check for VMAs created by other
854
         * mmap() calls that overlap with our proposed mapping
855
         * - we can only share with an exact match on most regular files
856
         * - shared mappings on character devices and memory backed files are
857
         *   permitted to overlap inexactly as far as we are concerned for in
858
         *   these cases, sharing is handled in the driver or filesystem rather
859
         *   than here
860
         */
861
        if (vm_flags & VM_MAYSHARE) {
862
                unsigned long pglen = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
863
                unsigned long vmpglen;
864
 
865
                /* suppress VMA sharing for shared regions */
866
                if (vm_flags & VM_SHARED &&
867
                    capabilities & BDI_CAP_MAP_DIRECT)
868
                        goto dont_share_VMAs;
869
 
870
                for (rb = rb_first(&nommu_vma_tree); rb; rb = rb_next(rb)) {
871
                        vma = rb_entry(rb, struct vm_area_struct, vm_rb);
872
 
873
                        if (!(vma->vm_flags & VM_MAYSHARE))
874
                                continue;
875
 
876
                        /* search for overlapping mappings on the same file */
877
                        if (vma->vm_file->f_path.dentry->d_inode != file->f_path.dentry->d_inode)
878
                                continue;
879
 
880
                        if (vma->vm_pgoff >= pgoff + pglen)
881
                                continue;
882
 
883
                        vmpglen = vma->vm_end - vma->vm_start + PAGE_SIZE - 1;
884
                        vmpglen >>= PAGE_SHIFT;
885
                        if (pgoff >= vma->vm_pgoff + vmpglen)
886
                                continue;
887
 
888
                        /* handle inexactly overlapping matches between mappings */
889
                        if (vma->vm_pgoff != pgoff || vmpglen != pglen) {
890
                                if (!(capabilities & BDI_CAP_MAP_DIRECT))
891
                                        goto sharing_violation;
892
                                continue;
893
                        }
894
 
895
                        /* we've found a VMA we can share */
896
                        atomic_inc(&vma->vm_usage);
897
 
898
                        vml->vma = vma;
899
                        result = (void *) vma->vm_start;
900
                        goto shared;
901
                }
902
 
903
        dont_share_VMAs:
904
                vma = NULL;
905
 
906
                /* obtain the address at which to make a shared mapping
907
                 * - this is the hook for quasi-memory character devices to
908
                 *   tell us the location of a shared mapping
909
                 */
910
                if (file && file->f_op->get_unmapped_area) {
911
                        addr = file->f_op->get_unmapped_area(file, addr, len,
912
                                                             pgoff, flags);
913
                        if (IS_ERR((void *) addr)) {
914
                                ret = addr;
915
                                if (ret != (unsigned long) -ENOSYS)
916
                                        goto error;
917
 
918
                                /* the driver refused to tell us where to site
919
                                 * the mapping so we'll have to attempt to copy
920
                                 * it */
921
                                ret = (unsigned long) -ENODEV;
922
                                if (!(capabilities & BDI_CAP_MAP_COPY))
923
                                        goto error;
924
 
925
                                capabilities &= ~BDI_CAP_MAP_DIRECT;
926
                        }
927
                }
928
        }
929
 
930
        /* we're going to need a VMA struct as well */
931
        vma = kzalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
932
        if (!vma)
933
                goto error_getting_vma;
934
 
935
        INIT_LIST_HEAD(&vma->anon_vma_node);
936
        atomic_set(&vma->vm_usage, 1);
937
        if (file)
938
                get_file(file);
939
        vma->vm_file    = file;
940
        vma->vm_flags   = vm_flags;
941
        vma->vm_start   = addr;
942
        vma->vm_end     = addr + len;
943
        vma->vm_pgoff   = pgoff;
944
 
945
        vml->vma = vma;
946
 
947
        /* set up the mapping */
948
        if (file && vma->vm_flags & VM_SHARED)
949
                ret = do_mmap_shared_file(vma, len);
950
        else
951
                ret = do_mmap_private(vma, len);
952
        if (ret < 0)
953
                goto error;
954
 
955
        /* okay... we have a mapping; now we have to register it */
956
        result = (void *) vma->vm_start;
957
 
958
        if (vma->vm_flags & VM_MAPPED_COPY) {
959
                realalloc += kobjsize(result);
960
                askedalloc += len;
961
        }
962
 
963
        realalloc += kobjsize(vma);
964
        askedalloc += sizeof(*vma);
965
 
966
        current->mm->total_vm += len >> PAGE_SHIFT;
967
 
968
        add_nommu_vma(vma);
969
 
970
 shared:
971
        realalloc += kobjsize(vml);
972
        askedalloc += sizeof(*vml);
973
 
974
        add_vma_to_mm(current->mm, vml);
975
 
976
        up_write(&nommu_vma_sem);
977
 
978
        if (prot & PROT_EXEC)
979
                flush_icache_range((unsigned long) result,
980
                                   (unsigned long) result + len);
981
 
982
#ifdef DEBUG
983
        printk("do_mmap:\n");
984
        show_process_blocks();
985
#endif
986
 
987
        return (unsigned long) result;
988
 
989
 error:
990
        up_write(&nommu_vma_sem);
991
        kfree(vml);
992
        if (vma) {
993
                if (vma->vm_file)
994
                        fput(vma->vm_file);
995
                kfree(vma);
996
        }
997
        return ret;
998
 
999
 sharing_violation:
1000
        up_write(&nommu_vma_sem);
1001
        printk("Attempt to share mismatched mappings\n");
1002
        kfree(vml);
1003
        return -EINVAL;
1004
 
1005
 error_getting_vma:
1006
        up_write(&nommu_vma_sem);
1007
        kfree(vml);
1008
        printk("Allocation of vma for %lu byte allocation from process %d failed\n",
1009
               len, current->pid);
1010
        show_free_areas();
1011
        return -ENOMEM;
1012
 
1013
 error_getting_vml:
1014
        printk("Allocation of vml for %lu byte allocation from process %d failed\n",
1015
               len, current->pid);
1016
        show_free_areas();
1017
        return -ENOMEM;
1018
}
1019
EXPORT_SYMBOL(do_mmap_pgoff);
1020
 
1021
/*
1022
 * handle mapping disposal for uClinux
1023
 */
1024
static void put_vma(struct vm_area_struct *vma)
1025
{
1026
        if (vma) {
1027
                down_write(&nommu_vma_sem);
1028
 
1029
                if (atomic_dec_and_test(&vma->vm_usage)) {
1030
                        delete_nommu_vma(vma);
1031
 
1032
                        if (vma->vm_ops && vma->vm_ops->close)
1033
                                vma->vm_ops->close(vma);
1034
 
1035
                        /* IO memory and memory shared directly out of the pagecache from
1036
                         * ramfs/tmpfs mustn't be released here */
1037
                        if (vma->vm_flags & VM_MAPPED_COPY) {
1038
                                realalloc -= kobjsize((void *) vma->vm_start);
1039
                                askedalloc -= vma->vm_end - vma->vm_start;
1040
                                kfree((void *) vma->vm_start);
1041
                        }
1042
 
1043
                        realalloc -= kobjsize(vma);
1044
                        askedalloc -= sizeof(*vma);
1045
 
1046
                        if (vma->vm_file)
1047
                                fput(vma->vm_file);
1048
                        kfree(vma);
1049
                }
1050
 
1051
                up_write(&nommu_vma_sem);
1052
        }
1053
}
1054
 
1055
/*
1056
 * release a mapping
1057
 * - under NOMMU conditions the parameters must match exactly to the mapping to
1058
 *   be removed
1059
 */
1060
int do_munmap(struct mm_struct *mm, unsigned long addr, size_t len)
1061
{
1062
        struct vm_list_struct *vml, **parent;
1063
        unsigned long end = addr + len;
1064
 
1065
#ifdef DEBUG
1066
        printk("do_munmap:\n");
1067
#endif
1068
 
1069
        for (parent = &mm->context.vmlist; *parent; parent = &(*parent)->next) {
1070
                if ((*parent)->vma->vm_start > addr)
1071
                        break;
1072
                if ((*parent)->vma->vm_start == addr &&
1073
                    ((len == 0) || ((*parent)->vma->vm_end == end)))
1074
                        goto found;
1075
        }
1076
 
1077
        printk("munmap of non-mmaped memory by process %d (%s): %p\n",
1078
               current->pid, current->comm, (void *) addr);
1079
        return -EINVAL;
1080
 
1081
 found:
1082
        vml = *parent;
1083
 
1084
        put_vma(vml->vma);
1085
 
1086
        *parent = vml->next;
1087
        realalloc -= kobjsize(vml);
1088
        askedalloc -= sizeof(*vml);
1089
        kfree(vml);
1090
 
1091
        update_hiwater_vm(mm);
1092
        mm->total_vm -= len >> PAGE_SHIFT;
1093
 
1094
#ifdef DEBUG
1095
        show_process_blocks();
1096
#endif
1097
 
1098
        return 0;
1099
}
1100
EXPORT_SYMBOL(do_munmap);
1101
 
1102
asmlinkage long sys_munmap(unsigned long addr, size_t len)
1103
{
1104
        int ret;
1105
        struct mm_struct *mm = current->mm;
1106
 
1107
        down_write(&mm->mmap_sem);
1108
        ret = do_munmap(mm, addr, len);
1109
        up_write(&mm->mmap_sem);
1110
        return ret;
1111
}
1112
 
1113
/*
1114
 * Release all mappings
1115
 */
1116
void exit_mmap(struct mm_struct * mm)
1117
{
1118
        struct vm_list_struct *tmp;
1119
 
1120
        if (mm) {
1121
#ifdef DEBUG
1122
                printk("Exit_mmap:\n");
1123
#endif
1124
 
1125
                mm->total_vm = 0;
1126
 
1127
                while ((tmp = mm->context.vmlist)) {
1128
                        mm->context.vmlist = tmp->next;
1129
                        put_vma(tmp->vma);
1130
 
1131
                        realalloc -= kobjsize(tmp);
1132
                        askedalloc -= sizeof(*tmp);
1133
                        kfree(tmp);
1134
                }
1135
 
1136
#ifdef DEBUG
1137
                show_process_blocks();
1138
#endif
1139
        }
1140
}
1141
 
1142
unsigned long do_brk(unsigned long addr, unsigned long len)
1143
{
1144
        return -ENOMEM;
1145
}
1146
 
1147
/*
1148
 * expand (or shrink) an existing mapping, potentially moving it at the same
1149
 * time (controlled by the MREMAP_MAYMOVE flag and available VM space)
1150
 *
1151
 * under NOMMU conditions, we only permit changing a mapping's size, and only
1152
 * as long as it stays within the hole allocated by the kmalloc() call in
1153
 * do_mmap_pgoff() and the block is not shareable
1154
 *
1155
 * MREMAP_FIXED is not supported under NOMMU conditions
1156
 */
1157
unsigned long do_mremap(unsigned long addr,
1158
                        unsigned long old_len, unsigned long new_len,
1159
                        unsigned long flags, unsigned long new_addr)
1160
{
1161
        struct vm_area_struct *vma;
1162
 
1163
        /* insanity checks first */
1164
        if (new_len == 0)
1165
                return (unsigned long) -EINVAL;
1166
 
1167
        if (flags & MREMAP_FIXED && new_addr != addr)
1168
                return (unsigned long) -EINVAL;
1169
 
1170
        vma = find_vma_exact(current->mm, addr);
1171
        if (!vma)
1172
                return (unsigned long) -EINVAL;
1173
 
1174
        if (vma->vm_end != vma->vm_start + old_len)
1175
                return (unsigned long) -EFAULT;
1176
 
1177
        if (vma->vm_flags & VM_MAYSHARE)
1178
                return (unsigned long) -EPERM;
1179
 
1180
        if (new_len > kobjsize((void *) addr))
1181
                return (unsigned long) -ENOMEM;
1182
 
1183
        /* all checks complete - do it */
1184
        vma->vm_end = vma->vm_start + new_len;
1185
 
1186
        askedalloc -= old_len;
1187
        askedalloc += new_len;
1188
 
1189
        return vma->vm_start;
1190
}
1191
EXPORT_SYMBOL(do_mremap);
1192
 
1193
asmlinkage unsigned long sys_mremap(unsigned long addr,
1194
        unsigned long old_len, unsigned long new_len,
1195
        unsigned long flags, unsigned long new_addr)
1196
{
1197
        unsigned long ret;
1198
 
1199
        down_write(&current->mm->mmap_sem);
1200
        ret = do_mremap(addr, old_len, new_len, flags, new_addr);
1201
        up_write(&current->mm->mmap_sem);
1202
        return ret;
1203
}
1204
 
1205
struct page *follow_page(struct vm_area_struct *vma, unsigned long address,
1206
                        unsigned int foll_flags)
1207
{
1208
        return NULL;
1209
}
1210
 
1211
int remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
1212
                unsigned long to, unsigned long size, pgprot_t prot)
1213
{
1214
        vma->vm_start = vma->vm_pgoff << PAGE_SHIFT;
1215
        return 0;
1216
}
1217
EXPORT_SYMBOL(remap_pfn_range);
1218
 
1219
void swap_unplug_io_fn(struct backing_dev_info *bdi, struct page *page)
1220
{
1221
}
1222
 
1223
unsigned long arch_get_unmapped_area(struct file *file, unsigned long addr,
1224
        unsigned long len, unsigned long pgoff, unsigned long flags)
1225
{
1226
        return -ENOMEM;
1227
}
1228
 
1229
void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
1230
{
1231
}
1232
 
1233
void unmap_mapping_range(struct address_space *mapping,
1234
                         loff_t const holebegin, loff_t const holelen,
1235
                         int even_cows)
1236
{
1237
}
1238
EXPORT_SYMBOL(unmap_mapping_range);
1239
 
1240
/*
1241
 * ask for an unmapped area at which to create a mapping on a file
1242
 */
1243
unsigned long get_unmapped_area(struct file *file, unsigned long addr,
1244
                                unsigned long len, unsigned long pgoff,
1245
                                unsigned long flags)
1246
{
1247
        unsigned long (*get_area)(struct file *, unsigned long, unsigned long,
1248
                                  unsigned long, unsigned long);
1249
 
1250
        get_area = current->mm->get_unmapped_area;
1251
        if (file && file->f_op && file->f_op->get_unmapped_area)
1252
                get_area = file->f_op->get_unmapped_area;
1253
 
1254
        if (!get_area)
1255
                return -ENOSYS;
1256
 
1257
        return get_area(file, addr, len, pgoff, flags);
1258
}
1259
EXPORT_SYMBOL(get_unmapped_area);
1260
 
1261
/*
1262
 * Check that a process has enough memory to allocate a new virtual
1263
 * mapping. 0 means there is enough memory for the allocation to
1264
 * succeed and -ENOMEM implies there is not.
1265
 *
1266
 * We currently support three overcommit policies, which are set via the
1267
 * vm.overcommit_memory sysctl.  See Documentation/vm/overcommit-accounting
1268
 *
1269
 * Strict overcommit modes added 2002 Feb 26 by Alan Cox.
1270
 * Additional code 2002 Jul 20 by Robert Love.
1271
 *
1272
 * cap_sys_admin is 1 if the process has admin privileges, 0 otherwise.
1273
 *
1274
 * Note this is a helper function intended to be used by LSMs which
1275
 * wish to use this logic.
1276
 */
1277
int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin)
1278
{
1279
        unsigned long free, allowed;
1280
 
1281
        vm_acct_memory(pages);
1282
 
1283
        /*
1284
         * Sometimes we want to use more memory than we have
1285
         */
1286
        if (sysctl_overcommit_memory == OVERCOMMIT_ALWAYS)
1287
                return 0;
1288
 
1289
        if (sysctl_overcommit_memory == OVERCOMMIT_GUESS) {
1290
                unsigned long n;
1291
 
1292
                free = global_page_state(NR_FILE_PAGES);
1293
                free += nr_swap_pages;
1294
 
1295
                /*
1296
                 * Any slabs which are created with the
1297
                 * SLAB_RECLAIM_ACCOUNT flag claim to have contents
1298
                 * which are reclaimable, under pressure.  The dentry
1299
                 * cache and most inode caches should fall into this
1300
                 */
1301
                free += global_page_state(NR_SLAB_RECLAIMABLE);
1302
 
1303
                /*
1304
                 * Leave the last 3% for root
1305
                 */
1306
                if (!cap_sys_admin)
1307
                        free -= free / 32;
1308
 
1309
                if (free > pages)
1310
                        return 0;
1311
 
1312
                /*
1313
                 * nr_free_pages() is very expensive on large systems,
1314
                 * only call if we're about to fail.
1315
                 */
1316
                n = nr_free_pages();
1317
 
1318
                /*
1319
                 * Leave reserved pages. The pages are not for anonymous pages.
1320
                 */
1321
                if (n <= totalreserve_pages)
1322
                        goto error;
1323
                else
1324
                        n -= totalreserve_pages;
1325
 
1326
                /*
1327
                 * Leave the last 3% for root
1328
                 */
1329
                if (!cap_sys_admin)
1330
                        n -= n / 32;
1331
                free += n;
1332
 
1333
                if (free > pages)
1334
                        return 0;
1335
 
1336
                goto error;
1337
        }
1338
 
1339
        allowed = totalram_pages * sysctl_overcommit_ratio / 100;
1340
        /*
1341
         * Leave the last 3% for root
1342
         */
1343
        if (!cap_sys_admin)
1344
                allowed -= allowed / 32;
1345
        allowed += total_swap_pages;
1346
 
1347
        /* Don't let a single process grow too big:
1348
           leave 3% of the size of this process for other processes */
1349
        allowed -= current->mm->total_vm / 32;
1350
 
1351
        /*
1352
         * cast `allowed' as a signed long because vm_committed_space
1353
         * sometimes has a negative value
1354
         */
1355
        if (atomic_read(&vm_committed_space) < (long)allowed)
1356
                return 0;
1357
error:
1358
        vm_unacct_memory(pages);
1359
 
1360
        return -ENOMEM;
1361
}
1362
 
1363
int in_gate_area_no_task(unsigned long addr)
1364
{
1365
        return 0;
1366
}
1367
 
1368
int filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1369
{
1370
        BUG();
1371
        return 0;
1372
}
1373
EXPORT_SYMBOL(filemap_fault);
1374
 
1375
/*
1376
 * Access another process' address space.
1377
 * - source/target buffer must be kernel space
1378
 */
1379
int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write)
1380
{
1381
        struct vm_area_struct *vma;
1382
        struct mm_struct *mm;
1383
 
1384
        if (addr + len < addr)
1385
                return 0;
1386
 
1387
        mm = get_task_mm(tsk);
1388
        if (!mm)
1389
                return 0;
1390
 
1391
        down_read(&mm->mmap_sem);
1392
 
1393
        /* the access must start within one of the target process's mappings */
1394
        vma = find_vma(mm, addr);
1395
        if (vma) {
1396
                /* don't overrun this mapping */
1397
                if (addr + len >= vma->vm_end)
1398
                        len = vma->vm_end - addr;
1399
 
1400
                /* only read or write mappings where it is permitted */
1401
                if (write && vma->vm_flags & VM_MAYWRITE)
1402
                        len -= copy_to_user((void *) addr, buf, len);
1403
                else if (!write && vma->vm_flags & VM_MAYREAD)
1404
                        len -= copy_from_user(buf, (void *) addr, len);
1405
                else
1406
                        len = 0;
1407
        } else {
1408
                len = 0;
1409
        }
1410
 
1411
        up_read(&mm->mmap_sem);
1412
        mmput(mm);
1413
        return len;
1414
}

powered by: WebSVN 2.1.0

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