aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/mem.c39
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
242static 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 */
254static 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
261static inline int private_mapping_ok(struct vm_area_struct *vma)
262{
263 return 1;
264}
265#endif
266
241static int mmap_mem(struct file * file, struct vm_area_struct * vma) 267static 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
787static const struct file_operations kmem_fops = { 817static 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
795static const struct file_operations null_fops = { 826static 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 */
818static struct backing_dev_info zero_bdi = { 853static 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;