title: Linux kernel copy_to_user to user space display different result
body: <p>There some bugs reading from the user space with this application. Is my copy_to_user dont correctly?</p>
  
  <p>The following is the readout from terminal:</p>
  
  <pre><code>Press r to read from device or w to write the device r
  0x-1075024108 0x15123440 0xe70401 0xe6f8dc 0xe73524 
  0x0 0x15037588 0xbfec6f14 0xe57612 0xbfec6f34 
  0x15037140 0x2 0xe57334 0xc6d690 0xd696910 
  0x-1075024080 0x15071734 0xc737c9 0x804835a 0x2 
  </code></pre>
  
  <p>The following is the code from apps layer:</p>
  
  <pre><code>read(fd, read_buf, sizeof(read_buf));
  
  for(i=0;i&lt;=(BUFF_SIZE / sizeof(int));i+=5)
      printf(" 0x%x 0x%x 0x%x 0x%x 0x%x \n", 
          read_buf[i],read_buf[i+1],read_buf[i+2],
          read_buf[i+3],read_buf[i+4]);
  break;
  </code></pre>
  
  <p>and the following is my driver code:</p>
  
  <pre><code>#include &lt;linux/version.h&gt;
  #include &lt;linux/init.h&gt;
  #include &lt;linux/module.h&gt;
  #include &lt;linux/fs.h&gt;
  #include &lt;linux/cdev.h&gt;
  #include &lt;linux/slab.h&gt;
  #include &lt;linux/vmalloc.h&gt;
  #include &lt;linux/mm.h&gt;
  #ifdef MODVERSIONS
  #  include &lt;linux/modversions.h&gt;
  #endif
  #include &lt;asm/io.h&gt;
  #include &lt;asm/uaccess.h&gt; // required for copy_from and copy_to user 
  
  /* character device structures */
  static dev_t mmap_dev;
  static struct cdev mmap_cdev;
  
  /* methods of the character device */
  static int mmap_open(struct inode *inode, struct file *filp);
  static int mmap_release(struct inode *inode, struct file *filp);
  
  
  /* the file operations, i.e. all character device methods */
  static struct file_operations mmap_fops = {
      .open   = mmap_open,
      .release= mmap_release,
      .owner  = THIS_MODULE,
  };
  static int *vmalloc_area;
  
  #define NPAGES      1//16
  #define BUFF_SIZE   64 // bytes
  
  /* character device open method */
  static int mmap_open(struct inode *inode, struct file *filp)
  {
      return 0;
  }
  
  /* character device last close method */
  static int mmap_release(struct inode *inode, struct file *filp)
  {
      return 0;
  }
  
  ssize_t read(struct file *filp, int *buff, size_t count, loff_t *offp) 
  {
      unsigned long bytes_left;
  
      printk("Inside read \n");
  
      bytes_left = copy_to_user(buff, vmalloc_area , count);
  
      if(bytes_left&lt;0)
      bytes_left =  -EFAULT;
  
      return bytes_left;
  }
  
  /* module initialization - called at module load time */
  static int __init membuff_init(void)
  {
      int ret = 0, i =0;
  
      printk(KERN_ERR "@membuff_init\n");
  
      /* allocate a memory area with vmalloc. */
      if ((vmalloc_area = vmalloc(BUFF_SIZE)) == NULL) {
          ret = -ENOMEM;
          goto out_vfree;
      }
  
      /* get the major number of the character device */
      if( (ret = alloc_chrdev_region(&amp;mmap_dev, 0, 1, "mmap")) &lt; 0) {
          printk(KERN_ERR "@membuff_init could not allocate major number for mmap\n");
          goto out_vfree;
      }
      printk(KERN_ERR "@membuff_init Major number for mmap: %d\n",MAJOR(mmap_dev));
  
      /* initialize the device structure and register the device with the kernel */
      cdev_init(&amp;mmap_cdev, &amp;mmap_fops);
      if ((ret = cdev_add(&amp;mmap_cdev, mmap_dev, 1)) &lt; 0) {
          printk(KERN_ERR "@membuff_init could not allocate chrdev for mmap\n");
          goto out_unalloc_region;
      }
  
      for (i = 0; i &lt; (BUFF_SIZE / sizeof(int)); i +=1) {
      vmalloc_area[i] = i;
      printk(KERN_ERR "@membuff_init: %d\n",vmalloc_area[i]);
      }
      return ret;
  
      out_unalloc_region:
      unregister_chrdev_region(mmap_dev, 1);
      out_vfree:
      if(vmalloc_area)
      vfree(vmalloc_area);
      return ret;
  }
  
  /* module unload */
  static void __exit mmap_exit(void)
  {
  if(vmalloc_area)
  vfree(vmalloc_area);
  
  /* remove the character deivce */
  cdev_del(&amp;mmap_cdev);
  unregister_chrdev_region(mmap_dev, 1);
  
  printk(KERN_ERR "@mmap_exit\n");
  }
  
  module_init(membuff_init);
  module_exit(mmap_exit);
  MODULE_DESCRIPTION("trying out copy_to_user");
  MODULE_LICENSE("Dual BSD/GPL");
  </code></pre>