Hi all,
I'm trying to run Genode+NOVA on a Panasonic Toughpad FZ-M1. I'm new to Genode but thanks to documentation and good coding style I came along pretty good so far. However, I ran into a problem with DMA.
I tried to run the AHCI driver, but whenever the driver issued the first SATA- command, the hardware failed because it was not able to read from the specified DMA address. After I enabled IOMMU by adding 'pci_device_pd' to my modules, I got the message "[init -> acpi -> pci_drv -> oci_device_pd] attachment of DMA memory @ cb48c000+1000 failed".
I investigated more into the memory allocation process. As far as I understand it, the method 'alloc_dma_buffer' of the PCI session first allocates a dataspace in physical memory. Then it tries to attach this dataspace as a region to the driver's virtual address space. Thereby it enforces the virtual address to be equal to the physical address. So the allocator searches for a free block that contains that virtual address. But in my case it doesn't find a free block.
Do you have any ideas on how to resolve this issue? What I don't understand is why physical and virtual address of the dma buffer should be equal. Shouldn't there by some mechanism that ensures that there is a free block that contains the DMA address before the DMA buffer is allocated in physical memory?
Tell me if you need any specification on the device. I would like to print the full Log here, but unfortunately I have no serial interface, I am only able to use a vga console.
Thanks Christian
Hello,
On 07.07.2014 12:29, Christian Menard wrote:
Hi all,
I'm trying to run Genode+NOVA on a Panasonic Toughpad FZ-M1. I'm new to Genode but thanks to documentation and good coding style I came along pretty good so far. However, I ran into a problem with DMA.
I tried to run the AHCI driver, but whenever the driver issued the first SATA- command, the hardware failed because it was not able to read from the specified DMA address.
If you are using our run script infrastructure, then in the generated config files for pulsar and for grub the IOMMU support for the kernel is enabled by default. In this case you have to use the pci_device_pd process. For the starting you may disable the IOMMU support for the kernel, please see repos/base-nova/run/env file.
After I enabled IOMMU by adding 'pci_device_pd' to my modules, I got the message "[init -> acpi -> pci_drv -> oci_device_pd] attachment
of DMA
memory @ cb48c000+1000 failed".
I presume your are running a 32bit Genode ? In this case all virtual addresses starting with 0xc0000000 can't be used by user applications. Your physical address is above the 3G border, that is why you get this message. There is no quick fix for this case - beside disabling iommu support or using a 64bit Genode. A real fix would be not to rely on a 1:1 physical to virtual mapping for DMA buffers.
I investigated more into the memory allocation process. As far as I understand it, the method 'alloc_dma_buffer' of the PCI session first allocates a dataspace in physical memory. Then it tries to attach this dataspace as a region to the driver's virtual address space. Thereby it enforces the virtual address to be equal to the physical address. So the allocator searches for a free block that contains that virtual address. But in my case it doesn't find a free block.
Do you have any ideas on how to resolve this issue? What I don't understand is why physical and virtual address of the dma buffer should be equal. Shouldn't
Please read the release notes of 13.02 regarding IOMMU support and device_pd [0]. If it does not answer your question, don't hesitate to ask again.
there by some mechanism that ensures that there is a free block that contains the DMA address before the DMA buffer is allocated in physical memory?
Tell me if you need any specification on the device. I would like to print the full Log here, but unfortunately I have no serial interface, I am only able to use a vga console.
Cheers,
Alex B.
Hi Christian
welcome to the mailing list!
I'm trying to run Genode+NOVA on a Panasonic Toughpad FZ-M1. I'm new to Genode but thanks to documentation and good coding style I came along pretty good so far. However, I ran into a problem with DMA.
I tried to run the AHCI driver, but whenever the driver issued the first SATA- command, the hardware failed because it was not able to read from the specified DMA address. After I enabled IOMMU by adding 'pci_device_pd' to my modules, I got the message "[init -> acpi -> pci_drv -> oci_device_pd] attachment of DMA memory @ cb48c000+1000 failed".
I investigated more into the memory allocation process. As far as I understand it, the method 'alloc_dma_buffer' of the PCI session first allocates a dataspace in physical memory. Then it tries to attach this dataspace as a region to the driver's virtual address space. Thereby it enforces the virtual address to be equal to the physical address. So the allocator searches for a free block that contains that virtual address. But in my case it doesn't find a free block.
Your analysis is very good. The problem is that the allocation of the DMA buffer returned a very high physical address (above 0xc000000). So when the device PD tries to create a 1:1 mapping for this block, it attempts to create a mapping to the corresponding virtual address. But the NOVA kernel preserves all virtual addresses above 0xc0000000 for the kernel. Because Genode's core is aware of this constraint, it excludes the address range above 0xc0000000 from the virtual-memory allocators (that is maintained per process). This problem is related to the following issue:
https://github.com/genodelabs/genode/issues/1045
There three possible ways to cope with the problem:
* As a work-around, we could remove all physical memory above 0xc0000000 from core's physical-memory allocator. But that would be a pity because Genode could not use all the memory of your system.
* You could use NOVA on 64 bit instead of 32 bit. Here, the kernel's virtual address space won't interfere with the physical memory address space.
* We could add a constraint to Genode's RAM sessions to enable a RAM client to specify a physical memory range from where the allocations should come from. So the PCI/ACPI driver would then limit this range to 0x00000000 - 0xbfffffff. This approach would solve your problem as well as the issue cited above.
I think the quickest way forward would be to switch to 64 bit. Would that be feasible for you?
Do you have any ideas on how to resolve this issue? What I don't understand is why physical and virtual address of the dma buffer should be equal. Shouldn't there by some mechanism that ensures that there is a free block that contains the DMA address before the DMA buffer is allocated in physical memory?
Tell me if you need any specification on the device. I would like to print the full Log here, but unfortunately I have no serial interface, I am only able to use a vga console.
Does you platform support Intel AMT by any chance? It would be worthwhile to use it.
Btw, are you located in Dresden? If yes, you are very welcome to drop by at our office - e.g., if you like us to assist you with setting up AMT.
Cheers Norman
Hi,
Thanks for your fast and detailed answers. I compiled the 64-bit version and DMA is working now. I think a switch to 64-bit is generally the better idea, but somehow I didn't think of that.
Christian
On Monday 07 July 2014 13:26:38 Norman Feske wrote:
Hi Christian
welcome to the mailing list!
I'm trying to run Genode+NOVA on a Panasonic Toughpad FZ-M1. I'm new to Genode but thanks to documentation and good coding style I came along pretty good so far. However, I ran into a problem with DMA.
I tried to run the AHCI driver, but whenever the driver issued the first SATA- command, the hardware failed because it was not able to read from the specified DMA address. After I enabled IOMMU by adding 'pci_device_pd' to my modules, I got the message "[init -> acpi -> pci_drv -> oci_device_pd] attachment of DMA memory @ cb48c000+1000 failed".
I investigated more into the memory allocation process. As far as I understand it, the method 'alloc_dma_buffer' of the PCI session first allocates a dataspace in physical memory. Then it tries to attach this dataspace as a region to the driver's virtual address space. Thereby it enforces the virtual address to be equal to the physical address. So the allocator searches for a free block that contains that virtual address. But in my case it doesn't find a free block.
Your analysis is very good. The problem is that the allocation of the DMA buffer returned a very high physical address (above 0xc000000). So when the device PD tries to create a 1:1 mapping for this block, it attempts to create a mapping to the corresponding virtual address. But the NOVA kernel preserves all virtual addresses above 0xc0000000 for the kernel. Because Genode's core is aware of this constraint, it excludes the address range above 0xc0000000 from the virtual-memory allocators (that is maintained per process). This problem is related to the following issue:
https://github.com/genodelabs/genode/issues/1045
There three possible ways to cope with the problem:
As a work-around, we could remove all physical memory above 0xc0000000 from core's physical-memory allocator. But that would be a pity because Genode could not use all the memory of your system.
You could use NOVA on 64 bit instead of 32 bit. Here, the kernel's virtual address space won't interfere with the physical memory address space.
We could add a constraint to Genode's RAM sessions to enable a RAM client to specify a physical memory range from where the allocations should come from. So the PCI/ACPI driver would then limit this range to 0x00000000 - 0xbfffffff. This approach would solve your problem as well as the issue cited above.
I think the quickest way forward would be to switch to 64 bit. Would that be feasible for you?
Do you have any ideas on how to resolve this issue? What I don't understand is why physical and virtual address of the dma buffer should be equal. Shouldn't there by some mechanism that ensures that there is a free block that contains the DMA address before the DMA buffer is allocated in physical memory?
Tell me if you need any specification on the device. I would like to print the full Log here, but unfortunately I have no serial interface, I am only able to use a vga console.
Does you platform support Intel AMT by any chance? It would be worthwhile to use it.
Btw, are you located in Dresden? If yes, you are very welcome to drop by at our office - e.g., if you like us to assist you with setting up AMT.
Cheers Norman