@@ -1203,7 +1203,11 @@ static int kvm_cmd_run_init(int argc, const char **argv)
* come after this (it may set up device trees etc.)
*/
- kvm__start_timer(kvm);
+ r = kvm_timer__init(kvm);
+ if (r < 0) {
+ pr_err("kvm_timer__init() failed with error %d\n", r);
+ goto fail;
+ }
if (kvm->cfg.firmware_filename) {
if (!kvm__load_firmware(kvm, kvm->cfg.firmware_filename))
@@ -1258,9 +1262,13 @@ static void kvm_cmd_run_exit(int guest_ret)
if (r < 0)
pr_warning("irq__exit() failed with error %d\n", r);
+ r = kvm_timer__exit(kvm);
+ if (r < 0)
+ pr_warning("kvm_timer__exit() failed with error %d\n", r);
+
r = fb__exit(kvm);
if (r < 0)
- pr_warning("fb__exit() failed with error %d\n", r);
+ pr_warning("kvm_timer__exit() failed with error %d\n", r);
r = virtio_scsi_exit(kvm);
if (r < 0)
@@ -68,8 +68,8 @@ int kvm__exit(struct kvm *kvm);
bool kvm__load_firmware(struct kvm *kvm, const char *firmware_filename);
bool kvm__load_kernel(struct kvm *kvm, const char *kernel_filename,
const char *initrd_filename, const char *kernel_cmdline, u16 vidmode);
-void kvm__start_timer(struct kvm *kvm);
-void kvm__stop_timer(struct kvm *kvm);
+int kvm_timer__init(struct kvm *kvm);
+int kvm_timer__exit(struct kvm *kvm);
void kvm__irq_line(struct kvm *kvm, int irq, int level);
void kvm__irq_trigger(struct kvm *kvm, int irq);
bool kvm__emulate_io(struct kvm *kvm, u16 port, void *data, int direction, int size, u32 count);
@@ -254,8 +254,6 @@ int kvm__enumerate_instances(int (*callback)(const char *name, int fd))
int kvm__exit(struct kvm *kvm)
{
- kvm__stop_timer(kvm);
-
kvm__arch_delete_ram(kvm);
kvm_ipc__stop();
kvm__remove_socket(kvm->cfg.guest_name);
@@ -478,10 +476,11 @@ found_kernel:
* userspace hypervisor into the guest at periodical intervals. Please note
* that clock interrupt, for example, is not handled here.
*/
-void kvm__start_timer(struct kvm *kvm)
+int kvm_timer__init(struct kvm *kvm)
{
struct itimerspec its;
struct sigevent sev;
+ int r;
memset(&sev, 0, sizeof(struct sigevent));
sev.sigev_value.sival_int = 0;
@@ -489,25 +488,33 @@ void kvm__start_timer(struct kvm *kvm)
sev.sigev_signo = SIGALRM;
sev._sigev_un._tid = syscall(__NR_gettid);
- if (timer_create(CLOCK_REALTIME, &sev, &kvm->timerid) < 0)
- die("timer_create()");
+ r = timer_create(CLOCK_REALTIME, &sev, &kvm->timerid);
+ if (r < 0)
+ return r;
its.it_value.tv_sec = TIMER_INTERVAL_NS / 1000000000;
its.it_value.tv_nsec = TIMER_INTERVAL_NS % 1000000000;
its.it_interval.tv_sec = its.it_value.tv_sec;
its.it_interval.tv_nsec = its.it_value.tv_nsec;
- if (timer_settime(kvm->timerid, 0, &its, NULL) < 0)
- die("timer_settime()");
+ r = timer_settime(kvm->timerid, 0, &its, NULL);
+ if (r < 0) {
+ timer_delete(kvm->timerid);
+ return r;
+ }
+
+ return 0;
}
-void kvm__stop_timer(struct kvm *kvm)
+int kvm_timer__exit(struct kvm *kvm)
{
if (kvm->timerid)
if (timer_delete(kvm->timerid) < 0)
die("timer_delete()");
kvm->timerid = 0;
+
+ return 0;
}
void kvm__dump_mem(struct kvm *kvm, unsigned long addr, unsigned long size)
Make the timer init/exit follow the rest of the code, and move it out of builtin-run. Signed-off-by: Sasha Levin <levinsasha928@gmail.com> --- tools/kvm/builtin-run.c | 12 ++++++++++-- tools/kvm/include/kvm/kvm.h | 4 ++-- tools/kvm/kvm.c | 23 +++++++++++++++-------- 3 files changed, 27 insertions(+), 12 deletions(-)