Kernel allocated memory not visible in L4Re virtual device despite correct physical RAM mapping
Hi l4-hackers, I am trying to pass a kernel-allocated memory buffer to a virtual device, but I am running into an issue. I would appreciate any help or suggestions. 1.Kernel side(driver) In my platform driver, I allocate memory using devm_kzalloc, write a string into it, and pass its physical address to the device via an MMIO register: …… void* buf = devm_kzalloc(&pdev->dev, 0x200, GFP_KERNEL); if (!buf) return -ENOMEM; phys_addr_t pa = virt_to_phys(buf); char *str = "hi stephen"; memcpy(buf, str, strlen(str) + 1); wmb(); writeq((u64)pa, hb->base + 0x00); …… My understanding is: allocate kernel memory → write data → pass physical address to the device. 2. Memory layout I observed that the allocated physical address falls within the RAM regions configured via bootargs : 0x66200000 - 0x6fffffff So my assumption was that if the virtual device maps this physical memory region, it should be able to access the data written by the kernel. 3. Virtual device side (L4Re) On the virtual device side, I map the physical memory using L4Re RM attach: void write(unsigned reg, char /*size*/, l4_uint64_t value, unsigned) { if (reg == 0x00) { addr = value; auto d = L4Re::Env::env()->get_cap<L4Re::Dataspace>("lram"); l4_addr_t vaddr; l4_addr_t base = 0x66200000; l4_addr_t size = 0x09E00000; int r = L4Re::Env::env()->rm()->attach( &vaddr, size, L4Re::Rm::F::Search_addr | L4Re::Rm::F::RW | L4Re::Rm::F::Cache_uncached, L4::Ipc::make_cap_rw(d), 0, L4_PAGESHIFT); if (r) { printf("can't attach hb memory\n"); return; } char *dst = reinterpret_cast<char *>(vaddr + (addr - base)); for (int i = 0; i < 20; i++) { printf("%02x ", (unsigned char)dst[i]); } printf("\n"); printf("get msg for guest: %s\n", dst); } } 4.Problem However, I cannot read the string written by the kernel. The memory content I get appears to be uninitialized or unrelated data. 5.Question I can confirm that the lram dataspace capability does correctly correspond to the physical memory region 0x66200000 - 0x6fffffff, and this region is valid and usable RAM on the system. I am unsure where the issue lies: (1) Is this approach (kernel allocation → pass physical address → direct mapping in virtual device) actually valid? (2) Could this be a cache coherence / DMA issue? (3) Or is there something incorrect in my L4Re RM attach usage? Any insights would be greatly appreciated.
Hi Stephen, the memory in Linux is mapped cached, while in your L4Re side, you mapped it uncached. Did you try mapping it cached on the L4Re side? Or you do a cache clean on the str string in Linux. BR, Adam On Mon Apr 13, 2026 at 14:53:00 +0800, stephen.yang wrote:
Hi l4-hackers, I am trying to pass a kernel-allocated memory buffer to a virtual device, but I am running into an issue. I would appreciate any help or suggestions.
1.Kernel side(driver) In my platform driver, I allocate memory using devm_kzalloc, write a string into it, and pass its physical address to the device via an MMIO register: ¡¡ void* buf = devm_kzalloc(&pdev->dev, 0x200, GFP_KERNEL); if (!buf) return -ENOMEM; phys_addr_t pa = virt_to_phys(buf); char *str = "hi stephen"; memcpy(buf, str, strlen(str) + 1); wmb(); writeq((u64)pa, hb->base + 0x00); ¡¡
My understanding is: allocate kernel memory ¡ú write data ¡ú pass physical address to the device.
2. Memory layout I observed that the allocated physical address falls within the RAM regions configured via bootargs : 0x66200000 - 0x6fffffff So my assumption was that if the virtual device maps this physical memory region, it should be able to access the data written by the kernel.
3. Virtual device side (L4Re) On the virtual device side, I map the physical memory using L4Re RM attach: void write(unsigned reg, char /*size*/, l4_uint64_t value, unsigned) { if (reg == 0x00) { addr = value;
auto d = L4Re::Env::env()->get_cap<L4Re::Dataspace>("lram");
l4_addr_t vaddr; l4_addr_t base = 0x66200000; l4_addr_t size = 0x09E00000; int r = L4Re::Env::env()->rm()->attach( &vaddr, size, L4Re::Rm::F::Search_addr | L4Re::Rm::F::RW | L4Re::Rm::F::Cache_uncached, L4::Ipc::make_cap_rw(d), 0, L4_PAGESHIFT); if (r) { printf("can't attach hb memory\n"); return; } char *dst = reinterpret_cast<char *>(vaddr + (addr - base)); for (int i = 0; i < 20; i++) { printf("%02x ", (unsigned char)dst[i]); } printf("\n"); printf("get msg for guest: %s\n", dst); } }
4.Problem However, I cannot read the string written by the kernel. The memory content I get appears to be uninitialized or unrelated data.
5.Question I can confirm that the lram dataspace capability does correctly correspond to the physical memory region 0x66200000 - 0x6fffffff, and this region is valid and usable RAM on the system.
I am unsure where the issue lies: (1) Is this approach (kernel allocation ¡ú pass physical address ¡ú direct mapping in virtual device) actually valid? (2) Could this be a cache coherence / DMA issue? (3) Or is there something incorrect in my L4Re RM attach usage?
Any insights would be greatly appreciated.
_______________________________________________ l4-hackers mailing list -- l4-hackers@os.inf.tu-dresden.de To unsubscribe send an email to l4-hackers-leave@os.inf.tu-dresden.de
participants (2)
-
Adam Lackorzynski -
stephen.yang