aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/mem.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2010-05-02 23:28:58 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2010-05-02 23:28:58 -0400
commitdf2071bd081408318d659cd14a9cf6ff23d874c9 (patch)
treeb31291b5fd4b9f84c629833afbfaa8d431857475 /drivers/char/mem.c
parent97e3d94aac1c3e95bd04d1b186479a4df3663ab8 (diff)
parentbe1066bbcd443a65df312fdecea7e4959adedb45 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'drivers/char/mem.c')
-rw-r--r--drivers/char/mem.c197
1 files changed, 102 insertions, 95 deletions
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 48788db4e280..f54dab8acdcd 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds 4 * Copyright (C) 1991, 1992 Linus Torvalds
5 * 5 *
6 * Added devfs support. 6 * Added devfs support.
7 * Jan-11-1998, C. Scott Ananian <cananian@alumni.princeton.edu> 7 * Jan-11-1998, C. Scott Ananian <cananian@alumni.princeton.edu>
8 * Shared /dev/zero mmapping support, Feb 2000, Kanoj Sarcar <kanoj@sgi.com> 8 * Shared /dev/zero mmapping support, Feb 2000, Kanoj Sarcar <kanoj@sgi.com>
9 */ 9 */
@@ -44,36 +44,6 @@ static inline unsigned long size_inside_page(unsigned long start,
44 return min(sz, size); 44 return min(sz, size);
45} 45}
46 46
47/*
48 * Architectures vary in how they handle caching for addresses
49 * outside of main memory.
50 *
51 */
52static inline int uncached_access(struct file *file, unsigned long addr)
53{
54#if defined(CONFIG_IA64)
55 /*
56 * On ia64, we ignore O_DSYNC because we cannot tolerate memory attribute aliases.
57 */
58 return !(efi_mem_attributes(addr) & EFI_MEMORY_WB);
59#elif defined(CONFIG_MIPS)
60 {
61 extern int __uncached_access(struct file *file,
62 unsigned long addr);
63
64 return __uncached_access(file, addr);
65 }
66#else
67 /*
68 * Accessing memory above the top the kernel knows about or through a file pointer
69 * that was marked O_DSYNC will be done non-cached.
70 */
71 if (file->f_flags & O_DSYNC)
72 return 1;
73 return addr >= __pa(high_memory);
74#endif
75}
76
77#ifndef ARCH_HAS_VALID_PHYS_ADDR_RANGE 47#ifndef ARCH_HAS_VALID_PHYS_ADDR_RANGE
78static inline int valid_phys_addr_range(unsigned long addr, size_t count) 48static inline int valid_phys_addr_range(unsigned long addr, size_t count)
79{ 49{
@@ -115,15 +85,15 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size)
115} 85}
116#endif 86#endif
117 87
118void __attribute__((weak)) unxlate_dev_mem_ptr(unsigned long phys, void *addr) 88void __weak unxlate_dev_mem_ptr(unsigned long phys, void *addr)
119{ 89{
120} 90}
121 91
122/* 92/*
123 * This funcion reads the *physical* memory. The f_pos points directly to the 93 * This funcion reads the *physical* memory. The f_pos points directly to the
124 * memory location. 94 * memory location.
125 */ 95 */
126static ssize_t read_mem(struct file * file, char __user * buf, 96static ssize_t read_mem(struct file *file, char __user *buf,
127 size_t count, loff_t *ppos) 97 size_t count, loff_t *ppos)
128{ 98{
129 unsigned long p = *ppos; 99 unsigned long p = *ppos;
@@ -140,10 +110,10 @@ static ssize_t read_mem(struct file * file, char __user * buf,
140 if (sz > 0) { 110 if (sz > 0) {
141 if (clear_user(buf, sz)) 111 if (clear_user(buf, sz))
142 return -EFAULT; 112 return -EFAULT;
143 buf += sz; 113 buf += sz;
144 p += sz; 114 p += sz;
145 count -= sz; 115 count -= sz;
146 read += sz; 116 read += sz;
147 } 117 }
148 } 118 }
149#endif 119#endif
@@ -157,9 +127,9 @@ static ssize_t read_mem(struct file * file, char __user * buf,
157 return -EPERM; 127 return -EPERM;
158 128
159 /* 129 /*
160 * On ia64 if a page has been mapped somewhere as 130 * On ia64 if a page has been mapped somewhere as uncached, then
161 * uncached, then it must also be accessed uncached 131 * it must also be accessed uncached by the kernel or data
162 * by the kernel or data corruption may occur 132 * corruption may occur.
163 */ 133 */
164 ptr = xlate_dev_mem_ptr(p); 134 ptr = xlate_dev_mem_ptr(p);
165 if (!ptr) 135 if (!ptr)
@@ -180,7 +150,7 @@ static ssize_t read_mem(struct file * file, char __user * buf,
180 return read; 150 return read;
181} 151}
182 152
183static ssize_t write_mem(struct file * file, const char __user * buf, 153static ssize_t write_mem(struct file *file, const char __user *buf,
184 size_t count, loff_t *ppos) 154 size_t count, loff_t *ppos)
185{ 155{
186 unsigned long p = *ppos; 156 unsigned long p = *ppos;
@@ -212,9 +182,9 @@ static ssize_t write_mem(struct file * file, const char __user * buf,
212 return -EPERM; 182 return -EPERM;
213 183
214 /* 184 /*
215 * On ia64 if a page has been mapped somewhere as 185 * On ia64 if a page has been mapped somewhere as uncached, then
216 * uncached, then it must also be accessed uncached 186 * it must also be accessed uncached by the kernel or data
217 * by the kernel or data corruption may occur 187 * corruption may occur.
218 */ 188 */
219 ptr = xlate_dev_mem_ptr(p); 189 ptr = xlate_dev_mem_ptr(p);
220 if (!ptr) { 190 if (!ptr) {
@@ -242,13 +212,48 @@ static ssize_t write_mem(struct file * file, const char __user * buf,
242 return written; 212 return written;
243} 213}
244 214
245int __attribute__((weak)) phys_mem_access_prot_allowed(struct file *file, 215int __weak phys_mem_access_prot_allowed(struct file *file,
246 unsigned long pfn, unsigned long size, pgprot_t *vma_prot) 216 unsigned long pfn, unsigned long size, pgprot_t *vma_prot)
247{ 217{
248 return 1; 218 return 1;
249} 219}
250 220
251#ifndef __HAVE_PHYS_MEM_ACCESS_PROT 221#ifndef __HAVE_PHYS_MEM_ACCESS_PROT
222
223/*
224 * Architectures vary in how they handle caching for addresses
225 * outside of main memory.
226 *
227 */
228#ifdef pgprot_noncached
229static int uncached_access(struct file *file, unsigned long addr)
230{
231#if defined(CONFIG_IA64)
232 /*
233 * On ia64, we ignore O_DSYNC because we cannot tolerate memory
234 * attribute aliases.
235 */
236 return !(efi_mem_attributes(addr) & EFI_MEMORY_WB);
237#elif defined(CONFIG_MIPS)
238 {
239 extern int __uncached_access(struct file *file,
240 unsigned long addr);
241
242 return __uncached_access(file, addr);
243 }
244#else
245 /*
246 * Accessing memory above the top the kernel knows about or through a
247 * file pointer
248 * that was marked O_DSYNC will be done non-cached.
249 */
250 if (file->f_flags & O_DSYNC)
251 return 1;
252 return addr >= __pa(high_memory);
253#endif
254}
255#endif
256
252static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, 257static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
253 unsigned long size, pgprot_t vma_prot) 258 unsigned long size, pgprot_t vma_prot)
254{ 259{
@@ -294,7 +299,7 @@ static const struct vm_operations_struct mmap_mem_ops = {
294#endif 299#endif
295}; 300};
296 301
297static int mmap_mem(struct file * file, struct vm_area_struct * vma) 302static int mmap_mem(struct file *file, struct vm_area_struct *vma)
298{ 303{
299 size_t size = vma->vm_end - vma->vm_start; 304 size_t size = vma->vm_end - vma->vm_start;
300 305
@@ -329,7 +334,7 @@ static int mmap_mem(struct file * file, struct vm_area_struct * vma)
329} 334}
330 335
331#ifdef CONFIG_DEVKMEM 336#ifdef CONFIG_DEVKMEM
332static int mmap_kmem(struct file * file, struct vm_area_struct * vma) 337static int mmap_kmem(struct file *file, struct vm_area_struct *vma)
333{ 338{
334 unsigned long pfn; 339 unsigned long pfn;
335 340
@@ -337,9 +342,9 @@ static int mmap_kmem(struct file * file, struct vm_area_struct * vma)
337 pfn = __pa((u64)vma->vm_pgoff << PAGE_SHIFT) >> PAGE_SHIFT; 342 pfn = __pa((u64)vma->vm_pgoff << PAGE_SHIFT) >> PAGE_SHIFT;
338 343
339 /* 344 /*
340 * RED-PEN: on some architectures there is more mapped memory 345 * RED-PEN: on some architectures there is more mapped memory than
341 * than available in mem_map which pfn_valid checks 346 * available in mem_map which pfn_valid checks for. Perhaps should add a
342 * for. Perhaps should add a new macro here. 347 * new macro here.
343 * 348 *
344 * RED-PEN: vmalloc is not supported right now. 349 * RED-PEN: vmalloc is not supported right now.
345 */ 350 */
@@ -389,7 +394,7 @@ static ssize_t read_oldmem(struct file *file, char __user *buf,
389/* 394/*
390 * This function reads the *virtual* memory as seen by the kernel. 395 * This function reads the *virtual* memory as seen by the kernel.
391 */ 396 */
392static ssize_t read_kmem(struct file *file, char __user *buf, 397static ssize_t read_kmem(struct file *file, char __user *buf,
393 size_t count, loff_t *ppos) 398 size_t count, loff_t *ppos)
394{ 399{
395 unsigned long p = *ppos; 400 unsigned long p = *ppos;
@@ -400,8 +405,8 @@ static ssize_t read_kmem(struct file *file, char __user *buf,
400 read = 0; 405 read = 0;
401 if (p < (unsigned long) high_memory) { 406 if (p < (unsigned long) high_memory) {
402 low_count = count; 407 low_count = count;
403 if (count > (unsigned long) high_memory - p) 408 if (count > (unsigned long)high_memory - p)
404 low_count = (unsigned long) high_memory - p; 409 low_count = (unsigned long)high_memory - p;
405 410
406#ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED 411#ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
407 /* we don't have page 0 mapped on sparc and m68k.. */ 412 /* we don't have page 0 mapped on sparc and m68k.. */
@@ -465,9 +470,8 @@ static ssize_t read_kmem(struct file *file, char __user *buf,
465} 470}
466 471
467 472
468static inline ssize_t 473static ssize_t do_write_kmem(unsigned long p, const char __user *buf,
469do_write_kmem(unsigned long p, const char __user *buf, 474 size_t count, loff_t *ppos)
470 size_t count, loff_t *ppos)
471{ 475{
472 ssize_t written, sz; 476 ssize_t written, sz;
473 unsigned long copied; 477 unsigned long copied;
@@ -491,9 +495,9 @@ do_write_kmem(unsigned long p, const char __user *buf,
491 sz = size_inside_page(p, count); 495 sz = size_inside_page(p, count);
492 496
493 /* 497 /*
494 * On ia64 if a page has been mapped somewhere as 498 * On ia64 if a page has been mapped somewhere as uncached, then
495 * uncached, then it must also be accessed uncached 499 * it must also be accessed uncached by the kernel or data
496 * by the kernel or data corruption may occur 500 * corruption may occur.
497 */ 501 */
498 ptr = xlate_dev_kmem_ptr((char *)p); 502 ptr = xlate_dev_kmem_ptr((char *)p);
499 503
@@ -514,11 +518,10 @@ do_write_kmem(unsigned long p, const char __user *buf,
514 return written; 518 return written;
515} 519}
516 520
517
518/* 521/*
519 * This function writes to the *virtual* memory as seen by the kernel. 522 * This function writes to the *virtual* memory as seen by the kernel.
520 */ 523 */
521static ssize_t write_kmem(struct file * file, const char __user * buf, 524static ssize_t write_kmem(struct file *file, const char __user *buf,
522 size_t count, loff_t *ppos) 525 size_t count, loff_t *ppos)
523{ 526{
524 unsigned long p = *ppos; 527 unsigned long p = *ppos;
@@ -570,17 +573,17 @@ static ssize_t write_kmem(struct file * file, const char __user * buf,
570#endif 573#endif
571 574
572#ifdef CONFIG_DEVPORT 575#ifdef CONFIG_DEVPORT
573static ssize_t read_port(struct file * file, char __user * buf, 576static ssize_t read_port(struct file *file, char __user *buf,
574 size_t count, loff_t *ppos) 577 size_t count, loff_t *ppos)
575{ 578{
576 unsigned long i = *ppos; 579 unsigned long i = *ppos;
577 char __user *tmp = buf; 580 char __user *tmp = buf;
578 581
579 if (!access_ok(VERIFY_WRITE, buf, count)) 582 if (!access_ok(VERIFY_WRITE, buf, count))
580 return -EFAULT; 583 return -EFAULT;
581 while (count-- > 0 && i < 65536) { 584 while (count-- > 0 && i < 65536) {
582 if (__put_user(inb(i),tmp) < 0) 585 if (__put_user(inb(i), tmp) < 0)
583 return -EFAULT; 586 return -EFAULT;
584 i++; 587 i++;
585 tmp++; 588 tmp++;
586 } 589 }
@@ -588,22 +591,22 @@ static ssize_t read_port(struct file * file, char __user * buf,
588 return tmp-buf; 591 return tmp-buf;
589} 592}
590 593
591static ssize_t write_port(struct file * file, const char __user * buf, 594static ssize_t write_port(struct file *file, const char __user *buf,
592 size_t count, loff_t *ppos) 595 size_t count, loff_t *ppos)
593{ 596{
594 unsigned long i = *ppos; 597 unsigned long i = *ppos;
595 const char __user * tmp = buf; 598 const char __user * tmp = buf;
596 599
597 if (!access_ok(VERIFY_READ,buf,count)) 600 if (!access_ok(VERIFY_READ, buf, count))
598 return -EFAULT; 601 return -EFAULT;
599 while (count-- > 0 && i < 65536) { 602 while (count-- > 0 && i < 65536) {
600 char c; 603 char c;
601 if (__get_user(c, tmp)) { 604 if (__get_user(c, tmp)) {
602 if (tmp > buf) 605 if (tmp > buf)
603 break; 606 break;
604 return -EFAULT; 607 return -EFAULT;
605 } 608 }
606 outb(c,i); 609 outb(c, i);
607 i++; 610 i++;
608 tmp++; 611 tmp++;
609 } 612 }
@@ -612,13 +615,13 @@ static ssize_t write_port(struct file * file, const char __user * buf,
612} 615}
613#endif 616#endif
614 617
615static ssize_t read_null(struct file * file, char __user * buf, 618static ssize_t read_null(struct file *file, char __user *buf,
616 size_t count, loff_t *ppos) 619 size_t count, loff_t *ppos)
617{ 620{
618 return 0; 621 return 0;
619} 622}
620 623
621static ssize_t write_null(struct file * file, const char __user * buf, 624static ssize_t write_null(struct file *file, const char __user *buf,
622 size_t count, loff_t *ppos) 625 size_t count, loff_t *ppos)
623{ 626{
624 return count; 627 return count;
@@ -630,13 +633,13 @@ static int pipe_to_null(struct pipe_inode_info *info, struct pipe_buffer *buf,
630 return sd->len; 633 return sd->len;
631} 634}
632 635
633static ssize_t splice_write_null(struct pipe_inode_info *pipe,struct file *out, 636static ssize_t splice_write_null(struct pipe_inode_info *pipe, struct file *out,
634 loff_t *ppos, size_t len, unsigned int flags) 637 loff_t *ppos, size_t len, unsigned int flags)
635{ 638{
636 return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_null); 639 return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_null);
637} 640}
638 641
639static ssize_t read_zero(struct file * file, char __user * buf, 642static ssize_t read_zero(struct file *file, char __user *buf,
640 size_t count, loff_t *ppos) 643 size_t count, loff_t *ppos)
641{ 644{
642 size_t written; 645 size_t written;
@@ -667,7 +670,7 @@ static ssize_t read_zero(struct file * file, char __user * buf,
667 return written ? written : -EFAULT; 670 return written ? written : -EFAULT;
668} 671}
669 672
670static int mmap_zero(struct file * file, struct vm_area_struct * vma) 673static int mmap_zero(struct file *file, struct vm_area_struct *vma)
671{ 674{
672#ifndef CONFIG_MMU 675#ifndef CONFIG_MMU
673 return -ENOSYS; 676 return -ENOSYS;
@@ -677,7 +680,7 @@ static int mmap_zero(struct file * file, struct vm_area_struct * vma)
677 return 0; 680 return 0;
678} 681}
679 682
680static ssize_t write_full(struct file * file, const char __user * buf, 683static ssize_t write_full(struct file *file, const char __user *buf,
681 size_t count, loff_t *ppos) 684 size_t count, loff_t *ppos)
682{ 685{
683 return -ENOSPC; 686 return -ENOSPC;
@@ -688,8 +691,7 @@ static ssize_t write_full(struct file * file, const char __user * buf,
688 * can fopen() both devices with "a" now. This was previously impossible. 691 * can fopen() both devices with "a" now. This was previously impossible.
689 * -- SRB. 692 * -- SRB.
690 */ 693 */
691 694static loff_t null_lseek(struct file *file, loff_t offset, int orig)
692static loff_t null_lseek(struct file * file, loff_t offset, int orig)
693{ 695{
694 return file->f_pos = 0; 696 return file->f_pos = 0;
695} 697}
@@ -702,24 +704,26 @@ static loff_t null_lseek(struct file * file, loff_t offset, int orig)
702 * also note that seeking relative to the "end of file" isn't supported: 704 * also note that seeking relative to the "end of file" isn't supported:
703 * it has no meaning, so it returns -EINVAL. 705 * it has no meaning, so it returns -EINVAL.
704 */ 706 */
705static loff_t memory_lseek(struct file * file, loff_t offset, int orig) 707static loff_t memory_lseek(struct file *file, loff_t offset, int orig)
706{ 708{
707 loff_t ret; 709 loff_t ret;
708 710
709 mutex_lock(&file->f_path.dentry->d_inode->i_mutex); 711 mutex_lock(&file->f_path.dentry->d_inode->i_mutex);
710 switch (orig) { 712 switch (orig) {
711 case 0: 713 case SEEK_CUR:
712 file->f_pos = offset; 714 offset += file->f_pos;
713 ret = file->f_pos; 715 case SEEK_SET:
714 force_successful_syscall_return(); 716 /* to avoid userland mistaking f_pos=-9 as -EBADF=-9 */
715 break; 717 if ((unsigned long long)offset >= ~0xFFFULL) {
716 case 1: 718 ret = -EOVERFLOW;
717 file->f_pos += offset;
718 ret = file->f_pos;
719 force_successful_syscall_return();
720 break; 719 break;
721 default: 720 }
722 ret = -EINVAL; 721 file->f_pos = offset;
722 ret = file->f_pos;
723 force_successful_syscall_return();
724 break;
725 default:
726 ret = -EINVAL;
723 } 727 }
724 mutex_unlock(&file->f_path.dentry->d_inode->i_mutex); 728 mutex_unlock(&file->f_path.dentry->d_inode->i_mutex);
725 return ret; 729 return ret;
@@ -803,7 +807,7 @@ static const struct file_operations oldmem_fops = {
803}; 807};
804#endif 808#endif
805 809
806static ssize_t kmsg_write(struct file * file, const char __user * buf, 810static ssize_t kmsg_write(struct file *file, const char __user *buf,
807 size_t count, loff_t *ppos) 811 size_t count, loff_t *ppos)
808{ 812{
809 char *tmp; 813 char *tmp;
@@ -825,7 +829,7 @@ static ssize_t kmsg_write(struct file * file, const char __user * buf,
825} 829}
826 830
827static const struct file_operations kmsg_fops = { 831static const struct file_operations kmsg_fops = {
828 .write = kmsg_write, 832 .write = kmsg_write,
829}; 833};
830 834
831static const struct memdev { 835static const struct memdev {
@@ -876,7 +880,7 @@ static int memory_open(struct inode *inode, struct file *filp)
876} 880}
877 881
878static const struct file_operations memory_fops = { 882static const struct file_operations memory_fops = {
879 .open = memory_open, 883 .open = memory_open,
880}; 884};
881 885
882static char *mem_devnode(struct device *dev, mode_t *mode) 886static char *mem_devnode(struct device *dev, mode_t *mode)
@@ -897,10 +901,13 @@ static int __init chr_dev_init(void)
897 if (err) 901 if (err)
898 return err; 902 return err;
899 903
900 if (register_chrdev(MEM_MAJOR,"mem",&memory_fops)) 904 if (register_chrdev(MEM_MAJOR, "mem", &memory_fops))
901 printk("unable to get major %d for memory devs\n", MEM_MAJOR); 905 printk("unable to get major %d for memory devs\n", MEM_MAJOR);
902 906
903 mem_class = class_create(THIS_MODULE, "mem"); 907 mem_class = class_create(THIS_MODULE, "mem");
908 if (IS_ERR(mem_class))
909 return PTR_ERR(mem_class);
910
904 mem_class->devnode = mem_devnode; 911 mem_class->devnode = mem_devnode;
905 for (minor = 1; minor < ARRAY_SIZE(devlist); minor++) { 912 for (minor = 1; minor < ARRAY_SIZE(devlist); minor++) {
906 if (!devlist[minor].name) 913 if (!devlist[minor].name)