Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

mmap() on a small PCI BAR

788 views
Skip to first unread message

Reuben

unread,
Feb 11, 2010, 11:58:05 PM2/11/10
to
Hi everyone,

I have a PCI card driver that supports most of the card's functions by
allowing userspace to mmap() the two BARs on the card, one for control
registers and one for DPRAM. The driver uses remap_page_range() to
perform the mapping. (This should be updated to use remap_pfn_range,
I know). Up until now, each BAR has been 4096 bytes, equal to
PAGE_SIZE, so the mapping is easy and everything works.

Recently, the vendor has released a new version of the card. There
are several changes, but the one that's causing trouble is that each
BAR is now 2048 bytes. How can mmap() be used on this? If the
userspace code tries to mmap() less than one page, the kernel will
page-align the region before the driver ever sees the request.

Thanks for any suggestions!
- Walt Ogburn
Caltech

Rainer Weikusat

unread,
Feb 12, 2010, 7:45:56 AM2/12/10
to

Ehh ... and what's the problem with that? Just because you have
theoretically mapped 4096 bytes doesn't mean that you also have to
access them. The other obvious option would be to turn your
PCI-to-userspace glue driver into a real driver and provide a proper
interface for working with the card.

Reuben

unread,
Feb 12, 2010, 1:17:00 PM2/12/10
to
Thank you for the suggestions.

> Ehh ... and what's the problem with that? Just because you have
> theoretically mapped 4096 bytes doesn't mean that you also have to
> access them.

OK, so the kernel will allow this mapping? And the userspace will
just have to make assumptions about where the memory region has
actually been mapped after getting page-aligned? That might be a good
enough solution for this application.

Is it safe to cover more than one BAR in a single mmap()?

> The other obvious option would be to turn your PCI-to-userspace glue
> driver into a real driver and provide a proper interface for working with the card.

Yes, I'll certainly do that if needed. I expect it may be slightly
slower than using mmap(), though, and it would be good to minimize
changes to the overall system.

Thanks again for the response.
- Walt Ogburn

Mike

unread,
Feb 12, 2010, 3:45:16 PM2/12/10
to
On Feb 12, 12:17 pm, Reuben <rwogb...@gmail.com> wrote:

> OK, so the kernel will allow this mapping?  And the userspace will
> just have to make assumptions about where the memory region has
> actually been mapped after getting page-aligned?  

Hi. Can you please rephrase this question?

Thanks,
-Mike

Reuben

unread,
Feb 12, 2010, 5:08:59 PM2/12/10
to

Sure. There were two questions, so I'll try to rephrase both.

1. Will remap_pfn_range work correctly if I use it to map a PCI BAR,
but with a size that's greater than the size of the BAR?

2. The userspace code calls mmap() with a specified offset and
length. The function in the driver that implements mmap() receives a
vm_area_struct giving the start, end, and offset of the area to be
mapped. The vma is page-aligned, even if the start of the BAR is not
on a page boundary and the length is not an even multiple of the page
size. So how does the userspace program know what range has actually
been mapped?

Thanks,
- Walt

Rainer Weikusat

unread,
Feb 12, 2010, 5:45:50 PM2/12/10
to
Reuben <rwog...@gmail.com> writes:
> On Feb 12, 12:45�pm, Mike <michael.h.william...@gmail.com> wrote:
>> On Feb 12, 12:17�pm, Reuben <rwogb...@gmail.com> wrote:
>>
>> > OK, so the kernel will allow this mapping? �And the userspace will
>> > just have to make assumptions about where the memory region has
>> > actually been mapped after getting page-aligned? �
>>
>> Hi. Can you please rephrase this question?
>
> Sure. There were two questions, so I'll try to rephrase both.
>
> 1. Will remap_pfn_range work correctly if I use it to map a PCI BAR,
> but with a size that's greater than the size of the BAR?

The generic memory management code in Linux knows nothing about 'PCI
bars', consequently, it should.

> 2. The userspace code calls mmap() with a specified offset and
> length. The function in the driver that implements mmap() receives a
> vm_area_struct giving the start, end, and offset of the area to be
> mapped. The vma is page-aligned, even if the start of the BAR is not
> on a page boundary and the length is not an even multiple of the page
> size. So how does the userspace program know what range has actually
> been mapped?

By knowing that the bar does not start on a page boundary.

Reuben

unread,
Feb 12, 2010, 5:58:20 PM2/12/10
to
On Feb 12, 2:45 pm, Rainer Weikusat <rweiku...@mssgmbh.com> wrote:
> The generic memory management code in Linux knows nothing about 'PCI
> bars', consequently, it should.

Great. It was not obvious to me that this should work, but if it
does, then there's no problem.

> By knowing that the bar does not start on a page boundary.

Right, so the application will have to calculate how the kernel will
page-align the request. That should be easy enough.

Thanks for your help, I think that clears it up for me.
- Walt

Tim Roberts

unread,
Feb 13, 2010, 3:33:41 PM2/13/10
to
Reuben <rwog...@gmail.com> wrote:
>
>> By knowing that the bar does not start on a page boundary.
>
>Right, so the application will have to calculate how the kernel will
>page-align the request. That should be easy enough.

The kernel cannot do any page-aligning of physical addresses. The lowest
12 bits of a physical address and any of its corresponding virtual
addresses are always exactly the same. If a BAR is not page-aligned
physically, then the virtual address will not be page-aligned.
--
Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.

0 new messages