- Fixed an important bug with shadow object handling.
When a shadow is dropped, if there are references left
to it, both the object in front and dropped object becomes
a shadow of the original object underneath. We had thought
of this case but had not increase the shadow count.
- Added a test mechanism that tests the number of objects,
vmfiles, shadows etc. by first counting them and trying to
reach the same number by other means, i.e. per-object-shadow counts.
It discovered a plethora of bugs.
- Added new set of functions to register objects, files and tasks
globally with the pager, these functions introduce a refcount as
well as adding structures to linked lists.
- fork/exit now seems to work stably i.e. no negative shadow counts etc.
- Added cleaner allocation of shm addresses by moving the allocation to do_mmap().
- Added deletion routine for all objects: shadow, vm_file of type vfs_file, shm_file, etc.
- Need to make sure objects get deleted properly after exit().
- Currently we allow a single, unique virtual address for each shm segment.
- Updated sleeping paths such that a task is atomically put into
a runqueue and made RUNNABLE, or removed from a runqueue and made SLEEPING.
- Modified vma dropping sources to handle both copy_on_write() and exit() cases
in a common function.
- Added the first infrastructure to have a pager to suspend a task and wait for
suspend completion from the scheduler.
Now all system calls can simply return their final values and they
will be sent to client parties from a single location. Should have had this
simple cleanup a long time ago.
- Fixed do_mmap() so that it returns mapped address, and various bugs.
- A child seems to fork with new setup, but with incorrect return value.
Need to use and test exregs() for fork + clone.
- Shmat searches an unmapped area if input arg is invalid, do_mmap()
should do this.
- Added mutex_trylock()
- Implemented most of exchange_registers()
- thread_control() now needs a lock for operations that can modify thread context.
- thread_start() does not initialise scheduler flags, now done in thread_create.
TODO:
- Fork/clone'ed threads should retain their context in tcb, not syscall stack.
- exchange_registers() calls in userspace need cleaning up.
For clone, file descriptor and vm area structures need to be
separate from the tcb and reached via a pointer so that they
can be shared among multiple tcbs.
- Added automatic utcb map/prefaulting of forked tasks for fs0
so that it does not need to explicitly request those tasks from mm0.
Eliminating fs0 requests to mm0 reduce deadlock possibilities.
- Replaced kmalloc with a public malloc implementation because of a bug in kmalloc.
- Fixed a kfree bug. default_release_pages was trying to free page_array pages.
- Adding prefaulting of fs0 to avoid page fault deadlocks.
- Fixed a bug that a vmo page_cache equivalence would simply drop a link to
an original vmo, even if the vmo could have more pages outside the page cache,
or if the vmo was not a shadow vmo.
- Fixed a bug with page allocator where recursion would corrupt global variables.
- Now going to fix or re-write a simpler page allocator that works.
Removed some commented out code.
Removed excessive printfs.
Fixed spid not initialising for mm0
Fixed some faults with fs0.
TODO:
- Need to store vfs files in a separate list.
- Need to define vnum as a vfs-file-specific data, i.e. in priv_data field of vm_file.
- Need to then fix vfs_receive_sys_open.
- 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.
Next issues: For every read fault, the fault must traverse the
vma's object stack until the page is found. The problem was that
we were only searching the first object, that object was a writable
shadow, and the shadow didn't have the read-only page, and the 0
return value was interpreted with IS_ERR() and failed, so address
0 was mapped into the location, and QEMU blew off.
The svc images must be pushed to boot file list in correct order
otherwise if test0 starts earlier than fs0, it gets fs0's predefined
thread and space id (since that's the first unallocated one) and
fs0 fails to initalise. In the future we can pre-allocate ids from
the kernel but current temporary fix is simple enough to use.
utcb as a shared page instead of the message registers.
Implemented the code that passes task information from mm0 to fs0
using the fs0 utcb. The code seems to work OK but:
There's an issue with anon pages that they end up on the same swapfile
and with same file offsets (e.g. utcb and stack at offset 0). Need to
fix this issue but otherwise this implementation seems to work.
TODO:
- Separate anon regions into separate vmfiles.
- Possibly map the stacks from virtual files so that they can be
read from userspace in the future for debugging.
- Possibly utcb could be created as a shared memory object using shmget/shmat
during startup.
Environment is backed by a special per-task file maintained by mm0 for each task.
This file is filled in by the env pager, by simple copying of env data into the
faulty page upon a fault. UTCB and all anon regions (stack) could use the same
scheme.
Fixed IS_ERR(x) to accept negative values that are above -1000 for errors. This
protects against false positives for pointers such as 0xE0000000.
modified: include/l4/generic/scheduler.h
modified: include/l4/macros.h
modified: src/arch/arm/exception.c
modified: tasks/fs0/include/linker.lds
modified: tasks/libl4/src/init.c
modified: tasks/libposix/shm.c
new file: tasks/mm0/include/env.h
modified: tasks/mm0/include/file.h
new file: tasks/mm0/include/lib/addr.h
deleted: tasks/mm0/include/lib/vaddr.h
modified: tasks/mm0/include/task.h
new file: tasks/mm0/include/utcb.h
new file: tasks/mm0/src/env.c
modified: tasks/mm0/src/fault.c
modified: tasks/mm0/src/file.c
modified: tasks/mm0/src/init.c
new file: tasks/mm0/src/lib/addr.c
modified: tasks/mm0/src/lib/idpool.c
deleted: tasks/mm0/src/lib/vaddr.c
modified: tasks/mm0/src/mmap.c
modified: tasks/mm0/src/shm.c
modified: tasks/mm0/src/task.c
new file: tasks/mm0/src/utcb.c
modified: tasks/test0/include/linker.lds
This will help when syscalls have long arguments individual
utcbs can be mapped to server tasks and kept mapped in until the
tasks die, as opposed to map requests every time a server task maps
a different utcb at the same virtual address.
The changes have preparation code to also passing the utcb info
through the stack as part of the environment.
To sum up env and arg regions have also been added above the stack and
env region is to be used to pass on the utcb address information at
task startup.
Added reading pages from the page cache into user buffer for sys_read.
Increases stack sizes to 4 pages.
Updated README to include more details about multi-pager environments.
This implements the infrastructure for read/write system calls where
file content is first searched in mm0's page cache and then read-in
or written via the vfs read/write functions.
modified: tasks/fs0/src/syscalls.c
modified: tasks/mm0/include/lib/bit.h
modified: tasks/mm0/include/lib/idpool.h
modified: tasks/mm0/include/task.h
modified: tasks/mm0/include/vm_area.h
modified: tasks/mm0/main.c
modified: tasks/mm0/src/devzero.c
modified: tasks/mm0/src/fault.c
new file: tasks/mm0/src/file.c
modified: tasks/mm0/src/init.c
modified: tasks/mm0/src/lib/bit.c
modified: tasks/mm0/src/lib/idpool.c
modified: tasks/mm0/src/task.c
Boot files and tasks are now initialised together. Theads can ask for particular
space and thread ids, if they're unused. This enables us to get predefined ids for
known tasks such as the VFS task.
Fixes to README
Other minor fixes.
Changed l4id_t type to integer to recognise negative id values like L4_ANYTHREAD.
Added an extremely simple script that cleans and builds everything in right order.
Increased boot pmds by one:
This is due to the fact that if the 1MB initial allocation area of the kernel is
not 1MB-aligned, it is ought to be mapped from the middle of one MB to next,
which requires 2 pmds.
modified: .gdbinit
modified: README
new file: buildall.sh
modified: include/l4/arch/arm/types.h
modified: include/l4/generic/scheduler.h
modified: loader/kernel.S
modified: loader/main.c
modified: loader/mylink.lds
modified: loader/start.axf.S
modified: src/glue/arm/init.c
modified: src/glue/arm/memory.c
modified: tasks/fs0/src/bdev.c
modified: tasks/mm0/include/kdata.h
modified: tasks/mm0/include/vm_area.h
modified: tasks/mm0/src/init.c
modified: tasks/mm0/src/task.c
modified: tools/ksym_to_lds.py
modified: tools/l4-qemu