aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/mem.c')
-rw-r--r--drivers/char/mem.c42
1 files changed, 30 insertions, 12 deletions
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 91dd669273e0..5b2d18035073 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -101,6 +101,11 @@ static inline int valid_phys_addr_range(unsigned long addr, size_t *count)
101 101
102 return 1; 102 return 1;
103} 103}
104
105static inline int valid_mmap_phys_addr_range(unsigned long addr, size_t *size)
106{
107 return 1;
108}
104#endif 109#endif
105 110
106/* 111/*
@@ -228,26 +233,36 @@ static ssize_t write_mem(struct file * file, const char __user * buf,
228 return written; 233 return written;
229} 234}
230 235
236#ifndef __HAVE_PHYS_MEM_ACCESS_PROT
237static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
238 unsigned long size, pgprot_t vma_prot)
239{
240#ifdef pgprot_noncached
241 unsigned long offset = pfn << PAGE_SHIFT;
242
243 if (uncached_access(file, offset))
244 return pgprot_noncached(vma_prot);
245#endif
246 return vma_prot;
247}
248#endif
249
231static int mmap_mem(struct file * file, struct vm_area_struct * vma) 250static int mmap_mem(struct file * file, struct vm_area_struct * vma)
232{ 251{
233#if defined(__HAVE_PHYS_MEM_ACCESS_PROT) 252 size_t size = vma->vm_end - vma->vm_start;
253
254 if (!valid_mmap_phys_addr_range(vma->vm_pgoff << PAGE_SHIFT, &size))
255 return -EINVAL;
256
234 vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff, 257 vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
235 vma->vm_end - vma->vm_start, 258 size,
236 vma->vm_page_prot); 259 vma->vm_page_prot);
237#elif defined(pgprot_noncached)
238 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
239 int uncached;
240
241 uncached = uncached_access(file, offset);
242 if (uncached)
243 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
244#endif
245 260
246 /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */ 261 /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */
247 if (remap_pfn_range(vma, 262 if (remap_pfn_range(vma,
248 vma->vm_start, 263 vma->vm_start,
249 vma->vm_pgoff, 264 vma->vm_pgoff,
250 vma->vm_end-vma->vm_start, 265 size,
251 vma->vm_page_prot)) 266 vma->vm_page_prot))
252 return -EAGAIN; 267 return -EAGAIN;
253 return 0; 268 return 0;
@@ -817,7 +832,7 @@ static ssize_t kmsg_write(struct file * file, const char __user * buf,
817 size_t count, loff_t *ppos) 832 size_t count, loff_t *ppos)
818{ 833{
819 char *tmp; 834 char *tmp;
820 int ret; 835 ssize_t ret;
821 836
822 tmp = kmalloc(count + 1, GFP_KERNEL); 837 tmp = kmalloc(count + 1, GFP_KERNEL);
823 if (tmp == NULL) 838 if (tmp == NULL)
@@ -826,6 +841,9 @@ static ssize_t kmsg_write(struct file * file, const char __user * buf,
826 if (!copy_from_user(tmp, buf, count)) { 841 if (!copy_from_user(tmp, buf, count)) {
827 tmp[count] = 0; 842 tmp[count] = 0;
828 ret = printk("%s", tmp); 843 ret = printk("%s", tmp);
844 if (ret > count)
845 /* printk can add a prefix */
846 ret = count;
829 } 847 }
830 kfree(tmp); 848 kfree(tmp);
831 return ret; 849 return ret;