From 26d9b8d6f3617c1d466ca8d3b28f368fdf25e29a Mon Sep 17 00:00:00 2001 From: Luke Craig Date: Wed, 3 Jun 2026 12:09:33 -0400 Subject: [PATCH] Map QEMU mmap apertures as normal memory on arm64 --- src/portal/portal_anon.c | 5 +++-- src/portal/portal_devfs.c | 3 ++- src/portal/portal_mmap.h | 20 ++++++++++++++++++++ src/portal/portal_procfs.c | 3 ++- 4 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 src/portal/portal_mmap.h diff --git a/src/portal/portal_anon.c b/src/portal/portal_anon.c index e92259c..8b09683 100644 --- a/src/portal/portal_anon.c +++ b/src/portal/portal_anon.c @@ -4,6 +4,7 @@ #include #include #include "portal_devfs.h" +#include "portal_mmap.h" struct portal_anonfs_create_req { @@ -44,7 +45,7 @@ static int igloo_anonfs_proxy_mmap(struct file *file, struct vm_area_struct *vma size_t size = vma->vm_end - vma->vm_start; if (pe && pe->mmap_phys_addr) { - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + vma->vm_page_prot = igloo_mmap_phys_pgprot(vma->vm_page_prot); return remap_pfn_range(vma, vma->vm_start, pe->mmap_phys_addr >> PAGE_SHIFT, size, vma->vm_page_prot); } @@ -205,4 +206,4 @@ void handle_op_sockfs_create_socket(portal_region *mem_region) { fail: mem_region->header.op = HYPER_RESP_WRITE_FAIL; -} \ No newline at end of file +} diff --git a/src/portal/portal_devfs.c b/src/portal/portal_devfs.c index f341ee1..1db00ea 100644 --- a/src/portal/portal_devfs.c +++ b/src/portal/portal_devfs.c @@ -20,6 +20,7 @@ #include #include "portal_devfs.h" +#include "portal_mmap.h" // Request to create a directory in devfs struct portal_devfs_dir_req { @@ -225,7 +226,7 @@ static int igloo_devfs_proxy_mmap(struct file *file, struct vm_area_struct *vma) if (pe->mmap_phys_addr) { // NATIVE QEMU MMAP: Directly map the physical address assigned by Penguin - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + vma->vm_page_prot = igloo_mmap_phys_pgprot(vma->vm_page_prot); return remap_pfn_range(vma, vma->vm_start, pe->mmap_phys_addr >> PAGE_SHIFT, size, vma->vm_page_prot); } diff --git a/src/portal/portal_mmap.h b/src/portal/portal_mmap.h new file mode 100644 index 0000000..d153d20 --- /dev/null +++ b/src/portal/portal_mmap.h @@ -0,0 +1,20 @@ +#ifndef IGLOO_PORTAL_MMAP_H +#define IGLOO_PORTAL_MMAP_H + +#include + +static inline pgprot_t igloo_mmap_phys_pgprot(pgprot_t prot) +{ +#if defined(CONFIG_ARM64) + /* + * arm64 maps pgprot_noncached() as device memory. User-space string and + * runtime helpers may issue unaligned accesses into mmap()ed pseudo-files, + * and device mappings fault on those accesses before QEMU sees the MMIO. + */ + return pgprot_writecombine(prot); +#else + return pgprot_noncached(prot); +#endif +} + +#endif diff --git a/src/portal/portal_procfs.c b/src/portal/portal_procfs.c index f8d0070..9bfc6dd 100644 --- a/src/portal/portal_procfs.c +++ b/src/portal/portal_procfs.c @@ -18,6 +18,7 @@ #include "../args.h" #include "portal_procfs.h" +#include "portal_mmap.h" #if LINUX_VERSION_CODE >= KERNEL_VERSION(6,13,0) #define IGLOO_NEEDS_PROC_PERMANENT_CLEAR 1 @@ -103,7 +104,7 @@ int igloo_proxy_mmap(struct file *file, struct vm_area_struct *vma) if (pe->mmap_phys_addr) { // NATIVE QEMU MMAP: Directly map the physical address assigned by Penguin - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + vma->vm_page_prot = igloo_mmap_phys_pgprot(vma->vm_page_prot); return remap_pfn_range(vma, vma->vm_start, pe->mmap_phys_addr >> PAGE_SHIFT, size, vma->vm_page_prot); }