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.c54
1 files changed, 35 insertions, 19 deletions
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 1f528fad3516..8fc04b4f311f 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -47,10 +47,7 @@ static inline unsigned long size_inside_page(unsigned long start,
47#ifndef ARCH_HAS_VALID_PHYS_ADDR_RANGE 47#ifndef ARCH_HAS_VALID_PHYS_ADDR_RANGE
48static 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)
49{ 49{
50 if (addr + count > __pa(high_memory)) 50 return addr + count <= __pa(high_memory);
51 return 0;
52
53 return 1;
54} 51}
55 52
56static inline int valid_mmap_phys_addr_range(unsigned long pfn, size_t size) 53static inline int valid_mmap_phys_addr_range(unsigned long pfn, size_t size)
@@ -805,32 +802,46 @@ static const struct file_operations full_fops = {
805static const struct file_operations oldmem_fops = { 802static const struct file_operations oldmem_fops = {
806 .read = read_oldmem, 803 .read = read_oldmem,
807 .open = open_oldmem, 804 .open = open_oldmem,
805 .llseek = default_llseek,
808}; 806};
809#endif 807#endif
810 808
811static ssize_t kmsg_write(struct file *file, const char __user *buf, 809static ssize_t kmsg_writev(struct kiocb *iocb, const struct iovec *iv,
812 size_t count, loff_t *ppos) 810 unsigned long count, loff_t pos)
813{ 811{
814 char *tmp; 812 char *line, *p;
815 ssize_t ret; 813 int i;
814 ssize_t ret = -EFAULT;
815 size_t len = iov_length(iv, count);
816 816
817 tmp = kmalloc(count + 1, GFP_KERNEL); 817 line = kmalloc(len + 1, GFP_KERNEL);
818 if (tmp == NULL) 818 if (line == NULL)
819 return -ENOMEM; 819 return -ENOMEM;
820 ret = -EFAULT; 820
821 if (!copy_from_user(tmp, buf, count)) { 821 /*
822 tmp[count] = 0; 822 * copy all vectors into a single string, to ensure we do
823 ret = printk("%s", tmp); 823 * not interleave our log line with other printk calls
824 if (ret > count) 824 */
825 /* printk can add a prefix */ 825 p = line;
826 ret = count; 826 for (i = 0; i < count; i++) {
827 if (copy_from_user(p, iv[i].iov_base, iv[i].iov_len))
828 goto out;
829 p += iv[i].iov_len;
827 } 830 }
828 kfree(tmp); 831 p[0] = '\0';
832
833 ret = printk("%s", line);
834 /* printk can add a prefix */
835 if (ret > len)
836 ret = len;
837out:
838 kfree(line);
829 return ret; 839 return ret;
830} 840}
831 841
832static const struct file_operations kmsg_fops = { 842static const struct file_operations kmsg_fops = {
833 .write = kmsg_write, 843 .aio_write = kmsg_writev,
844 .llseek = noop_llseek,
834}; 845};
835 846
836static const struct memdev { 847static const struct memdev {
@@ -874,6 +885,10 @@ static int memory_open(struct inode *inode, struct file *filp)
874 if (dev->dev_info) 885 if (dev->dev_info)
875 filp->f_mapping->backing_dev_info = dev->dev_info; 886 filp->f_mapping->backing_dev_info = dev->dev_info;
876 887
888 /* Is /dev/mem or /dev/kmem ? */
889 if (dev->dev_info == &directly_mappable_cdev_bdi)
890 filp->f_mode |= FMODE_UNSIGNED_OFFSET;
891
877 if (dev->fops->open) 892 if (dev->fops->open)
878 return dev->fops->open(inode, filp); 893 return dev->fops->open(inode, filp);
879 894
@@ -882,6 +897,7 @@ static int memory_open(struct inode *inode, struct file *filp)
882 897
883static const struct file_operations memory_fops = { 898static const struct file_operations memory_fops = {
884 .open = memory_open, 899 .open = memory_open,
900 .llseek = noop_llseek,
885}; 901};
886 902
887static char *mem_devnode(struct device *dev, mode_t *mode) 903static char *mem_devnode(struct device *dev, mode_t *mode)