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 {
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; }