X-Git-Url: https://rtime.felk.cvut.cz/gitweb/l4.git/blobdiff_plain/c02c23b58bcb65fea74d86d33bcc1b094ef97902..d1e11ef9d33b46388b8234795a9aacc92d1dbe23:/l4/pkg/plr/server/src/fault_handlers/kiptime.cc diff --git a/l4/pkg/plr/server/src/fault_handlers/kiptime.cc b/l4/pkg/plr/server/src/fault_handlers/kiptime.cc index b3fb284e7..cb7aef240 100644 --- a/l4/pkg/plr/server/src/fault_handlers/kiptime.cc +++ b/l4/pkg/plr/server/src/fault_handlers/kiptime.cc @@ -1,7 +1,9 @@ /* * kiptime.cc -- * - * (c) 2011 Björn Döbel , + * Intercept and emulate accesses to Fiasco's KIP->clock field. + * + * (c) 2011-2013 Björn Döbel , * 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. @@ -16,38 +18,26 @@ #include "observers.h" #include -#include +#include +#include +#include namespace Romain { class KipTimeObserver_priv : public KIPTimeObserver { private: std::vector _breakpoints; + unsigned _hitcount; - void read_target_list(char *list) + void configureBreakpoint(char *str) { - char *end = list + strlen(list); // end of list - char *c = list; // iterator - - while (c < end) { - char *c2 = c; - - /* find next separator or end char */ - while ((*c2 != ',') && (c2 < end)) ++c2; - - *c2 = 0; - - /* convert the address found */ - errno = 0; - l4_addr_t a = strtol(c, NULL, 16); // XXX check return - if (errno) { - ERROR() << "Conversion error."; - } else { - _breakpoints.push_back(new Breakpoint(a)); - } - - c = c2+1; - } + errno = 0; + l4_addr_t a = strtol(str, NULL, 16); // XXX check return + if (errno) { + ERROR() << "Conversion error: " << errno << std::hex << " (" << a << ")"; + } else { + _breakpoints.push_back(new Breakpoint(a)); + } } DECLARE_OBSERVER("kip time"); @@ -61,26 +51,46 @@ Romain::KIPTimeObserver* Romain::KIPTimeObserver::Create() } Romain::KipTimeObserver_priv::KipTimeObserver_priv() + : _hitcount(0) { - char *list = strdup(ConfigStringValue("kip-time:target", "none")); - if (list) { - read_target_list(list); + char *rtget = strdup(ConfigStringValue("kip-time:libc_backend_rt_clock_gettime", "")); + if (strlen(rtget) != 0) { + INFO() << "BP @ " << rtget; + configureBreakpoint(rtget); + } else { + ERROR() << "No set address for libc_backend_rt_clock_gettime()"; + //enter_kdebug("??"); } - free(list); + + char *monoget = strdup(ConfigStringValue("kip-time:mono_clock_gettime", "")); + if (strlen(monoget) != 0) { + INFO() << "BP @ " << monoget; + configureBreakpoint(monoget); + } else { + ERROR() << "No set address for mono_clock_gettime()"; + //enter_kdebug("??"); + } + + free(monoget); + free(rtget); + //enter_kdebug("kiptime"); } -void Romain::KipTimeObserver_priv::status() const { } +void Romain::KipTimeObserver_priv::status() const +{ + INFO() << "[time] gettime() calls: " << _hitcount; +} /***************************************************************** * Debugging stuff * *****************************************************************/ void Romain::KipTimeObserver_priv::startup_notify(Romain::App_instance *inst, Romain::App_thread *, - Romain::App_model *am) + Romain::Thread_group *, + Romain::App_model *am) { - for (std::vector::iterator i = _breakpoints.begin(); - i != _breakpoints.end(); ++i) { + for (auto i = _breakpoints.begin(); i != _breakpoints.end(); ++i) { DEBUG() << std::hex << (*i)->address(); (*i)->activate(inst, am); } @@ -89,20 +99,43 @@ void Romain::KipTimeObserver_priv::startup_notify(Romain::App_instance *inst, Romain::Observer::ObserverReturnVal Romain::KipTimeObserver_priv::notify(Romain::App_instance *i, Romain::App_thread *t, + Romain::Thread_group *, Romain::App_model *am) { if (!entry_reason_is_int3(t->vcpu(), i, am) && !entry_reason_is_int1(t->vcpu())) return Romain::Observer::Ignored; - for (std::vector::const_iterator it = _breakpoints.begin(); - it != _breakpoints.end(); ++it) { + for (auto it = _breakpoints.begin(); it != _breakpoints.end(); ++it) { if ((*it)->was_hit(t)) { - l4_cpu_time_t time = l4re_kip()->clock; + ++_hitcount; + DEBUG() << "BP @ " << std::hex << (*it)->address() << " was hit."; + DEBUG() << "stack ptr 0x" << std::hex << t->vcpu()->r()->sp; + + l4_addr_t stack = am->rm()->remote_to_local(t->vcpu()->r()->sp, i->id()); + l4_addr_t ret = *(l4_addr_t*)stack; + l4_addr_t specptr = *(l4_addr_t*)(stack + 1 * sizeof(l4_addr_t)); + l4_addr_t spec_local = am->rm()->remote_to_local(specptr, i->id()); + DEBUG() << "Retaddr " << std::hex << ret << ", ptr " << specptr; + + int rv = libc_backend_rt_clock_gettime((struct timespec*)(spec_local)); + t->vcpu()->r()->ax = rv; + + /* We wrote data directly into the replica's address space. Now + we need to make sure the other replicas see the same value. + */ + for (unsigned rep = 0; rep < Romain::_the_instance_manager->instance_count(); + ++rep) { + + if (rep == i->id()) + continue; + + l4_addr_t specptr_rep = am->rm()->remote_to_local(specptr, rep); + //INFO() << "memcpy " << std::hex << specptr_rep << " <- " << spec_local; + memcpy((void*)specptr_rep, (void*)spec_local, sizeof(struct timespec)); + } - t->vcpu()->r()->si = time & 0xFFFFFFFF; - t->vcpu()->r()->di = (time >> 32) & 0xFFFFFFFF; - t->vcpu()->r()->ip += 11; + t->return_to(ret); return Romain::Observer::Replicatable; }