* Oops when using MAP_SHARED with do_mmap
@ 2000-11-14 12:05 aprasad
0 siblings, 0 replies; only message in thread
From: aprasad @ 2000-11-14 12:05 UTC (permalink / raw)
To: linux-kernel; +Cc: linux-mm
[-- Attachment #1: Type: text/plain, Size: 375 bytes --]
Hi,
I have written a simple char device which allocate a page size buffer and
maps this to user-land via mmap-ing. it works if i specify MAP_PRIVATE as
flag in do_mmap but i am getting oops with MAP_SHARED flag.
i am using 2.4-test10 kernel.
attached are files.
(See attached file: char.c)code for the module.
(See attached file: mmap.c)test code.
thanks and regards,
anil
[-- Attachment #2: char.c --]
[-- Type: application/octet-stream, Size: 4257 bytes --]
/*
*char.c -- the bare char module
*
*
*/
#ifndef __KERNEL__
#define __KERNEL__
#endif
#ifndef MODULE
#define MODULE
#endif
#ifndef EXPORT_SYMTAB
#define EXPORT_SYMTAB
#endif
#include <linux/module.h>
#include <linux/kernel.h> /* printk() */
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/string.h>
#include <linux/malloc.h> /* kmalloc() */
#include <linux/fs.h> /* everything... */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/proc_fs.h>
#include <linux/fcntl.h> /* O_ACCMODE */
#include <linux/mm.h>
#include <asm/mman.h>
#include <linux/slab.h>
#include <asm/ioctl.h>
#include <linux/wrapper.h>
#include <asm/system.h> /* cli(), *_flags */
#include <asm/segment.h>
#define CHAR_IOCTL 0x1a
#define I_CHAR_MMAP _IOWR(CHAR_IOCTL, 1,1024)
#define debug(fmt,args...) \
printk(KERN_DEBUG "%s, %s, %d", __FILE__, __FUNCTION__, __LINE__); \
printk(KERN_DEBUG, fmt, ##args);
static int perform_mmap(unsigned long);
static int test_mmap(struct file*, struct vm_area_struct *);
static int char_major=0;
static unsigned long physical=0;
static int flag=0;
/*
* open
*/
int
char_open (struct inode *inode, struct file *filp)
{
if( inode== NULL || filp == NULL)
{
return -ENODEV;
}
/*continue only if called in read or write or both mode*/
if ( (filp->f_flags & O_ACCMODE) == O_RDWR)
{
return 0; /*indicate succes*/
}
return -EACCES; /*returned access denied*/
}
int
char_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long usrptr)
{
int rc=0;
printk(KERN_DEBUG "%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__);
switch(cmd) {
case I_CHAR_MMAP:
rc = perform_mmap(usrptr);
break;
default:
rc = -EACCES;
break;
}
return rc;
}
/*
* The different file operations
*/
struct file_operations char_fops = {
read: NULL,
write: NULL,
open: char_open,
ioctl: char_ioctl
};
/*
* Finally, the module stuff
*/
int init_module(void)
{
int result;
/*
* Register the major number , and accept a dynamic number
*/
result = register_chrdev(char_major, "simplechar", &char_fops);
if (result < 0)
{
printk(KERN_WARNING "char: can't get major %d\n",char_major);
return result;
}
if (char_major == 0)
char_major = result; /* dynamic */
/*
* allocate the devices -- we can't have them static, as the number
* can be specified at load time
*/
printk("\ninitialization successful\n");
return 0; /* succeed */
}
void cleanup_module(void)
{
unregister_chrdev(char_major, "simplechar");
}
static int
perform_mmap(unsigned long usrptr)
{
unsigned long virt=0;
struct file_operations fops;
struct file pseudofile;
printk(KERN_DEBUG "%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__);
physical = (unsigned long)kmalloc(4096,GFP_KERNEL);
fops.mmap = test_mmap;
pseudofile.f_op = &fops;
pseudofile.f_mode= 0x3;
for(virt = physical & PAGE_MASK; virt < physical + 4096; virt += PAGE_SIZE)
mem_map_reserve(virt_to_page(virt));
printk("before do_mmap\n\n\n\n");
virt = do_mmap(&pseudofile, 0, (4096 + ~PAGE_MASK) & PAGE_MASK, PROT_READ|PROT_WRITE, MAP_SHARED, physical & PAGE_MASK);
if(virt <0) {
printk("error in mmap with :%d",virt);
return -EACCES;
}
printk("after do_mmap returns with:%lx\n",virt);
virt |= physical & ~PAGE_MASK;
put_user( virt, (unsigned long*)usrptr);
strcpy((char *) physical, "hello");
printk("virt addres:%ul and wrote:%s\n",virt, (char*)physical);
return 0;
}
static int
test_mmap(struct file *file, struct vm_area_struct *vma)
{
unsigned long phy;
printk(KERN_DEBUG "%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__);
printk("\n");
phy = vma->vm_pgoff << PAGE_SHIFT;
phy = __pa(phy);
printk(KERN_DEBUG "%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__);
if(remap_page_range(vma->vm_start, phy, vma->vm_end- vma->vm_start, vma->vm_page_prot)) {
printk("remap_page failed\n");
return -1;
}
vma->vm_file = NULL;
return 0;
}
[-- Attachment #3: mmap.c --]
[-- Type: application/octet-stream, Size: 673 bytes --]
#include<unistd.h>
#include<sys/mman.h>
#include<fcntl.h>
#include<sys/types.h>
#include<stdlib.h>
#include<errno.h>
#include<sys/ioctl.h>
#define CHAR_IOCTL 0x1a
#define I_CHAR_MMAP _IOWR(CHAR_IOCTL, 1,1024)
main()
{
int fd=0;
unsigned long buffer;
char *buf;
int rc=0;
char towrite;
fd = open("/dev/simplechar",O_RDWR);
if(fd <0){
perror("Open failed");
return;
}
printf("buffer ptr:%p\n", buffer);
rc = ioctl (fd, I_CHAR_MMAP,&buffer);
if(rc ) {
perror("mmap");
return;
}
printf("buffer pointr:%p\n",buffer);
printf(" buffer is:%s\n", (char *)buffer);
// strcpy((char*)buffer,"hi meri");
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2000-11-14 12:43 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-11-14 12:05 Oops when using MAP_SHARED with do_mmap aprasad
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®