mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 13:47:56 +00:00
base_hw & arm_v7: Use write-back caching.
Add 'resume_faulter' syscall that is similar to 'resume_thread', but is called only when resuming a thread after resolving its pagefault. This way the kernel can flush caches after resolving a pagefault. This is because by now the MMU doesn't use caches when doing a pagetable walk.
This commit is contained in:
parent
4723b08322
commit
6cb89f79e3
@ -39,6 +39,7 @@ namespace Kernel
|
||||
START_THREAD = 2,
|
||||
PAUSE_THREAD = 3,
|
||||
RESUME_THREAD = 4,
|
||||
RESUME_FAULTER = 28,
|
||||
GET_THREAD = 5,
|
||||
CURRENT_THREAD_ID = 6,
|
||||
YIELD_THREAD = 7,
|
||||
@ -247,6 +248,15 @@ namespace Kernel
|
||||
{ return syscall(RESUME_THREAD, id); }
|
||||
|
||||
|
||||
/**
|
||||
* Continue thread after a pagefault that could be resolved
|
||||
*
|
||||
* \param id ID of the targeted thread
|
||||
*/
|
||||
inline void resume_faulter(unsigned long const id = 0) {
|
||||
syscall(RESUME_FAULTER, id); }
|
||||
|
||||
|
||||
/**
|
||||
* Let the current thread give up its remaining timeslice
|
||||
*
|
||||
|
@ -154,7 +154,7 @@ namespace Arm
|
||||
return Tex::bits(2) | C::bits(0) | B::bits(0);
|
||||
if(cache_support()) {
|
||||
if(Page_flags::C::get(flags))
|
||||
return Tex::bits(6) | C::bits(1) | B::bits(0);
|
||||
return Tex::bits(5) | C::bits(0) | B::bits(1);
|
||||
return Tex::bits(4) | C::bits(0) | B::bits(0);
|
||||
}
|
||||
return Tex::bits(4) | C::bits(0) | B::bits(0);
|
||||
|
@ -1726,6 +1726,31 @@ namespace Kernel
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Do specific syscall for 'user', for details see 'syscall.h'
|
||||
*/
|
||||
void do_resume_faulter(Thread * const user)
|
||||
{
|
||||
/* get targeted thread */
|
||||
Thread * const t = Thread::pool()->object(user->user_arg_1());
|
||||
assert(t);
|
||||
|
||||
/* check permissions */
|
||||
assert(user->pd_id() == core_id() || user->pd_id() == t->pd_id());
|
||||
|
||||
/*
|
||||
* Writeback the TLB entry that resolves the fault.
|
||||
* This is a substitution for write-through-flagging
|
||||
* the memory that holds the TLB data, because the latter
|
||||
* is not feasible in core space.
|
||||
*/
|
||||
Cpu::flush_caches();
|
||||
|
||||
/* resume targeted thread */
|
||||
t->resume();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Do specific syscall for 'user', for details see 'syscall.h'
|
||||
*/
|
||||
@ -2075,6 +2100,7 @@ namespace Kernel
|
||||
/* 25 */ do_run_vm,
|
||||
/* 26 */ do_delete_thread,
|
||||
/* 27 */ do_signal_pending,
|
||||
/* 28 */ do_resume_faulter,
|
||||
};
|
||||
enum { MAX_SYSCALL = sizeof(handle_sysc)/sizeof(handle_sysc[0]) - 1 };
|
||||
|
||||
|
@ -80,8 +80,8 @@ void Ipc_pager::resolve_and_wait_for_fault()
|
||||
_mapping.size_log2, flags, space);
|
||||
assert(!sl2);
|
||||
}
|
||||
/* try to wake up faulter */
|
||||
assert(!Kernel::resume_thread(_pagefault.thread_id));
|
||||
/* wake up faulter */
|
||||
Kernel::resume_faulter(_pagefault.thread_id);
|
||||
|
||||
/* wait for next page fault */
|
||||
wait_for_fault();
|
||||
|
Loading…
Reference in New Issue
Block a user