RE: mmap non-kmalloc'ed or non-vmalloc'ed buffer?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

>> Example:
>> 
>> Within my device driver code I have the following table ...
>> 
>> typedef struct foobar_entry {
>>        char      foo[1024];
>>        char      bar[1024];
>>        uint32_t  x;
>>        uint32_t  y;
>> } foobar_entry_t;
>> 
>> foobar_entry_t foobar_table[] =
>> {
>>      { "foo1", "bar1", 232, 0 },
>>      { "foo2", "bar2", 233, 1 },
>>      { "foo3", "bar3", 234, 0 },
>>      { "foo4", "bar4", 235, 1 },
>> };
>> EXPORT_SYMBOL(foobar_table);
>> 
>> ... and I'd like this to be memory mappped as read-only into user
>> space. I tried things with 'remap_pfn_range', but without success.
>> Do you have any idea/code example how to manage this?
> 
> Hm, what do you mean by "without success"? Do you get
> segmentation fault?
> 
> I guess the basic problem here is fundamental: you're accessing kernel
> data from ring 3. And to be honest, I am not sure whether
> remap_pfn_range would change the privilege level protection so they
> are accessible from user space.
> 
> I think, you could do it by providing /proc or /debugfs entry that
> read (or possible write) to this array. Robert PJ Day's Linux.com
> kernel article series could give you a nice howto on this topic.
> 
> NB: Well, maybe they are not {k,v}malloc-ed, but it doesn't matter,
> since I bet they are statically allocated (thus resides in .data
> section). 

Although LDD3 talks about a limitation of remap_pfn_range, but even from
that discussion, it seems remapping kernel .code and kernel .data
section should be possible:

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
(From LDD3)
An interesting limitation of remap_pfn_range is that it gives access
only to reserved pages and physical addresses above the top of physical
memory. In Linux, a page of physical addresses is marked as "reserved"
in the memory map to indicate that it is not available for memory
management. On the PC, for example, the range between 640 KB and 1 MB is
marked as reserved, as are the pages that host the kernel code itself.
Reserved pages are locked in memory and are the only ones that can be
safely mapped to user space; this limitation is a basic requirement for
system stability.

Therefore, remap_pfn_range won't allow you to remap conventional
addresses, which include the ones you obtain by calling get_free_page.
Instead, it maps in the zero page. Everything appears to work, with the
exception that the process sees private, zero-filled pages rather than
the remapped RAM that it was hoping for. Nonetheless, the function does
everything that most hardware drivers need it to do, because it can
remap high PCI buffers and ISA memory.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

I think the following code should work:

unsigned long pfn = virt_to_phys(foobar_table) >> PAGE_SHIFT;
unsigned long size = vma->vm_end - vma->vm_start;
remap_pfn_range(vma, vma->vm_start, pfn, vsize, vma->vm_page_prot);

Thanks,

Rajat


> 
> --
> regards,
> 
> Mulyadi Santosa
> Freelance Linux trainer and consultant
> 
> blog: the-hydra.blogspot.com
> training: mulyaditraining.blogspot.com

--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ



[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux