Exemplo n.º 1
0
L4_msg_tag
Ipc_gate_ctl::bind_thread(L4_obj_ref, L4_fpage::Rights,
                          Syscall_frame *f, Utcb const *in, Utcb *)
{
  L4_msg_tag tag = f->tag();

  if (tag.words() < 2)
    return commit_result(-L4_err::EMsgtooshort);

  L4_fpage::Rights t_rights(0);
  Thread *t = Ko::deref<Thread>(&tag, in, &t_rights);
  if (!t)
    return tag;

  if (!(t_rights & L4_fpage::Rights::CS()))
    return commit_result(-L4_err::EPerm);

  Ipc_gate_obj *g = static_cast<Ipc_gate_obj*>(this);
  g->_id = in->values[1];
  Mem::mp_wmb();
  t->inc_ref();
  g->_thread = t;
  Mem::mp_wmb();
  g->unblock_all();
  current()->rcu_wait();
  g->unblock_all();

  return commit_result(0);
}
Exemplo n.º 2
0
PUBLIC
L4_msg_tag
Irq_muxer::kinvoke(L4_obj_ref, L4_fpage::Rights /*rights*/, Syscall_frame *f,
                   Utcb const *utcb, Utcb *)
{
  register Context *const c_thread = ::current();
  assert_opt (c_thread);
  register Space *const c_space = c_thread->space();
  assert_opt (c_space);

  L4_msg_tag tag = f->tag();

  if (EXPECT_FALSE(tag.proto() != L4_msg_tag::Label_irq))
    return commit_result(-L4_err::EBadproto);

  if (EXPECT_FALSE(tag.words() < 1))
    return commit_result(-L4_err::EInval);

  switch ((utcb->values[0] & 0xffff))
    {
    case Op_chain:
      return sys_attach(tag, utcb, f, c_space);
    case Op_trigger:
      log();
      hit(0);
      return no_reply();
    default:
      return commit_result(-L4_err::EInval);
    }
}
Exemplo n.º 3
0
PRIVATE inline NOEXPORT
L4_msg_tag
Vlog::get_attr(Mword, Syscall_frame *, Utcb *u)
{
  if (!have_receive(u))
    return commit_result(0);

  u->values[1] = _i_flags;
  u->values[2] = _o_flags;
  u->values[3] = _l_flags;
  return commit_result(0, 4);
}
Exemplo n.º 4
0
PUBLIC
L4_msg_tag
Vlog::icu_bind_irq(Irq *irq_o, unsigned irqnum)
{
  if (irqnum > 0)
    return commit_result(-L4_err::EInval);

  if (_irq)
    _irq->unbind();

  bind(irq_o, irqnum);
  return commit_result(0);
}
Exemplo n.º 5
0
L4_msg_tag
Icu::op_icu_bind(unsigned irqnum, Ko::Cap<Irq> const &irq)
{
  if (!Ko::check_rights(irq.rights, Ko::Rights::CW()))
    return commit_result(-L4_err::EPerm);

  auto g = lock_guard(irq.obj->irq_lock());
  irq.obj->unbind();

  if (!Irq_mgr::mgr->alloc(irq.obj, irqnum))
    return commit_result(-L4_err::EPerm);

  return commit_result(0);
}
Exemplo n.º 6
0
PUBLIC
L4_msg_tag
Vlog::kinvoke(L4_obj_ref ref, Mword rights, Syscall_frame *f,
              Utcb const *r_msg, Utcb *s_msg)
{
  L4_msg_tag const t = f->tag();

  if (t.proto() == L4_msg_tag::Label_irq)
    return Icu_h<Vlog>::icu_invoke(ref, rights, f, r_msg, s_msg);
  else if (t.proto() != L4_msg_tag::Label_log)
    return commit_result(-L4_err::EBadproto);

  switch (r_msg->values[0])
    {
    case 0:
      log_string(f, r_msg);
      return no_reply();

    case 2: // set attr
      return set_attr(rights, f, r_msg);

    case 3: // get attr
      return get_attr(rights, f, s_msg);

    default:
      return get_input(rights, f, s_msg);
    }
}
Exemplo n.º 7
0
PRIVATE inline NOEXPORT
L4_msg_tag
Ipc_gate_ctl::get_infos(L4_obj_ref, L4_fpage::Rights,
                        Syscall_frame *, Utcb const *, Utcb *out)
{
  Ipc_gate_obj *g = static_cast<Ipc_gate_obj*>(this);
  out->values[0] = g->_id;
  return commit_result(0, 1);
}
Exemplo n.º 8
0
L4_msg_tag
Icu::op_icu_set_mode(Mword pin, Irq_chip::Mode mode)
{
  Irq_mgr::Irq i = Irq_mgr::mgr->chip(pin);

  if (!i.chip)
    return commit_result(-L4_err::ENodev);

  int r = i.chip->set_mode(i.pin, mode);

  Irq_base *irq = i.chip->irq(i.pin);
  if (irq)
    {
      auto g = lock_guard(irq->irq_lock());
      if (irq->chip() == i.chip && irq->pin() == i.pin)
        irq->switch_mode(i.chip->is_edge_triggered(i.pin));
    }

  return commit_result(r);
}
Exemplo n.º 9
0
PRIVATE
L4_msg_tag
Irq_muxer::sys_attach(L4_msg_tag const &tag, Utcb const *utcb, Syscall_frame * /*f*/,
                Obj_space *o_space)
{
  L4_snd_item_iter snd_items(utcb, tag.words());

  Irq *irq = 0;

  if (tag.items() == 0)
    return commit_result(-L4_err::EInval);

  if (tag.items() && snd_items.next())
    {
      L4_fpage bind_irq(snd_items.get()->d);
      if (EXPECT_FALSE(!bind_irq.is_objpage()))
	return commit_error(utcb, L4_error::Overflow);

      irq = Kobject::dcast<Irq*>(o_space->lookup_local(bind_irq.obj_index()));
    }

  if (!irq)
    return commit_result(-L4_err::EInval);

  irq->unbind();

  if (!irq->masked())
    {
      Smword old;
      do
	old = _mask_cnt;
      while (!mp_cas(&_mask_cnt, old, old + 1));
    }

  bind(irq, 0);

  irq->Irq_base::_next = Irq_base::_next;
  Irq_base::_next = irq;

  return commit_result(0);
}
Exemplo n.º 10
0
PRIVATE
L4_msg_tag
Irq_sender::sys_attach(L4_msg_tag const &tag, Utcb const *utcb, Syscall_frame * /*f*/,
                Obj_space *o_space)
{
  L4_snd_item_iter snd_items(utcb, tag.words());

  Thread *thread = 0;

  if (tag.items() == 0)
    {
      // detach
      Reap_list rl;
      free(_irq_thread, rl.list());
      _irq_id = ~0UL;
      cpu_lock.clear();
      rl.del();
      cpu_lock.lock();
      return commit_result(0);
    }

  if (tag.items() && snd_items.next())
    {
      L4_fpage bind_thread(snd_items.get()->d);
      if (EXPECT_FALSE(!bind_thread.is_objpage()))
	return commit_error(utcb, L4_error::Overflow);

      thread = Kobject::dcast<Thread_object*>(o_space->lookup_local(bind_thread.obj_index()));
    }

  if (!thread)
    thread = current_thread();

  if (alloc(thread))
    {
      _irq_id = utcb->values[1];
      return commit_result(0);
    }

  return commit_result(-L4_err::EInval);
}
Exemplo n.º 11
0
PRIVATE inline NOEXPORT
L4_msg_tag
Vlog::get_input(Mword rights, Syscall_frame *f, Utcb *u)
{
  (void)f;

  if (!have_receive(u))
    return commit_result(0);

  if (!(rights & L4_fpage::X))
    return commit_result(-L4_err::EPerm);

  char *buffer = reinterpret_cast<char *>(&u->values[1]);
  long cnt_down = u->values[0] >> 16;
  int i = 0;
  while (cnt_down && (i = Vkey::get()) != -1)
    {
      Vkey::clear();

      if (_i_flags & F_INLCR && i == '\n')
	i = '\r';

      if (_i_flags & F_IGNCR && i == '\r')
	continue;

      if (_i_flags & F_ICRNL && i == '\r')
	i = '\n';

      *buffer = i;
      ++buffer;
      --cnt_down;
    }

  u->values[0] = buffer - reinterpret_cast<char *>(&u->values[1]);
  if (i == -1)
    u->values[0] |= 1UL<<31;
  return commit_result(0);
}
Exemplo n.º 12
0
PUBLIC
L4_msg_tag
Ipc_gate_ctl::kinvoke(L4_obj_ref self, L4_fpage::Rights rights,
                      Syscall_frame *f, Utcb const *in, Utcb *out)
{
  L4_msg_tag tag = f->tag();

  if (EXPECT_FALSE(tag.proto() != L4_msg_tag::Label_kobject))
    return commit_result(-L4_err::EBadproto);

  if (EXPECT_FALSE(tag.words() < 1))
    return commit_result(-L4_err::EInval);

  switch (in->values[0])
    {
    case Op_bind:
      return bind_thread(self, rights, f, in, out);
    case Op_get_info:
      return get_infos(self, rights, f, in, out);
    default:
      return static_cast<Ipc_gate_obj*>(this)->kobject_invoke(self, rights, f, in, out);
    }
}
Exemplo n.º 13
0
PRIVATE inline NOEXPORT
L4_msg_tag
Vlog::set_attr(Mword, Syscall_frame const *, Utcb const *u)
{
  _i_flags = u->values[1];
  _o_flags = u->values[2] | F_ONLCR;
  _l_flags = u->values[3];
  Vkey::set_echo((!(_l_flags & F_ECHO))
                  ? Vkey::Echo_off
                  : (_o_flags & F_OCRNL
                    ? Vkey::Echo_crnl
                    : Vkey::Echo_on));

  return commit_result(0);
}
Exemplo n.º 14
0
IMPLEMENTATION [ia32 || amd64]:

#include "gdt.h"
#include "std_macros.h"
#include "x86desc.h"

PRIVATE inline NEEDS["gdt.h"]
bool
Task::invoke_arch(L4_msg_tag &tag, Utcb *utcb)
{
  switch (utcb->values[0])
    {
    case Ldt_set_x86:
        {
          enum
          {
            Utcb_values_per_ldt_entry
              = Cpu::Ldt_entry_size / sizeof(utcb->values[0]),
          };
          if (EXPECT_FALSE(tag.words() < 3
                           || tag.words() % Utcb_values_per_ldt_entry))
            {
              tag = commit_result(-L4_err::EInval);
              return true;
            }

          unsigned entry_number  = utcb->values[1];
          unsigned size          = (tag.words() - 2) * sizeof(utcb->values[0]);

          // Allocate the memory if not yet done
          if (!_ldt.addr())
            _ldt.alloc();

          if (entry_number * Cpu::Ldt_entry_size + size > Config::PAGE_SIZE)
            {
              WARN("set_ldt: LDT size exceeds one page, not supported.");
              tag = commit_result(-L4_err::EInval);
              return true;
            }

          _ldt.size(size + Cpu::Ldt_entry_size * entry_number);

          Address desc_addr = reinterpret_cast<Address>(&utcb->values[2]);
          Gdt_entry desc;
          Gdt_entry *ldtp
            = reinterpret_cast<Gdt_entry *>(_ldt.addr()) + entry_number;

          while (size >= Cpu::Ldt_entry_size)
            {
              desc = *reinterpret_cast<Gdt_entry const *>(desc_addr);
              if (desc.unsafe())
                {
                  WARN("set_ldt: Bad descriptor.");
                  tag = commit_result(-L4_err::EInval);
                  return true;
                }

              *ldtp      = desc;
              size      -= Cpu::Ldt_entry_size;
              desc_addr += Cpu::Ldt_entry_size;
              ldtp++;
            }

          if (this == current()->space())
            Cpu::cpus.cpu(current_cpu()).enable_ldt(_ldt.addr(), _ldt.size());

          tag = commit_result(0);
        }
      return true;
    }




  return false;
}
Exemplo n.º 15
0
PRIVATE inline
L4_msg_tag
Thread_object::sys_vcpu_resume(L4_msg_tag const &tag, Utcb *utcb)
{
  if (this != current() || !(state() & Thread_vcpu_enabled))
    return commit_result(-L4_err::EInval);

  Space *s = space();
  Vcpu_state *vcpu = vcpu_state().access(true);

  L4_obj_ref user_task = vcpu->user_task;
  if (user_task.valid())
    {
      L4_fpage::Rights task_rights = L4_fpage::Rights(0);
      Task *task = Kobject::dcast<Task*>(s->lookup_local(user_task.cap(),
                                                         &task_rights));

      if (EXPECT_FALSE(task && !(task_rights & L4_fpage::Rights::W())))
        return commit_result(-L4_err::EPerm);

      if (task != vcpu_user_space())
        vcpu_set_user_space(task);

      vcpu->user_task = L4_obj_ref();
    }
  else if (user_task.op() == L4_obj_ref::Ipc_reply)
    vcpu_set_user_space(0);

  L4_snd_item_iter snd_items(utcb, tag.words());
  int items = tag.items();
  if (vcpu_user_space())
    for (; items && snd_items.more(); --items)
      {
        if (EXPECT_FALSE(!snd_items.next()))
          break;

        Lock_guard<Lock> guard;
        if (!guard.check_and_lock(&static_cast<Task *>(vcpu_user_space())->existence_lock))
          return commit_result(-L4_err::ENoent);

        cpu_lock.clear();

        L4_snd_item_iter::Item const *const item = snd_items.get();
        L4_fpage sfp(item->d);

        Reap_list rl;
        L4_error err = fpage_map(space(), sfp,
                                 vcpu_user_space(), L4_fpage::all_spaces(),
                                 item->b, &rl);
        rl.del();

        cpu_lock.lock();

        if (EXPECT_FALSE(!err.ok()))
          return commit_error(utcb, err);
      }

  if ((vcpu->_saved_state & Vcpu_state::F_irqs)
      && (vcpu->sticky_flags & Vcpu_state::Sf_irq_pending))
    {
      assert_kdb(cpu_lock.test());
      do_ipc(L4_msg_tag(), 0, 0, true, 0,
	     L4_timeout_pair(L4_timeout::Zero, L4_timeout::Zero),
	     &vcpu->_ipc_regs, L4_fpage::Rights::FULL());

      vcpu = vcpu_state().access(true);

      if (EXPECT_TRUE(!vcpu->_ipc_regs.tag().has_error()
	              || this->utcb().access(true)->error.error() == L4_error::R_timeout))
	{
	  vcpu->_ts.set_ipc_upcall();

	  Address sp;

	  // tried to resume to user mode, so an IRQ enters from user mode
	  if (vcpu->_saved_state & Vcpu_state::F_user_mode)
            sp = vcpu->_entry_sp;
	  else
            sp = vcpu->_ts.sp();

          arch_load_vcpu_kern_state(vcpu, true);

	  LOG_TRACE("VCPU events", "vcpu", this, Vcpu_log,
	      l->type = 4;
	      l->state = vcpu->state;
	      l->ip = vcpu->_entry_ip;
	      l->sp = sp;
	      l->space = static_cast<Task*>(_space.vcpu_aware())->dbg_id();
	      );
Exemplo n.º 16
0
int main (int argc, char **argv) {
    git_index *index = NULL;
    pthread_t updateThread, hashThread;
    int rc, difficulty;
    void *status;
    hash_args args;
    timing_info timing;
    git_oid curr_commit;

    reset_timing(&timing);

    pthread_mutex_init(&commit_mutex, NULL);
    pthread_mutex_init(&update_mutex, NULL);
    push_commit = NULL;

    difficulty = init_args(&args);
    init_git(&index);

    init_hasher(difficulty);

    check_updates();
    reset_hard();

    puts("Starting update thread");
    rc = pthread_create(&updateThread, NULL, check_updates_worker, NULL);
    if (rc){
        printf("ERROR creating update thread %d\n", rc);
        exit(-1);
    }

    signal (SIGINT, int_handler);

    while(!stop){
        start_timing(&timing);

        args.found = 0;

        time_point(&timing);

        pthread_mutex_lock(&commit_mutex);
        pthread_mutex_lock(&update_mutex);
        if(updated){
            reset_hard();
            updated = 0;
            push_commit = NULL;
        }
        pthread_mutex_unlock(&update_mutex);
        pthread_mutex_unlock(&commit_mutex);

        time_point(&timing);

        puts("Preparing index");
        prepare_index(index, args.msg);
        time_point(&timing);

        puts("Starting brute force thread");
        rc = pthread_create(&hashThread, NULL, force_hash, &args);

        time_point(&timing);

        if (rc){
            printf("ERROR creating hash thread %d\n", rc);
            stop = 1;
        } else {
            pthread_join(hashThread, &status);
        }

        time_point(&timing);

        if(!stop && !updated && args.found){
            puts("Found one!");

            while(push_commit){
                usleep(10);
            }

            time_point(&timing);

            if(!stop && !updated){
                pthread_mutex_lock(&commit_mutex);

                commit_result(args.msg, &curr_commit);
                push_commit = &curr_commit;

                pthread_mutex_unlock(&commit_mutex);
            }
        } else {
            puts("Reset while looking for a hash");
            time_point(&timing);
        }

        time_point(&timing);
        print_timing(&timing);
    }

    pthread_join(updateThread, &status);

    free_hasher();
    free(args.msg);

    git_index_free(index);
    git_repository_free(repo);

    git_threads_shutdown();

    return 0;
}
Exemplo n.º 17
0
PRIVATE inline
bool
Task::invoke_arch(L4_msg_tag &tag, Utcb *utcb)
{

  switch (utcb->values[0])
    {
    case Ldt_set_x86:
        {
          enum
          {
            Utcb_values_per_ldt_entry
              = Cpu::Ldt_entry_size / sizeof(utcb->values[0]),
          };
          if (EXPECT_FALSE(tag.words() < 3
                           || tag.words() % Utcb_values_per_ldt_entry))
            {
              tag = commit_result(-L4_err::EInval);
              return true;
            }

          unsigned entry_number  = utcb->values[1];
          unsigned idx           = 2;
          Mword *trampoline_page = (Mword *)Kmem::kernel_trampoline_page;

          for (; idx < tag.words()
              ; idx += Utcb_values_per_ldt_entry,
              ++entry_number)
            {
              Gdt_entry *d = (Gdt_entry *)&utcb->values[idx];
              if (!d->limit())
                continue;

              Ldt_user_desc info;
              info.entry_number    = entry_number;
              info.base_addr       =  d->base();
              info.limit           =  d->limit();
              info.seg_32bit       =  d->seg32();
              info.contents        =  d->contents();
              info.read_exec_only  = !d->writable();
              info.limit_in_pages  =  d->granularity();
              info.seg_not_present = !d->present();
              info.useable         =  d->avl();


              // Set up data on trampoline
              for (unsigned i = 0; i < sizeof(info) / sizeof(Mword); i++)
                *(trampoline_page + i + 1) = *(((Mword *)&info) + i);

              // Call modify_ldt for given user process
              Trampoline::syscall(pid(), __NR_modify_ldt,
                                  1, // write LDT
                                  Mem_layout::Trampoline_page + sizeof(Mword),
                                  sizeof(info));

              // Also set this for the fiasco kernel so that
              // segment registers can be set, this is necessary for signal
              // handling, esp. for sigreturn to work in the Fiasco kernel
              // with the context of the client (gs/fs values).
              if (*(trampoline_page + 1))
                Emulation::modify_ldt(*(trampoline_page + 1), // entry
                                      0,                      // base
                                      1);                     // size
            }
        }
      return true;
    }

  return false;
}
Exemplo n.º 18
0
L4_msg_tag
Icu::op_icu_msi_info(Mword msi, Unsigned64 source, Irq_mgr::Msi_info *out)
{
  return commit_result(Irq_mgr::mgr->msg(msi, source, out));
}