mirror of
https://github.com/drasko/codezero.git
synced 2026-04-07 12:39:03 +02:00
Multiple above-minor updates.
- fixed is_err(x), was evaluating x twice, resulting in calling a function x twice. - Divided task initialisation into multiple parts. - MM0 now creates a tcb for itself and maintains memory regions of its own. - MM0's tcb is used for mmapping other tasks' regions. MM0 mmaps and prefaults those regions, instead of the typical mmap() and fault approach used by non-pager tasks. For example there's an internal shmget_shmat() path to map in other tasks' shm utcbs. Those mappings are then prefaulted into mm0's address space using the default fault handling path. - FS0 now reads task data into its utcb from mm0 via a syscall. FS0 shmat()s to utcbs of other tasks, e.g. mm0 and test0. FS0 then crashes, that is to be fixed and where this commit is left last.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* mmap/munmap and friends.
|
||||
*
|
||||
* Copyright (C) 2007 Bahadir Balban
|
||||
* Copyright (C) 2007, 2008 Bahadir Balban
|
||||
*/
|
||||
#include <vm_area.h>
|
||||
#include <kmalloc/kmalloc.h>
|
||||
@@ -394,13 +394,13 @@ unsigned long find_unmapped_area(unsigned long npages, struct tcb *task)
|
||||
|
||||
/* If no vmas, first map slot is available. */
|
||||
if (list_empty(&task->vm_area_list))
|
||||
return USER_AREA_START;
|
||||
return task->start;
|
||||
|
||||
/* First vma to check our range against */
|
||||
vma = list_entry(task->vm_area_list.next, struct vm_area, list);
|
||||
|
||||
/* Start searching from task's end of data to start of stack */
|
||||
while (pfn_end <= __pfn(USER_AREA_END)) {
|
||||
while (pfn_end <= __pfn(task->end)) {
|
||||
|
||||
/* If intersection, skip the vma and fast-forward to next */
|
||||
if (vma_intersect(pfn_start, pfn_end, vma)) {
|
||||
@@ -414,7 +414,7 @@ unsigned long find_unmapped_area(unsigned long npages, struct tcb *task)
|
||||
* Are we out of task map area?
|
||||
*/
|
||||
if (vma->list.next == &task->vm_area_list) {
|
||||
if (pfn_end > __pfn(USER_AREA_END))
|
||||
if (pfn_end > __pfn(task->end))
|
||||
break; /* Yes, fail */
|
||||
else /* No, success */
|
||||
return __pfn_to_addr(pfn_start);
|
||||
@@ -425,22 +425,24 @@ unsigned long find_unmapped_area(unsigned long npages, struct tcb *task)
|
||||
struct vm_area, list);
|
||||
continue;
|
||||
}
|
||||
BUG_ON(pfn_start + npages > __pfn(USER_AREA_END));
|
||||
BUG_ON(pfn_start + npages > __pfn(task->end));
|
||||
return __pfn_to_addr(pfn_start);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Validate an address that is a possible candidate for an mmap() region */
|
||||
int mmap_address_validate(unsigned long map_address, unsigned int vm_flags)
|
||||
int mmap_address_validate(struct tcb *task, unsigned long map_address,
|
||||
unsigned int vm_flags)
|
||||
{
|
||||
if (map_address == 0)
|
||||
return 0;
|
||||
|
||||
/* Private mappings can only go in task address space */
|
||||
if (vm_flags & VMA_PRIVATE) {
|
||||
if (map_address >= USER_AREA_START ||
|
||||
map_address < USER_AREA_END) {
|
||||
if (map_address >= task->start ||
|
||||
map_address < task->end) {
|
||||
return 1;
|
||||
} else
|
||||
return 0;
|
||||
@@ -451,8 +453,8 @@ int mmap_address_validate(unsigned long map_address, unsigned int vm_flags)
|
||||
} else if (vm_flags & VMA_SHARED) {
|
||||
if ((map_address >= UTCB_AREA_START &&
|
||||
map_address < UTCB_AREA_END) ||
|
||||
(map_address >= USER_AREA_START &&
|
||||
map_address < USER_AREA_END) ||
|
||||
(map_address >= task->start &&
|
||||
map_address < task->end) ||
|
||||
(map_address >= SHM_AREA_START &&
|
||||
map_address < SHM_AREA_END))
|
||||
return 1;
|
||||
@@ -507,7 +509,7 @@ int do_mmap(struct vm_file *mapfile, unsigned long file_offset,
|
||||
}
|
||||
|
||||
/* Check invalid map address */
|
||||
if (!mmap_address_validate(map_address, flags)) {
|
||||
if (!mmap_address_validate(task, map_address, flags)) {
|
||||
/* Get new map address for region of this size */
|
||||
map_address = find_unmapped_area(npages, task);
|
||||
if ((int)map_address < 0)
|
||||
@@ -585,7 +587,7 @@ int sys_mmap(l4id_t sender, void *start, size_t length, int prot,
|
||||
if ((fd < 0 && !(flags & MAP_ANONYMOUS)) || fd > TASK_FILES_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
if (base < USER_AREA_START || base >= USER_AREA_END)
|
||||
if (base < task->start || base >= task->end)
|
||||
return -EINVAL;
|
||||
|
||||
/* Exclude task's stack, text and data from mmappable area in task's space */
|
||||
|
||||
Reference in New Issue
Block a user