hw: restrict processor broadcast to TLB flushing

Removes the generic processor broadcast function call. By now, that call
was used for cross processor TLB maintance operations only. When core/kernel
gets its memory mapped on demand, and unmapped again, the previous cross
processor flush routine doesn't work anymore, because of a hen-egg problem.
The previous cross processor broadcast is realized using a thread constructed
by core running on top of each processor core. When constructing threads in
core, a dataspace for its thread context is constructed. Each constructed
RAM dataspace gets attached, zeroed out, and detached again. The detach
routine requires a TLB flush operation executed on each processor core.

Instead of executing a thread on each processor core, now a thread waiting
for a global TLB flush is removed from the scheduler queue, and gets attached
to a TLB flush queue of each processor. The processor local queue gets checked
whenever the kernel is entered. The last processor, which executed the TLB
flush, re-attaches the blocked thread to its scheduler queue again.

To ease uo the above described mechanism, a platform thread is now directly
associated with a platform pd object, instead of just associate it with the
kernel pd's id.

Ref #723
This commit is contained in:
Stefan Kalkowski 2014-04-28 20:36:00 +02:00 committed by Norman Feske
parent b888a26d57
commit 34b18e9da2
14 changed files with 161 additions and 295 deletions

View File

@ -1,6 +1,7 @@
/* /*
* \brief Platform specific part of a Genode protection domain * \brief Platform specific part of a Genode protection domain
* \author Martin Stein * \author Martin Stein
* \author Stefan Kalkowski
* \date 2012-02-12 * \date 2012-02-12
*/ */
@ -45,14 +46,22 @@ namespace Genode
*/ */
class Platform_pd : public Address_space class Platform_pd : public Address_space
{ {
unsigned _id; protected:
Native_capability _parent;
Native_thread_id _main_thread; unsigned _id;
char const * const _label; Native_capability _parent;
Tlb * _tlb; Native_thread_id _main_thread;
char const * const _label;
Tlb * _tlb;
public: public:
/**
* Constructor for core pd
*/
Platform_pd(Tlb * tlb)
: _main_thread(0), _label("core"), _tlb(tlb) { }
/** /**
* Constructor * Constructor
*/ */
@ -95,9 +104,9 @@ namespace Genode
{ {
/* annotate that we've got a main thread from now on */ /* annotate that we've got a main thread from now on */
_main_thread = t->id(); _main_thread = t->id();
return t->join_pd(_id, 1, Address_space::weak_ptr()); return t->join_pd(this, 1, Address_space::weak_ptr());
} }
return t->join_pd(_id, 0, Address_space::weak_ptr()); return t->join_pd(this, 0, Address_space::weak_ptr());
} }
/** /**
@ -118,6 +127,7 @@ namespace Genode
** Accessors ** ** Accessors **
***************/ ***************/
unsigned const id() { return _id; }
char const * const label() { return _label; } char const * const label() { return _label; }

View File

@ -1,6 +1,7 @@
/* /*
* \brief Userland interface for the management of kernel thread-objects * \brief Userland interface for the management of kernel thread-objects
* \author Martin Stein * \author Martin Stein
* \author Stefan Kalkowski
* \date 2012-02-02 * \date 2012-02-02
*/ */
@ -42,7 +43,7 @@ namespace Genode {
enum { LABEL_MAX_LEN = 32 }; enum { LABEL_MAX_LEN = 32 };
size_t _stack_size; size_t _stack_size;
unsigned _pd_id; Platform_pd * _pd;
Weak_ptr<Address_space> _address_space; Weak_ptr<Address_space> _address_space;
unsigned _id; unsigned _id;
Rm_client * _rm_client; Rm_client * _rm_client;
@ -81,11 +82,9 @@ namespace Genode {
* Constructor for core threads * Constructor for core threads
* *
* \param stack_size initial size of the stack * \param stack_size initial size of the stack
* \param pd_id kernel name of targeted protection domain
* \param label debugging label * \param label debugging label
*/ */
Platform_thread(size_t const stack_size, Platform_thread(size_t const stack_size, const char * const label);
unsigned const pd_id, const char * const label);
/** /**
* Constructor for threads outside of core * Constructor for threads outside of core
@ -105,14 +104,14 @@ namespace Genode {
/** /**
* Join a protection domain * Join a protection domain
* *
* \param pd_id kernel name of targeted protection domain * \param pd platform pd object pointer
* \param main_thread wether thread is the first in protection domain * \param main_thread wether thread is the first in protection domain
* \param address_space corresponding Genode address space * \param address_space corresponding Genode address space
* *
* \retval 0 succeeded * \retval 0 succeeded
* \retval -1 failed * \retval -1 failed
*/ */
int join_pd(unsigned const pd_id, bool const main_thread, int join_pd(Platform_pd * const pd, bool const main_thread,
Weak_ptr<Address_space> address_space); Weak_ptr<Address_space> address_space);
/** /**
@ -179,7 +178,7 @@ namespace Genode {
Pager_object * pager(); Pager_object * pager();
unsigned pd_id() const { return _pd_id; } Platform_pd * pd() const { return _pd; }
Native_thread_id id() const { return _id; } Native_thread_id id() const { return _id; }

View File

@ -1,207 +0,0 @@
/*
* \brief Utility to execute a function on all available processors
* \author Martin Stein
* \date 2014-03-07
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _PROCESSOR_BROADCAST_H_
#define _PROCESSOR_BROADCAST_H_
/* Genode includes */
#include <base/thread.h>
#include <base/signal.h>
namespace Genode {
enum { PROCESSOR_BROADCAST_RECEIVER_STACK_SIZE = 4 * 1024 };
/**
* Functionality that can be broadcasted on all available processors
*/
class Processor_broadcast_operation;
/**
* Wrapper for the signalling between broadcast and receiver
*/
class Processor_broadcast_signal;
/**
* Processor local receiver of broadcasted functions
*/
class Processor_broadcast_receiver;
/**
* Executes a function on all available processors
*/
class Processor_broadcast;
/**
* Return broadcast singleton
*/
Processor_broadcast * processor_broadcast();
}
class Genode::Processor_broadcast_operation
{
public:
typedef void (*Entry)(void * const);
private:
Entry const _entry;
void * const _data;
public:
/**
* Constructor
*
* \param entry entry to the operation code
* \param data pointer to operation specific input/output data
*/
Processor_broadcast_operation(Entry const entry, void * const data)
:
_entry(entry), _data(data)
{ }
/**
* Execute operation processor-locally
*/
void execute() const { _entry(_data); }
};
class Genode::Processor_broadcast_signal
{
private:
Signal_context _context;
Signal_receiver _receiver;
Signal_transmitter _transmitter;
public:
/**
* Constructor
*/
Processor_broadcast_signal()
:
_transmitter(_receiver.manage(&_context))
{ }
/**
* Submit the signal
*/
void submit() { _transmitter.submit(); }
/**
* Wait for signal submission
*/
void await() { _receiver.wait_for_signal(); }
};
class Genode::Processor_broadcast_receiver
:
public Thread<PROCESSOR_BROADCAST_RECEIVER_STACK_SIZE>
{
private:
typedef Processor_broadcast_operation Operation;
typedef Processor_broadcast_signal Signal;
Operation const * _operation;
Signal _start;
Signal _end;
public:
/**
* Constructor
*/
Processor_broadcast_receiver() : Thread("processor_broadcast") { }
/**
* Start receiver on a specific processor
*
* \param processor_id kernel name of targeted processor
*/
void init(unsigned const processor_id)
{
Thread::utcb()->core_start_info()->init(processor_id);
Thread::start();
}
/**
* Start remote execution of an operation
*
* \param operation desired operation
*/
void start_executing(Operation const * const operation)
{
_operation = operation;
_start.submit();
}
/**
* Wait until the remote execution of the current operation is done
*/
void end_executing() { _end.await(); }
/*****************
** Thread_base **
*****************/
void entry()
{
while (1) {
_start.await();
_operation->execute();
_end.submit();
}
}
};
class Genode::Processor_broadcast
{
private:
typedef Processor_broadcast_operation Operation;
typedef Processor_broadcast_receiver Receiver;
Receiver _receiver[PROCESSORS];
public:
/**
* Constructor
*/
Processor_broadcast()
{
for (unsigned i = 0; i < PROCESSORS; i++) { _receiver[i].init(i); }
}
/**
* Execute operation on all available processors
*
* \param operation desired operation
*/
void execute(Operation const * const operation)
{
for (unsigned i = 0; i < PROCESSORS; i++) {
_receiver[i].start_executing(operation);
}
for (unsigned i = 0; i < PROCESSORS; i++) {
_receiver[i].end_executing();
}
}
};
#endif /* _PROCESSOR_BROADCAST_H_ */

View File

@ -1,6 +1,7 @@
/* /*
* \brief Singlethreaded minimalistic kernel * \brief Singlethreaded minimalistic kernel
* \author Martin Stein * \author Martin Stein
* \author Stefan Kalkowski
* \date 2011-10-20 * \date 2011-10-20
* *
* This kernel is the only code except the mode transition PIC, that runs in * This kernel is the only code except the mode transition PIC, that runs in
@ -92,34 +93,28 @@ namespace Kernel
/** /**
* Static kernel PD that describes core * Static kernel PD that describes core
*/ */
Pd * core() Pd * core_pd()
{ {
/** /**
* Core protection-domain * Core protection-domain
*/ */
class Core_pd : public Pd struct Core_pd : public Platform_pd, public Pd
{ {
public: /**
* Constructor
/** */
* Constructor Core_pd(Tlb * const tlb)
*/ : Platform_pd(tlb),
Core_pd(Tlb * const tlb, Platform_pd * const platform_pd) Pd(tlb, this)
: {
Pd(tlb, platform_pd) Platform_pd::_id = Pd::id();
{ } }
}; };
constexpr int tlb_align = 1 << Core_tlb::ALIGNM_LOG2; constexpr int tlb_align = 1 << Core_tlb::ALIGNM_LOG2;
Core_tlb * core_tlb = unmanaged_singleton<Core_tlb, tlb_align>(); Core_tlb * core_tlb = unmanaged_singleton<Core_tlb, tlb_align>();
Core_pd * core_pd = unmanaged_singleton<Core_pd>(core_tlb, nullptr); return unmanaged_singleton<Core_pd>(core_tlb);
return core_pd;
} }
/**
* Get core attributes
*/
unsigned core_id() { return core()->id(); }
/** /**
* Return wether an interrupt is private to the kernel * Return wether an interrupt is private to the kernel
* *
@ -189,8 +184,8 @@ extern "C" void init_kernel_uniprocessor()
************************************************************************/ ************************************************************************/
/* calculate in advance as needed later when data writes aren't allowed */ /* calculate in advance as needed later when data writes aren't allowed */
core_tlb_base = core()->tlb()->base(); core_tlb_base = core_pd()->tlb()->base();
core_pd_id = core_id(); core_pd_id = core_pd()->id();
/* initialize all processor objects */ /* initialize all processor objects */
processor_pool(); processor_pool();
@ -275,7 +270,7 @@ extern "C" void init_kernel_multiprocessor()
_main_thread_utcb->start_info()->init(t.id(), Genode::Native_capability()); _main_thread_utcb->start_info()->init(t.id(), Genode::Native_capability());
t.ip = (addr_t)CORE_MAIN;; t.ip = (addr_t)CORE_MAIN;;
t.sp = (addr_t)s + STACK_SIZE; t.sp = (addr_t)s + STACK_SIZE;
t.init(processor_pool()->processor(processor_id), core(), &utcb, 1); t.init(processor_pool()->processor(processor_id), core_pd(), &utcb, 1);
/* initialize interrupt objects */ /* initialize interrupt objects */
static Genode::uint8_t _irqs[Pic::MAX_INTERRUPT_ID * sizeof(Irq)]; static Genode::uint8_t _irqs[Pic::MAX_INTERRUPT_ID * sizeof(Irq)];
@ -312,6 +307,9 @@ extern "C" void kernel()
Processor_client * const old_occupant = scheduler->occupant(); Processor_client * const old_occupant = scheduler->occupant();
old_occupant->exception(processor_id); old_occupant->exception(processor_id);
/* check for TLB maintainance requirements */
processor->flush_tlb();
/* /*
* The processor local as well as remote exception-handling may have * The processor local as well as remote exception-handling may have
* changed the scheduling of the local activities. Hence we must update the * changed the scheduling of the local activities. Hence we must update the
@ -338,5 +336,5 @@ Kernel::Cpu_context::Cpu_context()
_init(STACK_SIZE); _init(STACK_SIZE);
sp = (addr_t)kernel_stack; sp = (addr_t)kernel_stack;
ip = (addr_t)kernel; ip = (addr_t)kernel;
core()->admit(this); core_pd()->admit(this);
} }

View File

@ -1,6 +1,7 @@
/* /*
* \brief Singlethreaded minimalistic kernel * \brief Singlethreaded minimalistic kernel
* \author Martin Stein * \author Martin Stein
* \author Stefan Kalkowski
* \date 2013-09-30 * \date 2013-09-30
*/ */
@ -14,6 +15,8 @@
#ifndef _KERNEL__KERNEL_H_ #ifndef _KERNEL__KERNEL_H_
#define _KERNEL__KERNEL_H_ #define _KERNEL__KERNEL_H_
namespace Kernel { unsigned core_id(); } #include <kernel/pd.h>
namespace Kernel { Pd * core_pd(); }
#endif /* _KERNEL__KERNEL_H_ */ #endif /* _KERNEL__KERNEL_H_ */

View File

@ -1,6 +1,7 @@
/* /*
* \brief A multiplexable common instruction processor * \brief A multiplexable common instruction processor
* \author Martin Stein * \author Martin Stein
* \author Stefan Kalkowski
* \date 2014-01-14 * \date 2014-01-14
*/ */
@ -13,6 +14,7 @@
/* core includes */ /* core includes */
#include <kernel/processor.h> #include <kernel/processor.h>
#include <kernel/thread.h>
#include <kernel/irq.h> #include <kernel/irq.h>
#include <pic.h> #include <pic.h>
#include <timer.h> #include <timer.h>
@ -59,6 +61,25 @@ void Kernel::Processor_client::_interrupt(unsigned const processor_id)
void Kernel::Processor_client::_schedule() { __processor->schedule(this); } void Kernel::Processor_client::_schedule() { __processor->schedule(this); }
void Kernel::Processor_client::tlb_to_flush(unsigned pd_id)
{
/* initialize pd and reference counter, and remove client from scheduler */
_flush_tlb_pd_id = pd_id;
_flush_tlb_ref_cnt = PROCESSORS;
_unschedule();
}
void Kernel::Processor_client::flush_tlb_by_id()
{
Processor::flush_tlb_by_pid(_flush_tlb_pd_id);
/* if reference counter reaches zero, add client to scheduler again */
if (--_flush_tlb_ref_cnt == 0)
_schedule();
}
void Kernel::Processor::schedule(Processor_client * const client) void Kernel::Processor::schedule(Processor_client * const client)
{ {
if (_id != executing_id()) { if (_id != executing_id()) {
@ -99,3 +120,28 @@ void Kernel::Processor_client::_yield()
assert(__processor->id() == Processor::executing_id()); assert(__processor->id() == Processor::executing_id());
__processor->scheduler()->yield_occupation(); __processor->scheduler()->yield_occupation();
} }
void Kernel::Processor::flush_tlb(Processor_client * const client)
{
/* find the last working item in the TLB work queue */
Genode::List_element<Processor_client> * last = _ipi_scheduler.first();
while (last && last->next()) last = last->next();
/* insert new work item at the end of the work list */
_ipi_scheduler.insert(&client->_flush_tlb_li, last);
/* enforce kernel entry of the corresponding processor */
pic()->trigger_ip_interrupt(_id);
}
void Kernel::Processor::flush_tlb()
{
/* iterate through the list of TLB work items, and proceed them */
for (Genode::List_element<Processor_client> * cli = _ipi_scheduler.first(); cli;
cli = _ipi_scheduler.first()) {
cli->object()->flush_tlb_by_id();
_ipi_scheduler.remove(cli);
}
}

View File

@ -1,6 +1,7 @@
/* /*
* \brief A multiplexable common instruction processor * \brief A multiplexable common instruction processor
* \author Martin Stein * \author Martin Stein
* \author Stefan Kalkowski
* \date 2014-01-14 * \date 2014-01-14
*/ */
@ -18,6 +19,8 @@
#include <processor_driver.h> #include <processor_driver.h>
#include <kernel/scheduler.h> #include <kernel/scheduler.h>
#include <util/list.h>
namespace Kernel namespace Kernel
{ {
/** /**
@ -44,6 +47,14 @@ class Kernel::Processor_client : public Processor_scheduler::Item
protected: protected:
using List_item = Genode::List_element<Processor_client>;
List_item _flush_tlb_li; /* TLB maintainance work list item */
unsigned _flush_tlb_pd_id; /* id of pd that TLB entries are flushed */
unsigned _flush_tlb_ref_cnt; /* reference counter */
friend class Processor;
/** /**
* Handle an interrupt exception that occured during execution * Handle an interrupt exception that occured during execution
* *
@ -92,6 +103,18 @@ class Kernel::Processor_client : public Processor_scheduler::Item
*/ */
virtual void proceed(unsigned const processor_id) = 0; virtual void proceed(unsigned const processor_id) = 0;
/**
* Sets the pd id, which TLB entries should be flushed
*
* \param pd_id protection domain kernel object's id
*/
void tlb_to_flush(unsigned pd_id);
/**
* Flush TLB entries requested by this client on the current processor
*/
void flush_tlb_by_id();
/** /**
* Constructor * Constructor
* *
@ -101,7 +124,8 @@ class Kernel::Processor_client : public Processor_scheduler::Item
Processor_client(Processor * const processor, Priority const priority) Processor_client(Processor * const processor, Priority const priority)
: :
Processor_scheduler::Item(priority), Processor_scheduler::Item(priority),
__processor(processor) __processor(processor),
_flush_tlb_li(this)
{ } { }
/** /**
@ -118,8 +142,11 @@ class Kernel::Processor : public Processor_driver
{ {
private: private:
using Ipi_scheduler = Genode::List<Genode::List_element<Processor_client> >;
unsigned const _id; unsigned const _id;
Processor_scheduler _scheduler; Processor_scheduler _scheduler;
Ipi_scheduler _ipi_scheduler;
bool _ip_interrupt_pending; bool _ip_interrupt_pending;
public: public:
@ -157,6 +184,19 @@ class Kernel::Processor : public Processor_driver
void schedule(Processor_client * const client); void schedule(Processor_client * const client);
/**
* Add processor client to the TLB maintainance queue of the processor
*
* \param client targeted client
*/
void flush_tlb(Processor_client * const client);
/**
* Perform outstanding TLB maintainance work
*/
void flush_tlb();
/*************** /***************
** Accessors ** ** Accessors **
***************/ ***************/

View File

@ -1,6 +1,7 @@
/* /*
* \brief Provide a processor object for every available processor * \brief Provide a processor object for every available processor
* \author Martin Stein * \author Martin Stein
* \author Stefan Kalkowski
* \date 2014-01-14 * \date 2014-01-14
*/ */
@ -18,15 +19,11 @@
#include <unmanaged_singleton.h> #include <unmanaged_singleton.h>
/* core includes */ /* core includes */
#include <kernel/kernel.h>
#include <kernel/thread.h> #include <kernel/thread.h>
namespace Kernel namespace Kernel
{ {
/**
* Return kernel name of core domain
*/
Pd * core();
/** /**
* Thread that consumes processor time if no other thread is available * Thread that consumes processor time if no other thread is available
*/ */
@ -75,7 +72,7 @@ class Kernel::Idle_thread : public Thread
{ {
ip = (addr_t)&_main; ip = (addr_t)&_main;
sp = (addr_t)&_stack[STACK_SIZE]; sp = (addr_t)&_stack[STACK_SIZE];
init(processor, core(), 0, 0); init(processor, core_pd(), 0, 0);
} }
}; };

View File

@ -1,6 +1,7 @@
/* /*
* \brief Kernel backend for execution contexts in userland * \brief Kernel backend for execution contexts in userland
* \author Martin Stein * \author Martin Stein
* \author Stefan Kalkowski
* \date 2013-09-15 * \date 2013-09-15
*/ */
@ -31,7 +32,7 @@ typedef Genode::Thread_state Thread_state;
unsigned Thread::pd_id() const { return _pd ? _pd->id() : 0; } unsigned Thread::pd_id() const { return _pd ? _pd->id() : 0; }
bool Thread::_core() const { return pd_id() == core_id(); } bool Thread::_core() const { return pd_id() == core_pd()->id(); }
void Thread::_signal_context_kill_pending() void Thread::_signal_context_kill_pending()
{ {
@ -536,8 +537,11 @@ void Thread::_call_access_thread_regs()
void Thread::_call_update_pd() void Thread::_call_update_pd()
{ {
/* update hardware caches */ tlb_to_flush(user_arg_1());
Processor::flush_tlb_by_pid(user_arg_1());
/* inform other processors */
for (unsigned i = 0; i < PROCESSORS; i++)
Kernel::processor_pool()->processor(i)->flush_tlb(this);
} }

View File

@ -1,6 +1,7 @@
/* /*
* \brief Thread facility * \brief Thread facility
* \author Martin Stein * \author Martin Stein
* \author Stefan Kalkowski
* \date 2012-02-12 * \date 2012-02-12
*/ */
@ -13,12 +14,14 @@
/* core includes */ /* core includes */
#include <platform_thread.h> #include <platform_thread.h>
#include <platform_pd.h>
#include <core_env.h> #include <core_env.h>
#include <rm_session_component.h> #include <rm_session_component.h>
using namespace Genode; /* kernel includes */
#include <kernel/kernel.h>
namespace Kernel { unsigned core_id(); } using namespace Genode;
void Platform_thread::_init() { } void Platform_thread::_init() { }
@ -30,7 +33,7 @@ bool Platform_thread::_attaches_utcb_by_itself()
* virtual context area by itself, as it is done for other threads * virtual context area by itself, as it is done for other threads
* through a sub RM-session. * through a sub RM-session.
*/ */
return _pd_id == Kernel::core_id() || !_main_thread; return _pd == Kernel::core_pd()->platform_pd() || !_main_thread;
} }
@ -52,7 +55,7 @@ Platform_thread::~Platform_thread()
} }
} }
/* free UTCB */ /* free UTCB */
if (_pd_id == Kernel::core_id()) { if (_pd == Kernel::core_pd()->platform_pd()) {
Range_allocator * const ram = platform()->ram_alloc(); Range_allocator * const ram = platform()->ram_alloc();
ram->free(_utcb_phys, sizeof(Native_utcb)); ram->free(_utcb_phys, sizeof(Native_utcb));
} else { } else {
@ -76,11 +79,10 @@ Platform_thread::~Platform_thread()
Platform_thread::Platform_thread(size_t const stack_size, Platform_thread::Platform_thread(size_t const stack_size,
unsigned const pd_id,
const char * const label) const char * const label)
: :
_stack_size(stack_size), _stack_size(stack_size),
_pd_id(pd_id), _pd(Kernel::core_pd()->platform_pd()),
_rm_client(0), _rm_client(0),
_utcb_virt(0), _utcb_virt(0),
_main_thread(0) _main_thread(0)
@ -114,7 +116,7 @@ Platform_thread::Platform_thread(const char * const label,
addr_t const utcb) addr_t const utcb)
: :
_stack_size(0), _stack_size(0),
_pd_id(0), _pd(nullptr),
_rm_client(0), _rm_client(0),
_utcb_virt((Native_utcb *)utcb), _utcb_virt((Native_utcb *)utcb),
_main_thread(0) _main_thread(0)
@ -147,16 +149,16 @@ Platform_thread::Platform_thread(const char * const label,
} }
int Platform_thread::join_pd(unsigned const pd_id, bool const main_thread, int Platform_thread::join_pd(Platform_pd * pd, bool const main_thread,
Weak_ptr<Address_space> address_space) Weak_ptr<Address_space> address_space)
{ {
/* check if thread is already in another protection domain */ /* check if thread is already in another protection domain */
if (_pd_id && _pd_id != pd_id) { if (_pd && _pd != pd) {
PERR("thread already in another protection domain"); PERR("thread already in another protection domain");
return -1; return -1;
} }
/* join protection domain */ /* join protection domain */
_pd_id = pd_id; _pd = pd;
_main_thread = main_thread; _main_thread = main_thread;
_address_space = address_space; _address_space = address_space;
return 0; return 0;
@ -206,7 +208,7 @@ int Platform_thread::start(void * const ip, void * const sp)
/* start executing new thread */ /* start executing new thread */
_utcb_phys->start_info()->init(_id, _utcb); _utcb_phys->start_info()->init(_id, _utcb);
_tlb = Kernel::start_thread(_id, processor_id, _pd_id, _utcb_phys); _tlb = Kernel::start_thread(_id, processor_id, _pd->id(), _utcb_phys);
if (!_tlb) { if (!_tlb) {
PERR("failed to start thread"); PERR("failed to start thread");
return -1; return -1;

View File

@ -1,24 +0,0 @@
/*
* \brief Utility to execute a function on all available processors
* \author Martin Stein
* \date 2014-03-07
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* core includes */
#include <processor_broadcast.h>
using namespace Genode;
Processor_broadcast * Genode::processor_broadcast()
{
static Processor_broadcast s;
return &s;
}

View File

@ -1,6 +1,7 @@
/* /*
* \brief RM- and pager implementations specific for base-hw and core * \brief RM- and pager implementations specific for base-hw and core
* \author Martin Stein * \author Martin Stein
* \author Stefan Kalkowski
* \date 2012-02-12 * \date 2012-02-12
*/ */
@ -19,7 +20,6 @@
#include <platform.h> #include <platform.h>
#include <platform_pd.h> #include <platform_pd.h>
#include <platform_thread.h> #include <platform_thread.h>
#include <processor_broadcast.h>
#include <tlb.h> #include <tlb.h>
using namespace Genode; using namespace Genode;
@ -58,9 +58,7 @@ void Rm_client::unmap(addr_t, addr_t virt_base, size_t size)
tlb->remove_region(virt_base, size); tlb->remove_region(virt_base, size);
/* update translation caches of all processors */ /* update translation caches of all processors */
Update_pd_data data { pt->pd_id() }; Kernel::update_pd(pt->pd()->id());
Processor_broadcast_operation const operation(update_pd, &data);
processor_broadcast()->execute(&operation);
/* try to get back released memory from the translation table */ /* try to get back released memory from the translation table */
regain_ram_from_tlb(tlb); regain_ram_from_tlb(tlb);

View File

@ -54,7 +54,6 @@ SRC_CC += console.cc \
kernel/irq.cc \ kernel/irq.cc \
kernel/processor.cc \ kernel/processor.cc \
kernel/processor_pool.cc \ kernel/processor_pool.cc \
processor_broadcast.cc \
rm_session_support.cc \ rm_session_support.cc \
trustzone.cc \ trustzone.cc \
pager.cc \ pager.cc \

View File

@ -19,6 +19,7 @@
/* core includes */ /* core includes */
#include <platform.h> #include <platform.h>
#include <platform_thread.h> #include <platform_thread.h>
#include <kernel/kernel.h>
using namespace Genode; using namespace Genode;
@ -56,7 +57,7 @@ void Thread_base::_thread_start()
Thread_base::Thread_base(const char * const label, size_t const stack_size, Type) Thread_base::Thread_base(const char * const label, size_t const stack_size, Type)
{ {
_tid.platform_thread = new (platform()->core_mem_alloc()) _tid.platform_thread = new (platform()->core_mem_alloc())
Platform_thread(stack_size, Kernel::core_id(), label); Platform_thread(stack_size, label);
} }