diff options
Diffstat (limited to 'drivers/char/mem.c')
| -rw-r--r-- | drivers/char/mem.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 917b20402664..4ac70ec697f0 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
| @@ -238,6 +238,32 @@ static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, | |||
| 238 | } | 238 | } |
| 239 | #endif | 239 | #endif |
| 240 | 240 | ||
| 241 | #ifndef CONFIG_MMU | ||
| 242 | static unsigned long get_unmapped_area_mem(struct file *file, | ||
| 243 | unsigned long addr, | ||
| 244 | unsigned long len, | ||
| 245 | unsigned long pgoff, | ||
| 246 | unsigned long flags) | ||
| 247 | { | ||
| 248 | if (!valid_mmap_phys_addr_range(pgoff, len)) | ||
| 249 | return (unsigned long) -EINVAL; | ||
| 250 | return pgoff; | ||
| 251 | } | ||
| 252 | |||
| 253 | /* can't do an in-place private mapping if there's no MMU */ | ||
| 254 | static inline int private_mapping_ok(struct vm_area_struct *vma) | ||
| 255 | { | ||
| 256 | return vma->vm_flags & VM_MAYSHARE; | ||
| 257 | } | ||
| 258 | #else | ||
| 259 | #define get_unmapped_area_mem NULL | ||
| 260 | |||
| 261 | static inline int private_mapping_ok(struct vm_area_struct *vma) | ||
| 262 | { | ||
| 263 | return 1; | ||
| 264 | } | ||
| 265 | #endif | ||
| 266 | |||
| 241 | static int mmap_mem(struct file * file, struct vm_area_struct * vma) | 267 | static int mmap_mem(struct file * file, struct vm_area_struct * vma) |
| 242 | { | 268 | { |
| 243 | size_t size = vma->vm_end - vma->vm_start; | 269 | size_t size = vma->vm_end - vma->vm_start; |
| @@ -245,6 +271,9 @@ static int mmap_mem(struct file * file, struct vm_area_struct * vma) | |||
| 245 | if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size)) | 271 | if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size)) |
| 246 | return -EINVAL; | 272 | return -EINVAL; |
| 247 | 273 | ||
| 274 | if (!private_mapping_ok(vma)) | ||
| 275 | return -ENOSYS; | ||
| 276 | |||
| 248 | vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff, | 277 | vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff, |
| 249 | size, | 278 | size, |
| 250 | vma->vm_page_prot); | 279 | vma->vm_page_prot); |
| @@ -782,6 +811,7 @@ static const struct file_operations mem_fops = { | |||
| 782 | .write = write_mem, | 811 | .write = write_mem, |
| 783 | .mmap = mmap_mem, | 812 | .mmap = mmap_mem, |
| 784 | .open = open_mem, | 813 | .open = open_mem, |
| 814 | .get_unmapped_area = get_unmapped_area_mem, | ||
| 785 | }; | 815 | }; |
| 786 | 816 | ||
| 787 | static const struct file_operations kmem_fops = { | 817 | static const struct file_operations kmem_fops = { |
| @@ -790,6 +820,7 @@ static const struct file_operations kmem_fops = { | |||
| 790 | .write = write_kmem, | 820 | .write = write_kmem, |
| 791 | .mmap = mmap_kmem, | 821 | .mmap = mmap_kmem, |
| 792 | .open = open_kmem, | 822 | .open = open_kmem, |
| 823 | .get_unmapped_area = get_unmapped_area_mem, | ||
| 793 | }; | 824 | }; |
| 794 | 825 | ||
| 795 | static const struct file_operations null_fops = { | 826 | static const struct file_operations null_fops = { |
| @@ -815,6 +846,10 @@ static const struct file_operations zero_fops = { | |||
| 815 | .mmap = mmap_zero, | 846 | .mmap = mmap_zero, |
| 816 | }; | 847 | }; |
| 817 | 848 | ||
| 849 | /* | ||
| 850 | * capabilities for /dev/zero | ||
| 851 | * - permits private mappings, "copies" are taken of the source of zeros | ||
| 852 | */ | ||
| 818 | static struct backing_dev_info zero_bdi = { | 853 | static struct backing_dev_info zero_bdi = { |
| 819 | .capabilities = BDI_CAP_MAP_COPY, | 854 | .capabilities = BDI_CAP_MAP_COPY, |
| 820 | }; | 855 | }; |
| @@ -862,9 +897,13 @@ static int memory_open(struct inode * inode, struct file * filp) | |||
| 862 | switch (iminor(inode)) { | 897 | switch (iminor(inode)) { |
| 863 | case 1: | 898 | case 1: |
| 864 | filp->f_op = &mem_fops; | 899 | filp->f_op = &mem_fops; |
| 900 | filp->f_mapping->backing_dev_info = | ||
| 901 | &directly_mappable_cdev_bdi; | ||
| 865 | break; | 902 | break; |
| 866 | case 2: | 903 | case 2: |
| 867 | filp->f_op = &kmem_fops; | 904 | filp->f_op = &kmem_fops; |
| 905 | filp->f_mapping->backing_dev_info = | ||
| 906 | &directly_mappable_cdev_bdi; | ||
| 868 | break; | 907 | break; |
| 869 | case 3: | 908 | case 3: |
| 870 | filp->f_op = &null_fops; | 909 | filp->f_op = &null_fops; |
