Skip to content

Commit

Permalink
um: nommu: add a workaround for MAP_FIXED on nommu
Browse files Browse the repository at this point in the history
Signed-off-by: Hajime Tazaki <thehajime@gmail.com>
  • Loading branch information
thehajime committed Sep 11, 2024
1 parent 2f3145c commit b62c672
Showing 1 changed file with 44 additions and 0 deletions.
44 changes: 44 additions & 0 deletions arch/x86/um/syscalls_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,56 @@ void arch_switch_to(struct task_struct *to)
#endif
}

#ifndef CONFIG_MMU
/*
* XXX: copied from musl dynlink.c
* musl has a switch, DL_NOMMU_SUPPORT, to support nommu kernel, but it's
* a compilation-time switch, which isn't enabled on x86_64 platform. so
* emulate the behavior of DL_NOMMU_SUPPORT here, until musl support it over
* a runtime-switch.
*/

static void *mmap_fixed(void *p, size_t n, int prot, int flags, int fd, off_t off)
{
char *q;
ssize_t r;

/* Fallbacks for MAP_FIXED failure on NOMMU kernels. */
if (flags & MAP_ANONYMOUS) {
memset(p, 0, n);
return p;
}
if (sys_lseek(fd, off, SEEK_SET) < 0)
return (void *)-1;
for (q = p; n; q += r, off += r, n -= r) {
r = ksys_read(fd, q, n);
if (r < 0 && r != -EINTR)
return (void *)-1;
if (!r) {
memset(q, 0, n);
break;
}
}
return p;
}
#endif

SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
unsigned long, prot, unsigned long, flags,
unsigned long, fd, unsigned long, off)
{
if (off & ~PAGE_MASK)
return -EINVAL;

#ifndef CONFIG_MMU
if (flags & MAP_FIXED) {
void *ret;

ret = mmap_fixed((void *)addr, len, prot, flags, fd, off);
if (ret == (void *)-1)
return -EINVAL;
return (unsigned long)ret;
}
#endif
return ksys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
}

0 comments on commit b62c672

Please sign in to comment.