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.