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:
Martin Stein 2012-11-09 17:10:38 +01:00 committed by Norman Feske
parent 4723b08322
commit 6cb89f79e3
4 changed files with 39 additions and 3 deletions

View File

@ -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
*

View File

@ -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);

View File

@ -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 };

View File

@ -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();