[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] Mapping granted pages in the user space of a domU
> -----Original Message----- > From: xen-devel-bounces@xxxxxxxxxxxxx [mailto:xen-devel- > bounces@xxxxxxxxxxxxx] On Behalf Of Sébastien FREMAL [530784] > Sent: Wednesday, February 27, 2013 9:57 AM > To: xen-devel@xxxxxxxxxxxxx > Subject: [Xen-devel] Mapping granted pages in the user space of a domU > > Hello, > > I'm creating a communication channel between an application running in > the dom0 and applications running in domU's. I mapped several pages of > the kernel space of the dom0 in its user space (and this part works > fine) and I granted the access to these pages to a domU. The module > running in this domU successfuly retrieves these pages and their content > but I don't find how to map the pages in the user space. > > I already tried several possibilities I found on the web : > > ======================================================================== > ================================== > > The code of the module : > > #undef __KERNEL__ > #define __KERNEL__ > > #undef MODULE > #define MODULE > > #include <xen/grant_table.h> > #include <xen/page.h> > #include <asm/xen/hypercall.h> > #include <linux/gfp.h> > #include <linux/module.h> > #include <linux/vmalloc.h> > #include <linux/kernel.h> > #include <linux/init.h> > #include <asm/page.h> > #include <linux/delay.h> > #include <linux/time.h> > #include <linux/fs.h> > #include <linux/cdev.h> > > MODULE_LICENSE("GPL"); > > // internal data > // length of the two memory areas > enum{NUM_ALLOC = 1}; > enum{PAGES_PER_ALLOC = 4}; > > struct gnttab_map_grant_ref ops[NUM_ALLOC*PAGES_PER_ALLOC]; > struct gnttab_unmap_grant_ref unmap_ops[NUM_ALLOC*PAGES_PER_ALLOC]; > struct vm_struct * v_start; > > static dev_t mmap_dev; > static struct cdev mmap_cdev; > > static int mmap_open(struct inode * inode, struct file *filp); > static int mmap_release(struct inode * inode, struct file * filp); > static int mmap_mmap(struct file * filp, struct vm_area_struct *vma); > > static struct file_operations mmap_fops = { > .open = mmap_open, > .release = mmap_release, > .mmap = mmap_mmap, > .owner = THIS_MODULE, > }; > > > static int mmap_open(struct inode *inode, struct file * filp){ > printk(KERN_INFO "MMap_open invoked\n"); > return 0; > } > > static int mmap_release(struct inode * inode, struct file * filp){ > printk(KERN_INFO "MMap_release invoked\n"); > return 0; > } > > struct mmap_info{ > char * data; > int reference; > }; > > static int mmap_mmap(struct file * filp, struct vm_area_struct * vma){ > int ret; > size_t length = vma->vm_end - vma->vm_start; > size_t num_pages = length/PAGE_SIZE; > size_t i=0;; > > printk(KERN_INFO "Length : %lu, pages : %lu \n", length, > length/PAGE_SIZE); > > if(length > NUM_ALLOC * PAGES_PER_ALLOC * PAGE_SIZE){ > printk("Request for a chunk of memory bigger than the > available memory\n"); > return -EIO; > } > > for(i=0;i<num_pages;++i){ > > //FIRST ATTEMPT > if((ret = remap_pfn_range(vma, > vma->vm_start+i*PAGE_SIZE, > page_to_pfn(vmalloc_to_page(v_start- > >addr+i*PAGE_SIZE)), > PAGE_SIZE, > vma->vm_page_prot))<0){ > printk(KERN_INFO "Error in remap_pfn_range"); > return ret; > } > > /* > //SECOND ATTEMPT > unsigned long mfn = PFN_DOWN(ops[i].dev_bus_addr); > if((ret=m2p_add_override(mfn, virt_to_page(vma- > >vm_start+i*PAGE_SIZE), NULL))>0){ > printk(KERN_INFO "Overriding failed\n"); > return ret; > } > > //THIRD ATTEMPT > struct mmap_info * info = (struct mmap_info *) filp- > >private_data; > unsigned long mfn = PFN_DOWN(ops[i].dev_bus_addr); > if((ret=m2p_add_override(mfn, virt_to_page(info- > >data+i*PAGE_SIZE), NULL))>0){ > printk(KERN_INFO "Overriding failed\n"); > return ret; > } > > //FOURTH ATTEMPT > if((ret = remap_vmalloc_range(vma, v_start->addr, > 0))<0){ > printk(KERN_INFO "Error in remap_vmalloc_range"); > return ret; > } > */ > printk(KERN_INFO "Page %lu mapped\n", i); > printk(KERN_INFO "Content : %d - %d\n", *((int > *)ops[i].host_addr), *((int *) v_start->addr)); > > } > > printk(KERN_INFO "MMaped\n"); > > return 0; > } > > static int __init mapped_init(void){ > int i, ret; > > printk(KERN_INFO "Using shared memory in Xen \n"); > > if((ret = alloc_chrdev_region(&mmap_dev,0,1,"mmap"))<0){ > printk(KERN_INFO "Could not allocate major number for > mmap\n"); > return ret; > } > > cdev_init(&mmap_cdev, &mmap_fops); > if((ret=cdev_add(&mmap_cdev, mmap_dev, 1))<0){ > printk(KERN_INFO "Could not allocate chrdev for > mmap\n"); > unregister_chrdev_region(mmap_dev, 1); > return ret; > } > > v_start = alloc_vm_area(PAGE_SIZE*NUM_ALLOC*PAGES_PER_ALLOC,NULL); > > if(v_start==0){ > printk(KERN_INFO "Problem allocating vm area\n"); > return -EFAULT; > } > > for(i=0;i<NUM_ALLOC*PAGES_PER_ALLOC;++i){ > ops[i].flags = GNTMAP_host_map; > ops[i].ref = 8+i; > ops[i].dom = 0; > ops[i].host_addr = (unsigned long)(((char*) v_start- > >addr)+i*PAGE_SIZE); > } > > if(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, ops, > NUM_ALLOC*PAGES_PER_ALLOC)){ > printk(KERN_INFO "Hypervisor map grant failed\n"); > free_vm_area(v_start); > return -EFAULT; > } > > > for(i=0;i<NUM_ALLOC*PAGES_PER_ALLOC;++i){ > if(ops[i].status){ > printk(KERN_INFO "Hyper map grant failed with status > %d\n", ops[i].status); > free_vm_area(v_start); > return -EFAULT; > } > > unmap_ops[i].host_addr = ops[i].host_addr; > unmap_ops[i].handle = ops[i].handle; > > printk(KERN_INFO "Number : %d\n", *((int > *)ops[i].host_addr)); > } > > return 0; > } > > static int __exit mapped_exit(void){ > if(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap_ops, > NUM_ALLOC*PAGES_PER_ALLOC)) > printk("Error in unmapping operation\n"); > free_vm_area(v_start); > printk("Mapping module cleaned\n"); > return 0; > } > > module_init(mapped_init) > module_exit(mapped_exit) > > > Mapping : > > int main(void) > { > int fd; > int *vadr; > > unsigned long len = getpagesize(), i; > > if ((fd=open("node", O_RDWR|O_SYNC))<0) > { > perror("open"); > exit(-1); > } > > vadr = mmap(0, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); > > if (vadr == MAP_FAILED) > { > perror("mmap"); > exit(-1); > } > > for(i=0;i<len/sizeof(int);i+=(getpagesize()/sizeof(int))){ > printf("%d\n",*(vadr+i)); > vadr[i]=vadr[i]+1; > } > > close(fd); > return(0); > > } > > ======================================================================== > ================================= > > The first attempt doesn't indicate any error but I don't get the good > page (I put the value "3" in the page but the application read the value > 0). > > The second attempt gives an error in the module : > [ 86.071090] WARNING: at /build/buildd/linux- > 3.2.0/arch/x86/xen/p2m.c:696 m2p_add_override+0x7b/0x3c0() > [ 86.071093] m2p_add_override: pfn f73ed13ae not mapped > [ 86.071095] Modules linked in: shm13(O) lp parport > [ 86.071101] Pid: 1324, comm: fill Tainted: G O 3.2.0-34- > generic #53-Ubuntu > [ 86.071103] Call Trace: > [ 86.071110] [<ffffffff81066f0f>] warn_slowpath_common+0x7f/0xc0 > [ 86.071113] [<ffffffff81067006>] warn_slowpath_fmt+0x46/0x50 > [ 86.071116] [<ffffffff8100b62b>] m2p_add_override+0x7b/0x3c0 > [ 86.071121] [<ffffffff8164328c>] ? printk+0x51/0x53 > [ 86.071126] [<ffffffffa0019116>] mmap_mmap+0xd6/0x128 [shm13] > [ 86.071129] [<ffffffff810064fe>] ? xen_pmd_val+0xe/0x10 > [ 86.071134] [<ffffffff811437e9>] mmap_region+0x369/0x4f0 > [ 86.071137] [<ffffffff8113dde8>] ? handle_mm_fault+0x1f8/0x350 > [ 86.071140] [<ffffffff81143cb8>] do_mmap_pgoff+0x348/0x360 > [ 86.071143] [<ffffffff81143d96>] sys_mmap_pgoff+0xc6/0x230 > [ 86.071148] [<ffffffff81017b12>] sys_mmap+0x22/0x30 > [ 86.071153] [<ffffffff816643c2>] system_call_fastpath+0x16/0x1b > [ 86.071155] ---[ end trace ea7792ae1c43717f ]--- > > The third attempt gives me the same error in the module : > [ 105.337927] WARNING: at /build/buildd/linux- > 3.2.0/arch/x86/xen/p2m.c:696 m2p_add_override+0x7b/0x3c0() > [ 105.337929] m2p_add_override: pfn f78bba24c not mapped > [ 105.337931] Modules linked in: shm13(O) lp parport > [ 105.337937] Pid: 1201, comm: fill Tainted: G O 3.2.0-34- > generic #53-Ubuntu > [ 105.337939] Call Trace: > [ 105.337946] [<ffffffff81066f0f>] warn_slowpath_common+0x7f/0xc0 > [ 105.337949] [<ffffffff81067006>] warn_slowpath_fmt+0x46/0x50 > [ 105.337952] [<ffffffff8100b62b>] m2p_add_override+0x7b/0x3c0 > [ 105.337958] [<ffffffff8164328c>] ? printk+0x51/0x53 > [ 105.337962] [<ffffffffa0019116>] mmap_mmap+0xd6/0x128 [shm13] > [ 105.337965] [<ffffffff810064fe>] ? xen_pmd_val+0xe/0x10 > [ 105.337970] [<ffffffff811437e9>] mmap_region+0x369/0x4f0 > [ 105.337973] [<ffffffff8113dde8>] ? handle_mm_fault+0x1f8/0x350 > [ 105.337976] [<ffffffff81143cb8>] do_mmap_pgoff+0x348/0x360 > [ 105.337979] [<ffffffff81143d96>] sys_mmap_pgoff+0xc6/0x230 > [ 105.337984] [<ffffffff81017b12>] sys_mmap+0x22/0x30 > [ 105.337989] [<ffffffff816643c2>] system_call_fastpath+0x16/0x1b > [ 105.337991] ---[ end trace 33b54c96a0c2933b ]--- > > The fourth attempt results in an error in the function called by the > module : > [ 96.621242] Error in remap_vmalloc_range > > I don't really know what to do to make it works, but I know than such a > communication channel is possible as people have already done it before. > > Does someone know what is my mistake and how to correct it please ? > > Best regards, > > Sébastien Frémal It sounds like you are trying to do something like what libvchan already does. You should take a look at that library - it is in the xen tree under tools/libvchan Ross _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |