All of lore.kernel.org
 help / color / mirror / Atom feed
* Propper use of pci_map_sg
@ 2015-01-29 19:50 Malte Vesper
  2015-02-02 19:49 ` Malte Vesper
  0 siblings, 1 reply; 3+ messages in thread
From: Malte Vesper @ 2015-01-29 19:50 UTC (permalink / raw)
  To: kernelnewbies

Hi,
I am trying to use pci_map_sg in combination with get_user_pages_fast 
for a driver. However my code screws the processes memory map over. For 
easier testing I bundled the piinin/unpinning and mapping unmapping into 
one ioctl call. The following code misses all the checks on return 
values, since it is only inteneded as a MWE.

When I run my code I get a "*BUG: Bad page map in process ...*", after 
"Done" is printed.

I tried following DMA-API-howto.txt and looking at other code, but I 
fail to see where I go wrong.

Regards, Ted


Code from the IOCTL handler:

         case IOCTL_FPGA_PIN_PAGE:
         {
             struct pageInfo pageInfo;

             dev_dbg(&pcidev->dev, pr_fmt("IOCTL: IOCTL_FPGA_PIN_PAGE\n"));

             if(!copy_from_user(&pageInfo, (void*)arg, sizeof(struct 
pageInfo))) {
                 //horrible test
                 const int noPages = pageInfo.size/PAGE_SIZE;
                 int pinned;
                 int mapped  = 0;
                 struct scatterlist* scatterlist;
                 printk("Test start\n");
                 //userspacestartpointer, nopages, write?, page* array
                 struct page** pages=kmalloc(sizeof(struct 
page*)*noPages, GFP_KERNEL);
                 pinned=*get_user_pages_fast*((unsigned 
long)pageInfo.start, noPages, 1, pages);

                 scatterlist = kmalloc(sizeof(struct 
scatterlist)*pinned, GFP_KERNEL);

                 for(int i=0; i<pinned; ++i) {
                     sg_set_page(&scatterlist[i], pages[i], PAGE_SIZE, 0);
                 }

                 mapped =*pci_map_sg*(pcidev, scatterlist, pinned, 
DMA_BIDIRECTIONAL);
*pci_unmap_sg*(pcidev, scatterlist, pinned, DMA_BIDIRECTIONAL);

                 for(int i=0; i<pinned; ++i) {
*put_page*(pages[i]); //I did place a print here and got two pages 
unpinned as I expected
                 }
                 kfree(scatterlist);
                 kfree(pages);
                 printk("Done\n");
                 /*pageInfo.pageId = getPageId(getArea(&pageInfo));
                 copy_to_user((void*)arg, &pageInfo, sizeof(struct 
pageInfo));*/
                 return pageInfo.pageId;
             } else {
                 return -EFAULT;
             }
         }
             break;

P.S.: I used the following code to allocate the memory in userspace, and 
I use chunk and chunksize to fill pageInfo.start and pageInfo.size 
respectivly:

     const int pagesize = sysconf(_SC_PAGESIZE);
     const int chunksize = 2*pagesize;
     void* chunk;

     if(int error = posix_memalign(&chunk, pagesize, chunksize)) {
         std::cout << "Could not get a page." << std::endl;
         return error;
     }
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20150129/ab36b03d/attachment.html 

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2015-02-03 18:13 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-29 19:50 Propper use of pci_map_sg Malte Vesper
2015-02-02 19:49 ` Malte Vesper
2015-02-03 18:13   ` Malte Vesper

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.