Sébastien FREMAL [530784]
2013-Feb-27 14:57 UTC
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
Ross Philipson
2013-Feb-27 15:54 UTC
Re: Mapping granted pages in the user space of a domU
> -----Original Message----- > From: xen-devel-bounces@lists.xen.org [mailto:xen-devel- > bounces@lists.xen.org] On Behalf Of Sébastien FREMAL [530784] > Sent: Wednesday, February 27, 2013 9:57 AM > To: xen-devel@lists.xen.org > 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émalIt 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
Sébastien FREMAL [530784]
2013-Feb-28 16:20 UTC
RE : Mapping granted pages in the user space of a domU
Thanks for your reply. I''m studying this tool. It doesn''t do exactly what I want to do, but it uses mechanisms I want to use. I''m looking how to arrange them so it does what I want. Best regards, S. Fremal ________________________________________ De : Ross Philipson [Ross.Philipson@citrix.com] Date d''envoi : mercredi 27 février 2013 16:54 À : Sébastien FREMAL [530784]; xen-devel@lists.xen.org Objet : RE: Mapping granted pages in the user space of a domU> -----Original Message----- > From: xen-devel-bounces@lists.xen.org [mailto:xen-devel- > bounces@lists.xen.org] On Behalf Of Sébastien FREMAL [530784] > Sent: Wednesday, February 27, 2013 9:57 AM > To: xen-devel@lists.xen.org > 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émalIt 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
Ross Philipson
2013-Mar-01 15:39 UTC
Re: Mapping granted pages in the user space of a domU
> -----Original Message----- > From: Sébastien FREMAL [530784] [mailto:Sebastien.FREMAL@umons.ac.be] > Sent: Thursday, February 28, 2013 11:20 AM > To: Ross Philipson > Subject: RE : Mapping granted pages in the user space of a domU > > Thanks for your reply. I''m studying this tool. It doesn''t do exactly > what I want to do, but it uses mechanisms I want to use. I''m looking how > to arrange them so it does what I want. > > Best regards, > > S. Fremal > ________________________________________Great, best of luck.