[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [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 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |