/* Yield until that host time is reached */
host_time = v3_get_host_time(time_state);
+
while (host_time < target_host_time) {
v3_yield(info);
host_time = v3_get_host_time(time_state);
time_state->guest_host_offset = (sint64_t)guest_time - (sint64_t)host_time;
}
+
return 0;
}
* ra/c/dx here since they're modified by this instruction anyway. */
info->vm_regs.rcx = TSC_AUX_MSR;
ret = v3_handle_msr_read(info);
- if (ret) return ret;
+
+ if (ret != 0) {
+ return ret;
+ }
+
info->vm_regs.rcx = info->vm_regs.rax;
/* Now do the TSC half of the instruction */
ret = v3_rdtsc(info);
- if (ret) return ret;
-
+
+ if (ret != 0) {
+ return ret;
+ }
+
return 0;
}
struct vm_time * time_state = &(info->time_state);
V3_ASSERT(msr_num == TSC_AUX_MSR);
+
msr_val->lo = time_state->tsc_aux.lo;
msr_val->hi = time_state->tsc_aux.hi;
struct vm_time * time_state = &(info->time_state);
V3_ASSERT(msr_num == TSC_AUX_MSR);
+
time_state->tsc_aux.lo = msr_val.lo;
time_state->tsc_aux.hi = msr_val.hi;
uint64_t time = v3_get_guest_tsc(&info->time_state);
V3_ASSERT(msr_num == TSC_MSR);
+
msr_val->hi = time >> 32;
msr_val->lo = time & 0xffffffffLL;
struct v3_msr msr_val, void *priv) {
struct vm_time * time_state = &(info->time_state);
uint64_t guest_time, new_tsc;
+
V3_ASSERT(msr_num == TSC_MSR);
+
new_tsc = (((uint64_t)msr_val.hi) << 32) | (uint64_t)msr_val.lo;
guest_time = v3_get_guest_time(time_state);
time_state->tsc_guest_offset = (sint64_t)new_tsc - (sint64_t)guest_time;
}
-static int init_vm_time(struct v3_vm_info *vm_info) {
+int v3_init_time_vm(struct v3_vm_info * vm) {
int ret;
PrintDebug("Installing TSC MSR hook.\n");
- ret = v3_hook_msr(vm_info, TSC_MSR,
+ ret = v3_hook_msr(vm, TSC_MSR,
tsc_msr_read_hook, tsc_msr_write_hook, NULL);
+ if (ret != 0) {
+ return ret;
+ }
+
PrintDebug("Installing TSC_AUX MSR hook.\n");
- if (ret) return ret;
- ret = v3_hook_msr(vm_info, TSC_AUX_MSR, tsc_aux_msr_read_hook,
+ ret = v3_hook_msr(vm, TSC_AUX_MSR, tsc_aux_msr_read_hook,
tsc_aux_msr_write_hook, NULL);
- if (ret) return ret;
+
+ if (ret != 0) {
+ return ret;
+ }
PrintDebug("Registering TIME_CPUFREQ hypercall.\n");
- ret = v3_register_hypercall(vm_info, TIME_CPUFREQ_HCALL,
+ ret = v3_register_hypercall(vm, TIME_CPUFREQ_HCALL,
handle_cpufreq_hcall, NULL);
+
return ret;
}
-void v3_init_time(struct guest_info * info) {
+void v3_deinit_time_vm(struct v3_vm_info * vm) {
+ v3_unhook_msr(vm, TSC_MSR);
+ v3_unhook_msr(vm, TSC_AUX_MSR);
+
+ v3_remove_hypercall(vm, TIME_CPUFREQ_HCALL);
+}
+
+void v3_init_time_core(struct guest_info * info) {
struct vm_time * time_state = &(info->time_state);
v3_cfg_tree_t * cfg_tree = info->core_cfg_data;
- static int one_time = 0;
- char *khz;
+ char * khz = NULL;
time_state->host_cpu_freq = V3_CPU_KHZ();
khz = v3_cfg_val(cfg_tree, "khz");
+
if (khz) {
time_state->guest_cpu_freq = atoi(khz);
PrintDebug("Core %d CPU frequency requested at %d khz.\n",
info->cpu_id, time_state->guest_cpu_freq);
}
- if (!khz || time_state->guest_cpu_freq > time_state->host_cpu_freq) {
+ if ((khz == NULL) || (time_state->guest_cpu_freq > time_state->host_cpu_freq)) {
time_state->guest_cpu_freq = time_state->host_cpu_freq;
}
- PrintDebug("Core %d CPU frequency set to %d KHz (host CPU frequency = %d KHz).\n", info->cpu_id, time_state->guest_cpu_freq, time_state->host_cpu_freq);
+
+ PrintDebug("Core %d CPU frequency set to %d KHz (host CPU frequency = %d KHz).\n",
+ info->cpu_id,
+ time_state->guest_cpu_freq,
+ time_state->host_cpu_freq);
time_state->initial_time = 0;
time_state->last_update = 0;
time_state->tsc_aux.lo = 0;
time_state->tsc_aux.hi = 0;
- if (!one_time) {
- init_vm_time(info->vm_info);
- one_time = 1;
- }
+
}
+void v3_deinit_time_core(struct guest_info * core) {
+ struct vm_time * time_state = &(core->time_state);
+ struct v3_timer * tmr = NULL;
+ struct v3_timer * tmp = NULL;
+ list_for_each_entry_safe(tmr, tmp, &(time_state->timers), timer_link) {
+ v3_remove_timer(core, tmr);
+ }
+
+}