Hi Norman,
before Christmas we chatted about enabling the MMIO session on Linux. You said that you know a possibility to create constrained file descriptors (in such a way that accesses through this descriptor can only access a part of the file). I've done a second search but I couldn't find any useful information regarding this topic. Do you have any further, more specific, information about how to achieve this goal?
Regards, Johannes
Hello Johannes,
On Fri, Dec 29, 2017 at 07:37:39PM +0100, Johannes Kliemann wrote:
before Christmas we chatted about enabling the MMIO session on Linux. You said that you know a possibility to create constrained file descriptors (in such a way that accesses through this descriptor can only access a part of the file). I've done a second search but I couldn't find any useful information regarding this topic. Do you have any further, more specific, information about how to achieve this goal?
I had a chat with Norman and we're not sure if he was referring to memfd_create() [1] which, unfortunately, does not solve the issue as it only handles anonymous memory. Maybe adding "android" to the keywords on your internet search brings up more interesting hits? Also, uio has solve this issue too, right?
[1] http://man7.org/linux/man-pages/man2/memfd_create.2.html [2] https://www.kernel.org/doc/html/latest/driver-api/uio-howto.html
Greets
Hi Christian,
thanks for that info. We also found memfd_create and came to the same conclusion that it won't work for our use case. Since there seems to be no way to constrain /dev/mem as we need we most probably will implement this functionality by ourselves on the kernel either through a kernel module or by adding a new custom syscall.
UIO solved this issue but also by creating a small custom kernel module for each driver what we wanted to prevent in the first place. Since we now need to change the kernel anyway we won't use UIO because the kernel also should become as small as possible at some point.
Greets Johannes
Am 03.01.2018 um 09:45 schrieb Christian Helmuth:
Hello Johannes,
On Fri, Dec 29, 2017 at 07:37:39PM +0100, Johannes Kliemann wrote:
before Christmas we chatted about enabling the MMIO session on Linux. You said that you know a possibility to create constrained file descriptors (in such a way that accesses through this descriptor can only access a part of the file). I've done a second search but I couldn't find any useful information regarding this topic. Do you have any further, more specific, information about how to achieve this goal?
I had a chat with Norman and we're not sure if he was referring to memfd_create() [1] which, unfortunately, does not solve the issue as it only handles anonymous memory. Maybe adding "android" to the keywords on your internet search brings up more interesting hits? Also, uio has solve this issue too, right?
[1] http://man7.org/linux/man-pages/man2/memfd_create.2.html [2] https://www.kernel.org/doc/html/latest/driver-api/uio-howto.html
Greets
Hi Johannes,
On 04.01.2018 09:05, Johannes Kliemann wrote:
thanks for that info. We also found memfd_create and came to the same conclusion that it won't work for our use case. Since there seems to be no way to constrain /dev/mem as we need we most probably will implement this functionality by ourselves on the kernel either through a kernel module or by adding a new custom syscall.
UIO solved this issue but also by creating a small custom kernel module for each driver what we wanted to prevent in the first place. Since we now need to change the kernel anyway we won't use UIO because the kernel also should become as small as possible at some point.
this is certainly the cleanest way.
As another principle idea - at least for handing out MMIO mappings for PCI resources, you may have a look at the pseudo files under /sys/devices. Here you can find all memory-mapped PCI resources as files, which could be mapped in user space via 'mmap'. E.g., the following command lists the available resources (with their file size corresponding to the information given by 'lspci -v'):
ls -l `find /sys/devices/pci0000:00 -name "resource*"`
However, this approach has some caveats:
* Core's IO_MEM service hands out resources based on their physical address. You would need to search /sys/devices for the matching PCI resource.
* A user-level device driver may request just a window of a PCI resource. So the dataspace handed out by core would need to carry the information about its offset from the beginning of the underlying file. We are somehow back at the start of the discussion. :-/
* It only works for the (arguably most prominent) case of PCI resources but not for other mappings. I am in particular thinking of the mapping of the PCI config space, which we will need to run the platform driver once the issue "RFC platform_drv/x86: Switch to ECAM/MMCONF" [1] is closed. I guess that we would need to have a Linux-specific platform driver then.
[1] https://github.com/genodelabs/genode/pull/2547
That said, in my opinion the tinkering with the files at /sys/ is not very attractive. If you are prepared to develop a generic kernel module for solving this problem at a lower level (and allowing us to reuse our existing platform driver on Linux), this should be the way to go.
Cherrs Norman
Hi Norman,
As another principle idea - at least for handing out MMIO mappings for PCI resources, you may have a look at the pseudo files under /sys/devices. Here you can find all memory-mapped PCI resources as files, which could be mapped in user space via 'mmap'. E.g., the following command lists the available resources (with their file size corresponding to the information given by 'lspci -v'):
ls -l `find /sys/devices/pci0000:00 -name "resource*"`
However, this approach has some caveats:
Core's IO_MEM service hands out resources based on their physical address. You would need to search /sys/devices for the matching PCI resource.
A user-level device driver may request just a window of a PCI resource. So the dataspace handed out by core would need to carry the information about its offset from the beginning of the underlying
file. We are somehow back at the start of the discussion. :-/
- It only works for the (arguably most prominent) case of PCI resources but not for other mappings. I am in particular thinking of the mapping of the PCI config space, which we will need to run the platform driver once the issue "RFC platform_drv/x86: Switch to ECAM/MMCONF" [1] is closed. I guess that we would need to have a Linux-specific platform driver then.
[1] https://github.com/genodelabs/genode/pull/2547
That said, in my opinion the tinkering with the files at /sys/ is not very attractive. If you are prepared to develop a generic kernel module for solving this problem at a lower level (and allowing us to reuse our existing platform driver on Linux), this should be the way to go.
We also thought about these options and came to the same conclusions. Furthermore sysfs is something we probably want to remove in the future so we don't want to depend on it anyway. Also at the implementation of interrupts we will need a kernel module/patch anyway since we didn't find any way to get them into the userspace (except polling /proc/interrupts which is a really bad hack).
About the specific PCI memory spaces, as far as I know PCI is mainly available on X86. Since the use of the Linux kernel is intended for exotic platforms without a supported micro kernel (on X86 we can stay with NOVA) where PCI most probably isn't available we definitely want to create a generic solution to access MMIO space.
Thanks for your thoughts and regards, Johannes