Loading...
Searching...
No Matches
examples/sys/aliens/main.c

This example shows how system call tracing can be done.

This example shows how system call tracing can be done.

/*
* (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
* Alexander Warg <warg@os.inf.tu-dresden.de>,
* Björn Döbel <doebel@os.inf.tu-dresden.de>
* economic rights: Technische Universität Dresden (Germany)
*
* This file is part of TUD:OS and distributed under the terms of the
* GNU General Public License 2.
* Please see the COPYING-GPL-2 file for details.
*/
/*
* Example to show syscall tracing.
*/
#if defined(ARCH_x86) || defined(ARCH_amd64)
// MEASURE only works on x86/amd64
//#define MEASURE
#endif
#include <l4/sys/ipc.h>
#include <l4/sys/thread.h>
#include <l4/sys/factory.h>
#include <l4/sys/utcb.h>
#include <l4/util/util.h>
#include <l4/re/env.h>
#include <l4/re/c/util/cap_alloc.h>
#include <l4/re/c/util/kumem_alloc.h>
#include <l4/sys/debugger.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/* Architecture specifics */
#if defined(ARCH_x86) || defined(ARCH_amd64)
static int
is_alien_after_call(l4_exc_regs_t const *exc)
{
#if defined(ARCH_x86)
return exc->err & 4;
#else
return exc->err == 1;
#endif
}
static inline void
_print_exc_state(l4_exc_regs_t const *exc)
{
printf("PC=%08lx SP=%08lx Err=%08lx Trap=%lx, %s syscall, SC-Nr: %lx\n",
l4_utcb_exc_pc(exc), exc->sp, exc->err,
exc->trapno, is_alien_after_call(exc) ? " after" : "before",
exc->err >> 3);
}
#elif defined(ARCH_arm)
static int
is_alien_after_call(l4_exc_regs_t const *exc)
{ return exc->err & 0x40; } // TODO: Should change this to (1 << 16)
static inline void
_print_exc_state(l4_exc_regs_t const *exc)
{
printf("PC=%08lx SP=%08lx ULR=%08lx CPSR=%08lx Err=%lx/%lx, %s syscall\n",
l4_utcb_exc_pc(exc), exc->sp, exc->ulr, exc->cpsr,
exc->err, exc->err >> 26,
is_alien_after_call(exc) ? " after" : "before");
}
#elif defined(ARCH_arm64)
static int
is_alien_after_call(l4_exc_regs_t const *exc)
{ return exc->err & (1ul << 16); }
static inline void
_print_exc_state(l4_exc_regs_t const *exc)
{
printf("PC=%08lx SP=%08lx PSTATE=%08lx Err=%lx/%lx, %s syscall\n",
l4_utcb_exc_pc(exc), exc->sp, exc->pstate,
exc->err, exc->err >> 26,
is_alien_after_call(exc) ? " after" : "before");
}
#elif defined(ARCH_mips)
static int
is_alien_after_call(l4_exc_regs_t const *exc)
{ return 0; }
static inline void
_print_exc_state(l4_exc_regs_t const *exc)
{
printf("PC=%08lx SP=%08lx Cause=%lx, %s syscall\n",
l4_utcb_exc_pc(exc), exc->sp, exc->cause,
is_alien_after_call(exc) ? " after" : "before");
}
#elif defined(ARCH_riscv)
static int
is_alien_after_call(l4_exc_regs_t const *exc)
{ return exc->cause == L4_riscv_ec_l4_alien_after_syscall; }
static inline void
_print_exc_state(l4_exc_regs_t const *exc)
{
printf("PC=%08lx SP=%08lx Cause=%lx, %s syscall\n",
l4_utcb_exc_pc(exc), exc->sp, exc->cause,
is_alien_after_call(exc) ? " after" : "before");
}
#else
static int
is_alien_after_call(l4_exc_regs_t const *exc)
{ return exc->err & 1; }
static inline void
_print_exc_state(l4_exc_regs_t const *exc)
{
printf("PC=%08lx SP=%08lx, %s syscall\n",
l4_utcb_exc_pc(exc), exc->sp,
is_alien_after_call(exc) ? " after" : "before");
}
#endif
/* Measurement mode specifics.
*
* In measurement mode the code is less verbose and uses RDTSC for alient exception
* performance measurement.
*/
#ifdef MEASURE
#include <l4/util/rdtsc.h>
static inline void
calibrate_timer(void)
{
l4_calibrate_tsc(l4re_kip());
}
static inline void
print_timediff(l4_cpu_time_t start)
{
e = l4_rdtsc();
printf("time %lld\n", l4_tsc_to_ns(e - start));
}
static inline void
alien_sleep(void)
{
l4_sleep(0);
}
static inline void
print_exc_state(l4_exc_regs_t const *exc)
{
if (0)
_print_exc_state(exc);
}
#else
static inline void
calibrate_timer(void)
{
}
static inline void
print_timediff(l4_cpu_time_t start)
{
(void)start;
}
static inline l4_cpu_time_t
l4_rdtsc(void)
{
return 0;
}
static inline void
alien_sleep(void)
{
l4_sleep(1000);
}
static inline void
print_exc_state(l4_exc_regs_t const *exc)
{
_print_exc_state(exc);
}
#endif
static char alien_thread_stack[8 << 10];
static l4_cap_idx_t alien;
static void alien_thread(void)
{
while (1)
{
l4_ipc_call(0x1234 << L4_CAP_SHIFT, l4_utcb(),
l4_msgtag(0, 0, 0, 0), L4_IPC_NEVER);
alien_sleep();
}
}
int main(void)
{
l4_msgtag_t tag;
l4_cpu_time_t s;
l4_utcb_t *u = l4_utcb();
l4_exc_regs_t exc;
l4_umword_t mr0, mr1;
printf("Alien feature testing\n");
l4_debugger_set_object_name(l4re_env()->main_thread, "alientest");
/* Start alien thread */
if (l4_is_invalid_cap(alien = l4re_util_cap_alloc()))
return 1;
l4_touch_rw(alien_thread_stack, sizeof(alien_thread_stack));
tag = l4_factory_create_thread(l4re_env()->factory, alien);
if (l4_error(tag))
return 2;
l4_debugger_set_object_name(alien, "alienth");
l4_addr_t kumem;
if (l4re_util_kumem_alloc(&kumem, 0, L4RE_THIS_TASK_CAP, l4re_env()->rm))
return 3;
l4_thread_control_start();
l4_thread_control_pager(l4re_env()->main_thread);
l4_thread_control_exc_handler(l4re_env()->main_thread);
l4_thread_control_bind((l4_utcb_t *)kumem, L4RE_THIS_TASK_CAP);
l4_thread_control_alien(1);
tag = l4_thread_control_commit(alien);
if (l4_error(tag))
return 4;
tag = l4_thread_ex_regs(alien,
(l4_umword_t)alien_thread,
(l4_umword_t)alien_thread_stack + sizeof(alien_thread_stack),
0);
if (l4_error(tag))
return 5;
l4_sched_param_t sp = l4_sched_param(1, 0);
tag = l4_scheduler_run_thread(l4re_env()->scheduler, alien, &sp);
if (l4_error(tag))
return 6;
calibrate_timer();
/* Pager/Exception loop */
if (l4_msgtag_has_error(tag = l4_ipc_receive(alien, u, L4_IPC_NEVER)))
{
printf("l4_ipc_receive failed");
return 7;
}
memcpy(&exc, l4_utcb_exc(), sizeof(exc));
mr0 = l4_utcb_mr()->mr[0];
mr1 = l4_utcb_mr()->mr[1];
for (;;)
{
s = l4_rdtsc();
if (l4_msgtag_is_exception(tag))
{
print_exc_state(&exc);
tag = l4_msgtag(is_alien_after_call(&exc)
? 0 : L4_PROTO_ALLOW_SYSCALL,
L4_UTCB_EXCEPTION_REGS_SIZE, 0, 0);
}
else
printf("Umm, non-handled request (like PF): %lx %lx\n", mr0, mr1);
memcpy(l4_utcb_exc(), &exc, sizeof(exc));
/* Reply and wait */
if (l4_msgtag_has_error(tag = l4_ipc_call(alien, u, tag, L4_IPC_NEVER)))
{
printf("l4_ipc_call failed\n");
return 8;
}
memcpy(&exc, l4_utcb_exc(), sizeof(exc));
mr0 = l4_utcb_mr()->mr[0];
mr1 = l4_utcb_mr()->mr[1];
print_timediff(s);
}
return 0;
}
cap_alloc.h
Capability allocator C interface.
debugger.h
Debugger related definitions.
env.h
Environment interface.
factory.h
Common factory related definitions.
l4re_util_cap_alloc
L4_BEGIN_DECLS l4_cap_idx_t l4re_util_cap_alloc(void) L4_NOTHROW
Get free capability index at capability allocator.
l4re_kip
l4_kernel_info_t const * l4re_kip(void) L4_NOTHROW
Get Kernel Info Page.
Definition env.h:185
l4re_env
l4re_env_t * l4re_env(void) L4_NOTHROW
Get L4Re initial environment.
Definition env.h:181
l4_umword_t
unsigned long l4_umword_t
Unsigned machine word.
Definition l4int.h:40
l4_addr_t
unsigned long l4_addr_t
Address type.
Definition l4int.h:34
l4_cpu_time_t
l4_uint64_t l4_cpu_time_t
CPU clock type.
Definition l4int.h:47
l4_cap_idx_t
unsigned long l4_cap_idx_t
Capability selector type.
Definition types.h:336
l4_is_invalid_cap
unsigned l4_is_invalid_cap(l4_cap_idx_t c) L4_NOTHROW
Test if a capability selector is the invalid capability.
Definition types.h:389
L4_CAP_SHIFT
@ L4_CAP_SHIFT
Capability index shift.
Definition consts.h:142
l4_debugger_set_object_name
l4_msgtag_t l4_debugger_set_object_name(l4_cap_idx_t cap, const char *name) L4_NOTHROW
Set the name of a kernel object.
Definition debugger.h:368
l4_factory_create_thread
l4_msgtag_t l4_factory_create_thread(l4_cap_idx_t factory, l4_cap_idx_t target_cap) L4_NOTHROW
Create a new thread.
Definition factory.h:538
l4_ipc_receive
l4_msgtag_t l4_ipc_receive(l4_cap_idx_t object, l4_utcb_t *utcb, l4_timeout_t timeout) L4_NOTHROW
Wait for a message from a specific source.
Definition ipc.h:602
l4_ipc_call
l4_msgtag_t l4_ipc_call(l4_cap_idx_t object, l4_utcb_t *utcb, l4_msgtag_t tag, l4_timeout_t timeout) L4_NOTHROW
Object call (usual invocation).
Definition ipc.h:565
l4_error
long l4_error(l4_msgtag_t tag) L4_NOTHROW
Get IPC error code if any or message tag label otherwise for an IPC call.
Definition ipc.h:646
l4_msgtag_is_exception
unsigned l4_msgtag_is_exception(l4_msgtag_t t) L4_NOTHROW
Test for exception protocol.
Definition types.h:448
l4_msgtag_has_error
unsigned l4_msgtag_has_error(l4_msgtag_t t) L4_NOTHROW
Test for error indicator flag.
Definition types.h:440
l4_msgtag
l4_msgtag_t l4_msgtag(long label, unsigned words, unsigned items, unsigned flags) L4_NOTHROW
Create a message tag from the specified values.
Definition types.h:405
L4_PROTO_ALLOW_SYSCALL
@ L4_PROTO_ALLOW_SYSCALL
Allow an alien the system call.
Definition types.h:41
l4_scheduler_run_thread
l4_msgtag_t l4_scheduler_run_thread(l4_cap_idx_t scheduler, l4_cap_idx_t thread, l4_sched_param_t const *sp) L4_NOTHROW)
Run a thread on a Scheduler.
Definition scheduler.h:396
l4_sched_param
l4_sched_param_t l4_sched_param(unsigned prio, l4_umword_t quantum=0) L4_NOTHROW
Construct scheduler parameter.
Definition scheduler.h:289
l4_thread_ex_regs
l4_msgtag_t l4_thread_ex_regs(l4_cap_idx_t thread, l4_addr_t ip, l4_addr_t sp, l4_umword_t flags) L4_NOTHROW
Exchange basic thread registers.
Definition thread.h:942
l4_thread_control_bind
void l4_thread_control_bind(l4_utcb_t *thread_utcb, l4_cap_idx_t task) L4_NOTHROW
Bind the thread to a task.
Definition thread.h:975
l4_thread_control_commit
l4_msgtag_t l4_thread_control_commit(l4_cap_idx_t thread) L4_NOTHROW
Commit the thread control parameters.
Definition thread.h:987
l4_thread_control_alien
void l4_thread_control_alien(int on) L4_NOTHROW
Enable alien mode.
Definition thread.h:981
l4_thread_control_exc_handler
void l4_thread_control_exc_handler(l4_cap_idx_t exc_handler) L4_NOTHROW
Set the exception handler.
Definition thread.h:968
l4_thread_control_start
void l4_thread_control_start(void) L4_NOTHROW
Start a thread control API sequence.
Definition thread.h:956
l4_thread_control_pager
void l4_thread_control_pager(l4_cap_idx_t pager) L4_NOTHROW
Set the pager.
Definition thread.h:962
L4_IPC_NEVER
#define L4_IPC_NEVER
never timeout
Definition __timeout.h:76
l4_utcb_mr
l4_msg_regs_t * l4_utcb_mr(void) L4_NOTHROW L4_PURE
Get the message-register block of a UTCB.
Definition utcb.h:358
l4_utcb_t
struct l4_utcb_t l4_utcb_t
Opaque type for the UTCB.
Definition utcb.h:56
l4_utcb
l4_utcb_t * l4_utcb(void) L4_NOTHROW L4_PURE
Get the UTCB address.
Definition utcb.h:346
l4_utcb_exc
l4_exc_regs_t * l4_utcb_exc(void) L4_NOTHROW L4_PURE
Get the message-register block of a UTCB (for an exception IPC).
Definition utcb.h:367
l4_utcb_exc_pc
l4_umword_t l4_utcb_exc_pc(l4_exc_regs_t const *u) L4_NOTHROW L4_PURE
Access function to get the program counter of the exception state.
Definition utcb.h:85
l4_touch_rw
void l4_touch_rw(const void *addr, unsigned size) L4_NOTHROW
Touch data areas to force mapping (read-write).
Definition util.h:105
l4_sleep
void l4_sleep(l4_uint32_t ms) L4_NOTHROW
Suspend thread for a period of ms milliseconds.
l4_tsc_to_ns
l4_uint64_t l4_tsc_to_ns(l4_cpu_time_t tsc)
Convert timestamp to ns value.
Definition rdtsc.h:205
l4_calibrate_tsc
l4_uint32_t l4_calibrate_tsc(l4_kernel_info_t const *kip)
Determine scalers for timestamp calculations.
Definition rdtsc.h:159
l4_rdtsc
l4_cpu_time_t l4_rdtsc(void)
Read current value of CPU-internal timestamp counter.
Definition rdtsc.h:165
kumem_alloc.h
Kumem allocator utility C interface.
l4re_util_kumem_alloc
L4_BEGIN_DECLS int l4re_util_kumem_alloc(l4_addr_t *mem, unsigned pages_order, l4_cap_idx_t task, l4_cap_idx_t rm) L4_NOTHROW
Allocate state area.
string.h
String.
l4_exc_regs_t
UTCB structure for exceptions.
Definition utcb.h:28
l4_exc_regs_t::trapno
l4_umword_t trapno
trap number
Definition utcb.h:65
l4_exc_regs_t::sp
l4_umword_t sp
stack pointer
Definition utcb.h:33
l4_exc_regs_t::ulr
l4_umword_t ulr
ulr
Definition utcb.h:34
l4_exc_regs_t::err
l4_umword_t err
error code
Definition utcb.h:30
l4_exc_regs_t::cpsr
l4_umword_t cpsr
cpsr
Definition utcb.h:37
l4_msgtag_t
Message tag data structure.
Definition types.h:154
l4_sched_param_t
Scheduler parameter set.
Definition scheduler.h:174
l4_msg_regs_t::mr
l4_umword_t mr[L4_UTCB_GENERIC_DATA_SIZE]
Message registers.
Definition utcb.h:69