WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

Re: [Xen-devel] mmap in PV xen-4.0.1

On Tue, Aug 09, 2011 at 11:29:51PM -0700, Eric Camachat wrote:
> Hi,
> 
> I have a problem to map kernel memory to userspace via /dev/mem.
> The mmap() succeeded, but when I try to access it, the program will
> hang forever (until press ctrl-c to terminate it).
> 
> # memtest-user
> memtest_vma_open: virt 0x7fbc90085000, phys 0x3eee8000
> paddr = 0x3eee8000
>  mem = 0x7fbc90089000
>  map = 0x7fbc90085000
> map[0]= 4c4c4c4c
> map[1]= 4c4c4c4c
> *** Hang here, it cannot (finish) access the memory mapped via /dev/mem ***
> 
> My test source below, and it runs properly on HVM, VirtualBox, QEM and
> physical machines.
> What mistake I did?
> 
> My kernel module look like this:
> =================================================================================

[...snip...]

> memtest_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
>               unsigned long arg)
> {
>        int ret = -ENOIOCTLCMD;
>        phys_addr_t *paddr;
>        unsigned long *vaddr;
>        uint32_t *size;
> 
>        switch(cmd) {
>        case MEMTEST_DMA_SIZE:
>                size = (uint32_t*)arg;
>                *size = _size;

Though your output shows that this assignment works, shouldn't this
kind of direct assignment across kernel space and user land be
avoided? It is bad practice to do direct assignment I think.

copy_{from,to}_user should do the job.

>                ret = 0;
>                break;
>        case MEMTEST_DMA_PADDR:
>                paddr = (phys_addr_t*)arg;
>                *paddr = _pbase;
>                ret = 0;
>                break;
>        case MEMTEST_DMA_VADDR:
>                vaddr = (unsigned long*)arg;
>                *vaddr = _vbase;
>                ret = 0;
>                break;
>        }
>        return ret;
> }
> 
>

[...snip...]
 
> static struct file_operations memtest_fops = {
>        .owner          = THIS_MODULE,
>        .llseek         = no_llseek,
>        .ioctl          = memtest_ioctl,

My kernel doesn't have field called 'ioctl' in file_operations.

So which kernel do you use? 2.6.18? I don't have old kernel at the
moment so I can't help you much...

>        .mmap           = memtest_mmap,
> };
> 
>

[...snip...]
 
> static void __exit memtest_exit(void)
> {
>        if (_vbase != 0)
>                free_page(_vbase);

I suppose you should use free_pages here, since you use
__get_free_pages when allocating.

>        unregister_chrdev(MEMTEST_MAJOR, MEMTEST_NAME);
> }
> 
> 
> MODULE_LICENSE("GPL");
> 
> module_init(memtest_init);
> module_exit(memtest_exit);
> =================================================================================
> 
> Here is my user program:
> 
> =================================================================================
>

[...snip...]
 
>       if (map)
>       {
>               printf("map[0]= %x\n", map[0]);
>               printf("map[1]= %x\n", map[1]);

This confuses me. You did write different values in _vbase[0],
_vbase[1]. But the output '4C4C4C4C' shows that the value is 'L'.

I just skimmed the output and the code. I don't run your code since I
don't have a suitible environment at the moment...

Wei.

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel