mirror of
https://github.com/drasko/codezero.git
synced 2026-01-28 18:53:14 +01:00
Fixed utcb updating issue that was a significant burden.
Any thread that touches a utcb inside the kernel now properly checks whether the utcb is mapped on its owner, and whether the mapped physical address matches that of the current thread's tables. If not the tables are updated. This way, even though page tables become incoherent on utcb address change situations (such as fork() exit(), execve()) they get updated as they are referenced. Since mappings are added only conditionally, caches are flushed only when an update is necessary.
This commit is contained in:
@@ -141,13 +141,8 @@ struct address_space *address_space_create(struct address_space *orig)
|
||||
* check if a pte is locked before going forward with a request.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Checks whether the given user address is a valid userspace address.
|
||||
* If so, whether it is currently mapped into its own address space.
|
||||
* If its not mapped-in, it generates a page-in request to the thread's
|
||||
* pager. If fault hasn't cleared, aborts.
|
||||
*/
|
||||
int check_access(unsigned long vaddr, unsigned long size, unsigned int flags, int page_in)
|
||||
int check_access_task(unsigned long vaddr, unsigned long size,
|
||||
unsigned int flags, int page_in, struct ktcb *task)
|
||||
{
|
||||
int err;
|
||||
unsigned long start, end, mapsize;
|
||||
@@ -162,9 +157,15 @@ int check_access(unsigned long vaddr, unsigned long size, unsigned int flags, in
|
||||
mapsize = end - start;
|
||||
|
||||
/* Check if the address is mapped with given flags */
|
||||
if (!check_mapping(start, mapsize, flags)) {
|
||||
/* Is a page in requested? */
|
||||
if (page_in) {
|
||||
if (!check_mapping_pgd(start, mapsize, flags, TASK_PGD(task))) {
|
||||
/*
|
||||
* Is a page in requested?
|
||||
*
|
||||
* Only allow page-in from current task,
|
||||
* since on-behalf-of type of ipc is
|
||||
* complicated and we don't do it.
|
||||
*/
|
||||
if (page_in && task == current) {
|
||||
/* Ask pager if paging in is possible */
|
||||
if((err = pager_pagein_request(start, mapsize,
|
||||
flags)) < 0)
|
||||
@@ -176,3 +177,15 @@ int check_access(unsigned long vaddr, unsigned long size, unsigned int flags, in
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks whether the given user address is a valid userspace address.
|
||||
* If so, whether it is currently mapped into its own address space.
|
||||
* If its not mapped-in, it generates a page-in request to the thread's
|
||||
* pager. If fault hasn't cleared, aborts.
|
||||
*/
|
||||
int check_access(unsigned long vaddr, unsigned long size,
|
||||
unsigned int flags, int page_in)
|
||||
{
|
||||
return check_access_task(vaddr, size, flags, page_in, current);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user