Skip to content

Commit 5088531

Browse files
Merge pull request #210 from smartobjectoriented/209-mmap-anon
mmap: Add support for ANONYMOUS flag
2 parents d175143 + 2ec2066 commit 5088531

File tree

6 files changed

+92
-29
lines changed

6 files changed

+92
-29
lines changed

so3/arch/arm32/include/asm/mmu.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@
3939

4040
#define USER_SPACE_VADDR 0x1000ul
4141

42+
/* Anonymous start virtual address */
43+
#define USER_ANONYMOUS_VADDR UL(CONFIG_KERNEL_VADDR / 2)
44+
4245
/* Memory space all I/O mapped registers and additional mappings */
4346
#define IO_MAPPING_BASE 0xe0000000
4447

so3/arch/arm64/include/asm/mmu.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@
3535
/* Fixmap page used for temporary mapping */
3636
#define FIXMAP_MAPPING UL(0xffffb00000000000)
3737

38+
/* Anonymous start virtual address */
39+
#define USER_ANONYMOUS_VADDR UL(0x0000000100000000)
40+
3841
/* The user space can be up to bits [47:0] and uses ttbr0_el1
3942
* as main L0 page table.
4043
*/
@@ -45,6 +48,9 @@
4548
/* Fixmap page used for temporary mapping */
4649
#define FIXMAP_MAPPING UL(0xffffffd800000000)
4750

51+
/* Anonymous start virtual address */
52+
#define USER_ANONYMOUS_VADDR UL(0x0000000100000000)
53+
4854
/* The user space can be up to bits [38:0] and uses ttbr0_el1
4955
* as main L0 page table.
5056
*/

so3/fs/vfs.c

Lines changed: 74 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,75 @@ static int do_write(int fd, const void *buffer, int count)
463463
return ret;
464464
}
465465

466+
/* Low Level mmap */
467+
static int do_mmap(int fd, addr_t virt_addr, uint32_t page_count, off_t offset)
468+
{
469+
int gfd;
470+
struct file_operations *fops;
471+
472+
/* Get the fops associated to the file descriptor. */
473+
gfd = vfs_get_gfd(fd);
474+
if (-1 == gfd) {
475+
printk("%s: could not get global fd.\n", __func__);
476+
return -EBADF;
477+
}
478+
479+
mutex_lock(&vfs_lock);
480+
fops = vfs_get_fops(gfd);
481+
if (!fops) {
482+
printk("%s: could not get device fops.\n", __func__);
483+
mutex_unlock(&vfs_lock);
484+
return -EBADF;
485+
}
486+
487+
mutex_unlock(&vfs_lock);
488+
489+
if (!fops->mmap) {
490+
printk("%s: device doesn't support mmap.\n", __func__);
491+
return -EACCES;
492+
}
493+
494+
/* Call the mmap fops that will do the actual mapping. */
495+
return (long) fops->mmap(fd, virt_addr, page_count, offset);
496+
}
497+
498+
/* Low Level mmap - Anonymous case */
499+
static int do_mmap_anon(int fd, addr_t virt_addr, uint32_t page_count, off_t offset)
500+
{
501+
uint32_t page;
502+
pcb_t *pcb;
503+
int i;
504+
505+
if (offset != 0) {
506+
printk("%s: Offset should be 0 with MAP_ANONYMOUS flag\n", __func__);
507+
return -EINVAL;
508+
}
509+
510+
pcb = current()->pcb;
511+
512+
/* Start is smaller or NULL than initial virt_addr pointer */
513+
if (virt_addr < pcb->next_anon_start)
514+
virt_addr = pcb->next_anon_start;
515+
516+
for (i = 0; i < page_count; i++) {
517+
page = get_free_page();
518+
BUG_ON(!page);
519+
520+
create_mapping(pcb->pgtable, virt_addr + (i * PAGE_SIZE), page, PAGE_SIZE, false);
521+
add_page_to_proc(pcb, phys_to_page(page));
522+
}
523+
524+
memset((void *) virt_addr, 0, page_count * PAGE_SIZE);
525+
526+
/* WARNIMG - This is a simple/basic way to set the start virtual address:
527+
It only increment the start address after each mmap call, no algorithm
528+
to search for available spaces.
529+
*/
530+
pcb->next_anon_start = virt_addr + (page_count * PAGE_SIZE);
531+
532+
return virt_addr;
533+
}
534+
466535
SYSCALL_DEFINE3(read, int, fd, void *, buffer, int, count)
467536
{
468537
return do_read(fd, buffer, count);
@@ -738,43 +807,20 @@ SYSCALL_DEFINE2(stat, const char *, path, struct stat *, st)
738807
/**
739808
* An mmap() implementation in VFS.
740809
*/
741-
SYSCALL_DEFINE5(mmap, addr_t, start, size_t, length, int, prot, int, fd, off_t, offset)
810+
SYSCALL_DEFINE6(mmap, addr_t, start, size_t, length, int, prot, int, flags, int, fd, off_t, offset)
742811
{
743-
int gfd;
744812
uint32_t page_count;
745-
struct file_operations *fops;
746-
747-
/* Get the fops associated to the file descriptor. */
748-
749-
gfd = vfs_get_gfd(fd);
750-
if (-1 == gfd) {
751-
printk("%s: could not get global fd.\n", __func__);
752-
return -EBADF;
753-
}
754-
755-
mutex_lock(&vfs_lock);
756-
fops = vfs_get_fops(gfd);
757-
if (!fops) {
758-
printk("%s: could not get device fops.\n", __func__);
759-
mutex_unlock(&vfs_lock);
760-
return -EBADF;
761-
}
762-
763-
mutex_unlock(&vfs_lock);
764813

765814
/* Page count to allocate to the current process to be able to map the desired region. */
766815
page_count = length / PAGE_SIZE;
767816
if (length % PAGE_SIZE != 0) {
768817
page_count++;
769818
}
770819

771-
if (!fops->mmap) {
772-
printk("%s: device doesn't support mmap.\n", __func__);
773-
return -EACCES;
774-
}
775-
776-
/* Call the mmap fops that will do the actual mapping. */
777-
return (long) fops->mmap(fd, start, page_count, offset);
820+
if (flags & MAP_ANONYMOUS)
821+
return do_mmap_anon(fd, start, page_count, offset);
822+
else
823+
return do_mmap(fd, start, page_count, offset);
778824
}
779825

780826
SYSCALL_DEFINE3(ioctl, int, fd, unsigned long, cmd, unsigned long, args)

so3/include/process.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ struct pcb {
7676
/* current position of the heap pointer */
7777
addr_t heap_pointer;
7878

79+
/* next anonymous start pointer */
80+
addr_t next_anon_start;
81+
7982
/* Number of pages required by this process (including binary image) */
8083
size_t page_count;
8184

so3/include/vfs.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@
9191
#define DT_LNK 10 /* Symbolic link */
9292
#define DT_SOCK 12 /* Socket device */
9393

94+
/* mmap flags options */
95+
#define MAP_ANONYMOUS 0x10 /* don't use a file */
96+
9497
/* Return error values */
9598
#define MAP_FAILED ((void *) -1) /* mmap fail */
9699

@@ -165,7 +168,7 @@ SYSCALL_DECLARE(close, int fd);
165168
SYSCALL_DECLARE(dup, int oldfd);
166169
SYSCALL_DECLARE(dup2, int oldfd, int newfd);
167170
SYSCALL_DECLARE(stat, const char *path, struct stat *st);
168-
SYSCALL_DECLARE(mmap, addr_t start, size_t length, int prot, int fd, off_t offset);
171+
SYSCALL_DECLARE(mmap, addr_t start, size_t length, int prot, int flags, int fd, off_t offset);
169172
SYSCALL_DECLARE(ioctl, int fd, unsigned long cmd, unsigned long args);
170173
SYSCALL_DECLARE(fcntl, int fd, unsigned long cmd, unsigned long args);
171174
SYSCALL_DECLARE(lseek, int fd, off_t off, int whence);

so3/kernel/process.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,8 @@ pcb_t *new_process(void)
185185

186186
pcb->state = PROC_STATE_NEW;
187187

188+
pcb->next_anon_start = USER_ANONYMOUS_VADDR;
189+
188190
/* Reset the ptrace request indicator */
189191
pcb->ptrace_pending_req = PTRACE_NO_REQUEST;
190192

0 commit comments

Comments
 (0)