The first thing drivers/char/mem.c:read_kmem does is convert the loff_t it gets as the offset for reading into an unsigned int. This patch makes the kmem driver's llseek operator do that up-front, so that fs/read_write.c:rw_verify_area doesn't return -EINVAL when we try to read from higher addresses.
It's ugly but so is the existing code. And it won't fix 64-bit archs AFAICT. Tested on 2.6.11, patch offsets fixed up for 2.6.13-rc6. Signed-off-by: Chuck Ebbert <[EMAIL PROTECTED]> Index: 2.6.13-rc6/drivers/char/mem.c =================================================================== --- 2.6.13-rc6.orig/drivers/char/mem.c 2005-08-14 11:49:11.000000000 -0400 +++ 2.6.13-rc6/drivers/char/mem.c 2005-08-14 11:51:15.000000000 -0400 @@ -747,6 +747,29 @@ return ret; } +static loff_t kmem_lseek(struct file * file, loff_t offset, int orig) +{ + loff_t ret = -EINVAL; + + if (orig == 2) /* sys_seek/llseek has checked orig = {012} */ + goto out; + + down(&file->f_dentry->d_inode->i_sem); + switch (orig) { + case 0: + file->f_pos = offset; + break; + case 1: + file->f_pos += offset; + } + ret = file->f_pos; + file->f_pos = (loff_t)(unsigned long)file->f_pos; + force_successful_syscall_return(); + up(&file->f_dentry->d_inode->i_sem); +out: + return ret; +} + static int open_port(struct inode * inode, struct file * filp) { return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; @@ -769,7 +792,7 @@ }; static struct file_operations kmem_fops = { - .llseek = memory_lseek, + .llseek = kmem_lseek, .read = read_kmem, .write = write_kmem, .mmap = mmap_kmem, __ Chuck - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/