mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-16 07:27:35 +00:00
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:
parent
b888a26d57
commit
34b18e9da2
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* \brief Platform specific part of a Genode protection domain
|
||||
* \author Martin Stein
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2012-02-12
|
||||
*/
|
||||
|
||||
@ -45,14 +46,22 @@ namespace Genode
|
||||
*/
|
||||
class Platform_pd : public Address_space
|
||||
{
|
||||
unsigned _id;
|
||||
Native_capability _parent;
|
||||
Native_thread_id _main_thread;
|
||||
char const * const _label;
|
||||
Tlb * _tlb;
|
||||
protected:
|
||||
|
||||
unsigned _id;
|
||||
Native_capability _parent;
|
||||
Native_thread_id _main_thread;
|
||||
char const * const _label;
|
||||
Tlb * _tlb;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for core pd
|
||||
*/
|
||||
Platform_pd(Tlb * tlb)
|
||||
: _main_thread(0), _label("core"), _tlb(tlb) { }
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
@ -95,9 +104,9 @@ namespace Genode
|
||||
{
|
||||
/* annotate that we've got a main thread from now on */
|
||||
_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 **
|
||||
***************/
|
||||
|
||||
unsigned const id() { return _id; }
|
||||
char const * const label() { return _label; }
|
||||
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* \brief Userland interface for the management of kernel thread-objects
|
||||
* \author Martin Stein
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2012-02-02
|
||||
*/
|
||||
|
||||
@ -42,7 +43,7 @@ namespace Genode {
|
||||
enum { LABEL_MAX_LEN = 32 };
|
||||
|
||||
size_t _stack_size;
|
||||
unsigned _pd_id;
|
||||
Platform_pd * _pd;
|
||||
Weak_ptr<Address_space> _address_space;
|
||||
unsigned _id;
|
||||
Rm_client * _rm_client;
|
||||
@ -81,11 +82,9 @@ namespace Genode {
|
||||
* Constructor for core threads
|
||||
*
|
||||
* \param stack_size initial size of the stack
|
||||
* \param pd_id kernel name of targeted protection domain
|
||||
* \param label debugging label
|
||||
*/
|
||||
Platform_thread(size_t const stack_size,
|
||||
unsigned const pd_id, const char * const label);
|
||||
Platform_thread(size_t const stack_size, const char * const label);
|
||||
|
||||
/**
|
||||
* Constructor for threads outside of core
|
||||
@ -105,14 +104,14 @@ namespace Genode {
|
||||
/**
|
||||
* 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 address_space corresponding Genode address space
|
||||
*
|
||||
* \retval 0 succeeded
|
||||
* \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);
|
||||
|
||||
/**
|
||||
@ -179,7 +178,7 @@ namespace Genode {
|
||||
|
||||
Pager_object * pager();
|
||||
|
||||
unsigned pd_id() const { return _pd_id; }
|
||||
Platform_pd * pd() const { return _pd; }
|
||||
|
||||
Native_thread_id id() const { return _id; }
|
||||
|
||||
|
@ -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_ */
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* \brief Singlethreaded minimalistic kernel
|
||||
* \author Martin Stein
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2011-10-20
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
Pd * core()
|
||||
Pd * core_pd()
|
||||
{
|
||||
/**
|
||||
* Core protection-domain
|
||||
*/
|
||||
class Core_pd : public Pd
|
||||
struct Core_pd : public Platform_pd, public Pd
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Core_pd(Tlb * const tlb, Platform_pd * const platform_pd)
|
||||
:
|
||||
Pd(tlb, platform_pd)
|
||||
{ }
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Core_pd(Tlb * const tlb)
|
||||
: Platform_pd(tlb),
|
||||
Pd(tlb, this)
|
||||
{
|
||||
Platform_pd::_id = Pd::id();
|
||||
}
|
||||
};
|
||||
constexpr int tlb_align = 1 << Core_tlb::ALIGNM_LOG2;
|
||||
Core_tlb * core_tlb = unmanaged_singleton<Core_tlb, tlb_align>();
|
||||
Core_pd * core_pd = unmanaged_singleton<Core_pd>(core_tlb, nullptr);
|
||||
return core_pd;
|
||||
return unmanaged_singleton<Core_pd>(core_tlb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get core attributes
|
||||
*/
|
||||
unsigned core_id() { return core()->id(); }
|
||||
|
||||
/**
|
||||
* 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 */
|
||||
core_tlb_base = core()->tlb()->base();
|
||||
core_pd_id = core_id();
|
||||
core_tlb_base = core_pd()->tlb()->base();
|
||||
core_pd_id = core_pd()->id();
|
||||
|
||||
/* initialize all processor objects */
|
||||
processor_pool();
|
||||
@ -275,7 +270,7 @@ extern "C" void init_kernel_multiprocessor()
|
||||
_main_thread_utcb->start_info()->init(t.id(), Genode::Native_capability());
|
||||
t.ip = (addr_t)CORE_MAIN;;
|
||||
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 */
|
||||
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();
|
||||
old_occupant->exception(processor_id);
|
||||
|
||||
/* check for TLB maintainance requirements */
|
||||
processor->flush_tlb();
|
||||
|
||||
/*
|
||||
* The processor local as well as remote exception-handling may have
|
||||
* changed the scheduling of the local activities. Hence we must update the
|
||||
@ -338,5 +336,5 @@ Kernel::Cpu_context::Cpu_context()
|
||||
_init(STACK_SIZE);
|
||||
sp = (addr_t)kernel_stack;
|
||||
ip = (addr_t)kernel;
|
||||
core()->admit(this);
|
||||
core_pd()->admit(this);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* \brief Singlethreaded minimalistic kernel
|
||||
* \author Martin Stein
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2013-09-30
|
||||
*/
|
||||
|
||||
@ -14,6 +15,8 @@
|
||||
#ifndef _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_ */
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* \brief A multiplexable common instruction processor
|
||||
* \author Martin Stein
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2014-01-14
|
||||
*/
|
||||
|
||||
@ -13,6 +14,7 @@
|
||||
|
||||
/* core includes */
|
||||
#include <kernel/processor.h>
|
||||
#include <kernel/thread.h>
|
||||
#include <kernel/irq.h>
|
||||
#include <pic.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::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)
|
||||
{
|
||||
if (_id != executing_id()) {
|
||||
@ -99,3 +120,28 @@ void Kernel::Processor_client::_yield()
|
||||
assert(__processor->id() == Processor::executing_id());
|
||||
__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);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* \brief A multiplexable common instruction processor
|
||||
* \author Martin Stein
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2014-01-14
|
||||
*/
|
||||
|
||||
@ -18,6 +19,8 @@
|
||||
#include <processor_driver.h>
|
||||
#include <kernel/scheduler.h>
|
||||
|
||||
#include <util/list.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
/**
|
||||
@ -44,6 +47,14 @@ class Kernel::Processor_client : public Processor_scheduler::Item
|
||||
|
||||
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
|
||||
*
|
||||
@ -92,6 +103,18 @@ class Kernel::Processor_client : public Processor_scheduler::Item
|
||||
*/
|
||||
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
|
||||
*
|
||||
@ -101,7 +124,8 @@ class Kernel::Processor_client : public Processor_scheduler::Item
|
||||
Processor_client(Processor * const processor, Priority const priority)
|
||||
:
|
||||
Processor_scheduler::Item(priority),
|
||||
__processor(processor)
|
||||
__processor(processor),
|
||||
_flush_tlb_li(this)
|
||||
{ }
|
||||
|
||||
/**
|
||||
@ -118,8 +142,11 @@ class Kernel::Processor : public Processor_driver
|
||||
{
|
||||
private:
|
||||
|
||||
using Ipi_scheduler = Genode::List<Genode::List_element<Processor_client> >;
|
||||
|
||||
unsigned const _id;
|
||||
Processor_scheduler _scheduler;
|
||||
Ipi_scheduler _ipi_scheduler;
|
||||
bool _ip_interrupt_pending;
|
||||
|
||||
public:
|
||||
@ -157,6 +184,19 @@ class Kernel::Processor : public Processor_driver
|
||||
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 **
|
||||
***************/
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* \brief Provide a processor object for every available processor
|
||||
* \author Martin Stein
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2014-01-14
|
||||
*/
|
||||
|
||||
@ -18,15 +19,11 @@
|
||||
#include <unmanaged_singleton.h>
|
||||
|
||||
/* core includes */
|
||||
#include <kernel/kernel.h>
|
||||
#include <kernel/thread.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
/**
|
||||
* Return kernel name of core domain
|
||||
*/
|
||||
Pd * core();
|
||||
|
||||
/**
|
||||
* 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;
|
||||
sp = (addr_t)&_stack[STACK_SIZE];
|
||||
init(processor, core(), 0, 0);
|
||||
init(processor, core_pd(), 0, 0);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* \brief Kernel backend for execution contexts in userland
|
||||
* \author Martin Stein
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2013-09-15
|
||||
*/
|
||||
|
||||
@ -31,7 +32,7 @@ typedef Genode::Thread_state Thread_state;
|
||||
|
||||
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()
|
||||
{
|
||||
@ -536,8 +537,11 @@ void Thread::_call_access_thread_regs()
|
||||
|
||||
void Thread::_call_update_pd()
|
||||
{
|
||||
/* update hardware caches */
|
||||
Processor::flush_tlb_by_pid(user_arg_1());
|
||||
tlb_to_flush(user_arg_1());
|
||||
|
||||
/* inform other processors */
|
||||
for (unsigned i = 0; i < PROCESSORS; i++)
|
||||
Kernel::processor_pool()->processor(i)->flush_tlb(this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* \brief Thread facility
|
||||
* \author Martin Stein
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2012-02-12
|
||||
*/
|
||||
|
||||
@ -13,12 +14,14 @@
|
||||
|
||||
/* core includes */
|
||||
#include <platform_thread.h>
|
||||
#include <platform_pd.h>
|
||||
#include <core_env.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() { }
|
||||
|
||||
@ -30,7 +33,7 @@ bool Platform_thread::_attaches_utcb_by_itself()
|
||||
* virtual context area by itself, as it is done for other threads
|
||||
* 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 */
|
||||
if (_pd_id == Kernel::core_id()) {
|
||||
if (_pd == Kernel::core_pd()->platform_pd()) {
|
||||
Range_allocator * const ram = platform()->ram_alloc();
|
||||
ram->free(_utcb_phys, sizeof(Native_utcb));
|
||||
} else {
|
||||
@ -76,11 +79,10 @@ Platform_thread::~Platform_thread()
|
||||
|
||||
|
||||
Platform_thread::Platform_thread(size_t const stack_size,
|
||||
unsigned const pd_id,
|
||||
const char * const label)
|
||||
:
|
||||
_stack_size(stack_size),
|
||||
_pd_id(pd_id),
|
||||
_pd(Kernel::core_pd()->platform_pd()),
|
||||
_rm_client(0),
|
||||
_utcb_virt(0),
|
||||
_main_thread(0)
|
||||
@ -114,7 +116,7 @@ Platform_thread::Platform_thread(const char * const label,
|
||||
addr_t const utcb)
|
||||
:
|
||||
_stack_size(0),
|
||||
_pd_id(0),
|
||||
_pd(nullptr),
|
||||
_rm_client(0),
|
||||
_utcb_virt((Native_utcb *)utcb),
|
||||
_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)
|
||||
{
|
||||
/* 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");
|
||||
return -1;
|
||||
}
|
||||
/* join protection domain */
|
||||
_pd_id = pd_id;
|
||||
_pd = pd;
|
||||
_main_thread = main_thread;
|
||||
_address_space = address_space;
|
||||
return 0;
|
||||
@ -206,7 +208,7 @@ int Platform_thread::start(void * const ip, void * const sp)
|
||||
|
||||
/* start executing new thread */
|
||||
_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) {
|
||||
PERR("failed to start thread");
|
||||
return -1;
|
||||
|
@ -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;
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* \brief RM- and pager implementations specific for base-hw and core
|
||||
* \author Martin Stein
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2012-02-12
|
||||
*/
|
||||
|
||||
@ -19,7 +20,6 @@
|
||||
#include <platform.h>
|
||||
#include <platform_pd.h>
|
||||
#include <platform_thread.h>
|
||||
#include <processor_broadcast.h>
|
||||
#include <tlb.h>
|
||||
|
||||
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);
|
||||
|
||||
/* update translation caches of all processors */
|
||||
Update_pd_data data { pt->pd_id() };
|
||||
Processor_broadcast_operation const operation(update_pd, &data);
|
||||
processor_broadcast()->execute(&operation);
|
||||
Kernel::update_pd(pt->pd()->id());
|
||||
|
||||
/* try to get back released memory from the translation table */
|
||||
regain_ram_from_tlb(tlb);
|
||||
|
@ -54,7 +54,6 @@ SRC_CC += console.cc \
|
||||
kernel/irq.cc \
|
||||
kernel/processor.cc \
|
||||
kernel/processor_pool.cc \
|
||||
processor_broadcast.cc \
|
||||
rm_session_support.cc \
|
||||
trustzone.cc \
|
||||
pager.cc \
|
||||
|
@ -19,6 +19,7 @@
|
||||
/* core includes */
|
||||
#include <platform.h>
|
||||
#include <platform_thread.h>
|
||||
#include <kernel/kernel.h>
|
||||
|
||||
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)
|
||||
{
|
||||
_tid.platform_thread = new (platform()->core_mem_alloc())
|
||||
Platform_thread(stack_size, Kernel::core_id(), label);
|
||||
Platform_thread(stack_size, label);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user