static int mips_next_event(unsigned long delta,
				struct clock_event_device *evt)
{
	unsigned long flags;
	unsigned int mtflags;
	unsigned long timestamp, reference, previous;
	unsigned long nextcomp = 0L;
	int vpe = current_cpu_data.vpe_id;
	int cpu = smp_processor_id();
	local_irq_save(flags);
	mtflags = dmt();

	/*
	 * Maintain the per-TC virtual timer
	 * and program the per-VPE shared Count register
	 * as appropriate here...
	 */
	reference = (unsigned long)read_c0_count();
	timestamp = MAKEVALID(reference + delta);
	/*
	 * To really model the clock, we have to catch the case
	 * where the current next-in-VPE timestamp is the old
	 * timestamp for the calling CPE, but the new value is
	 * in fact later.  In that case, we have to do a full
	 * scan and discover the new next-in-VPE CPU id and
	 * timestamp.
	 */
	previous = smtc_nexttime[vpe][cpu];
	if (cpu == smtc_nextinvpe[vpe] && ISVALID(previous)
	    && IS_SOONER(previous, timestamp, reference)) {
		int i;
		int soonest = cpu;

		/*
		 * Update timestamp array here, so that new
		 * value gets considered along with those of
		 * other virtual CPUs on the VPE.
		 */
		smtc_nexttime[vpe][cpu] = timestamp;
		for_each_online_cpu(i) {
			if (ISVALID(smtc_nexttime[vpe][i])
			    && IS_SOONER(smtc_nexttime[vpe][i],
				smtc_nexttime[vpe][soonest], reference)) {
				    soonest = i;
			}
		}
		smtc_nextinvpe[vpe] = soonest;
		nextcomp = smtc_nexttime[vpe][soonest];
	/*
	 * Otherwise, we don't have to process the whole array rank,
	 * we just have to see if the event horizon has gotten closer.
	 */
	} else {
Exemplo n.º 2
0
int main(int argc, char *argv[])
  try {
    State state;
    auto parsers = new_subparser({"device"});
    argp argp = {options, init_parsers, nullptr, doc, parsers.get(), nullptr,
      nullptr};
    argp_parse(&argp, argc, argv, 0, nullptr, &state);

    Params params;

    try {
      params.load(state.device);
    } catch(const std::exception& e) {
      std::cerr << "Error: Header corrupt." << std::endl;
      return 1;
    }
    std::uint64_t blocks = state.device.size()/params.block_size;

    Pinentry pinentry;
    pinentry.SETDESC("Enter passphrases for a partition on this volume.");
    pinentry.SETPROMPT("Passphrase:");
    auto passphrase = pinentry.GETPIN();
    Superblock superblock(params, passphrase, blocks);
    try {
      superblock.load(state.device);
    } catch(...) {
      std::cerr << "Error: No partition found for that passphrase." << std::endl;
    }
    Hash hash(params.hash);
    std::string key = PBKDF2::PBKDF2(hash, passphrase, params.salt,
        params.iters, params.key_size);

    if (state.name.empty()) {
      hash.reset();
      hash.update(key);
      state.name = hex(hash.digest()).substr(8);
    }

    {
      std::unique_ptr<dm_task, void(*)(dm_task*)> dmt(
          dm_task_create(DM_DEVICE_CREATE), dm_task_destroy);
      if (!dmt.get())
        throw std::runtime_error("dm_task_create failed");
      if (!dm_task_set_name(dmt.get(), state.name.c_str()))
        throw std::runtime_error("dm_task_set_name failed");
      std::uint64_t offset = 0;
      for (auto block = superblock.blocks.begin()+superblock.offset;
          block != superblock.blocks.end();
          block++, offset += params.block_size) {
        if (*block != 0) {
          std::stringstream ss;
          ss << params.device_cipher << " " << hex(key) << " 0 ";
          ss << state.device.major() << ":" << state.device.minor() << " ";
          ss << (*block)*params.block_size/512;
          if (!dm_task_add_target(dmt.get(), offset/512, params.block_size/512,
                "crypt", ss.str().c_str()))
            throw std::runtime_error("dm_task_add_target(\"crypt\") failed");
        } else {
          if (!dm_task_add_target(dmt.get(), offset/512, params.block_size/512,
                "error", ""))
            throw std::runtime_error("dm_task_add_target(\"error\") failed");
        }
      }
      if (!dm_task_run(dmt.get()))
        throw std::runtime_error("dm_task_run failed");
    }

    return 0;
  } catch(const std::exception& e) {
    std::cerr << "Error: " << e.what() << std::endl;
    return 1;
  }