From: Sasha Levin <levinsasha928@gmail.com>
To: penberg@kernel.org
Cc: avi@redhat.com, kvm@vger.kernel.org, mingo@elte.hu,
asias.hejun@gmail.com, gorcunov@gmail.com,
prasadjoshi124@gmail.com, Sasha Levin <levinsasha928@gmail.com>
Subject: [PATCH 2/4] kvm tools: Allow pausing guests
Date: Sun, 29 May 2011 20:32:26 +0300 [thread overview]
Message-ID: <1306690348-23260-2-git-send-email-levinsasha928@gmail.com> (raw)
In-Reply-To: <1306690348-23260-1-git-send-email-levinsasha928@gmail.com>
Allow pausing and unpausing guests running on the host.
Pausing a guest means that none of the VCPU threads are running
KVM_RUN until they are unpaused.
Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
tools/kvm/include/kvm/kvm-cpu.h | 1 +
tools/kvm/include/kvm/kvm.h | 4 +++
tools/kvm/kvm-cpu.c | 18 +++++++++++----
tools/kvm/kvm-run.c | 4 +-
tools/kvm/kvm.c | 45 +++++++++++++++++++++++++++++++++++++++
5 files changed, 65 insertions(+), 7 deletions(-)
diff --git a/tools/kvm/include/kvm/kvm-cpu.h b/tools/kvm/include/kvm/kvm-cpu.h
index b2b6fce..4d99246 100644
--- a/tools/kvm/include/kvm/kvm-cpu.h
+++ b/tools/kvm/include/kvm/kvm-cpu.h
@@ -23,6 +23,7 @@ struct kvm_cpu {
struct kvm_msrs *msrs; /* dynamically allocated */
u8 is_running;
+ u8 paused;
};
struct kvm_cpu *kvm_cpu__init(struct kvm *kvm, unsigned long cpu_id);
diff --git a/tools/kvm/include/kvm/kvm.h b/tools/kvm/include/kvm/kvm.h
index 6a17362..d22a849 100644
--- a/tools/kvm/include/kvm/kvm.h
+++ b/tools/kvm/include/kvm/kvm.h
@@ -12,6 +12,7 @@
#define KVM_32BIT_GAP_START ((1ULL << 32) - KVM_32BIT_GAP_SIZE)
#define SIGKVMEXIT (SIGRTMIN + 0)
+#define SIGKVMPAUSE (SIGRTMIN + 1)
struct kvm {
int sys_fd; /* For system ioctls(), i.e. /dev/kvm */
@@ -50,6 +51,9 @@ bool kvm__emulate_io(struct kvm *kvm, u16 port, void *data, int direction, int s
bool kvm__emulate_mmio(struct kvm *kvm, u64 phys_addr, u8 *data, u32 len, u8 is_write);
bool kvm__register_mmio(u64 phys_addr, u64 phys_addr_len, void (*kvm_mmio_callback_fn)(u64 addr, u8 *data, u32 len, u8 is_write));
bool kvm__deregister_mmio(u64 phys_addr);
+void kvm__pause(void);
+void kvm__continue(void);
+void kvm__notify_paused(void);
/*
* Debugging
diff --git a/tools/kvm/kvm-cpu.c b/tools/kvm/kvm-cpu.c
index de0591f..81f479f 100644
--- a/tools/kvm/kvm-cpu.c
+++ b/tools/kvm/kvm-cpu.c
@@ -383,11 +383,15 @@ void kvm_cpu__run(struct kvm_cpu *vcpu)
die_perror("KVM_RUN failed");
}
-static void kvm_cpu_exit_handler(int signum)
+static void kvm_cpu_signal_handler(int signum)
{
- if (current_kvm_cpu->is_running) {
- current_kvm_cpu->is_running = false;
- pthread_kill(pthread_self(), SIGKVMEXIT);
+ if (signum == SIGKVMEXIT) {
+ if (current_kvm_cpu->is_running) {
+ current_kvm_cpu->is_running = false;
+ pthread_kill(pthread_self(), SIGKVMEXIT);
+ }
+ } else if (signum == SIGKVMPAUSE) {
+ current_kvm_cpu->paused = 1;
}
}
@@ -400,12 +404,16 @@ int kvm_cpu__start(struct kvm_cpu *cpu)
pthread_sigmask(SIG_BLOCK, &sigset, NULL);
- signal(SIGKVMEXIT, kvm_cpu_exit_handler);
+ signal(SIGKVMEXIT, kvm_cpu_signal_handler);
+ signal(SIGKVMPAUSE, kvm_cpu_signal_handler);
kvm_cpu__setup_cpuid(cpu);
kvm_cpu__reset_vcpu(cpu);
for (;;) {
+ if (cpu->paused)
+ kvm__notify_paused();
+
kvm_cpu__run(cpu);
switch (cpu->kvm_run->exit_reason) {
diff --git a/tools/kvm/kvm-run.c b/tools/kvm/kvm-run.c
index 48b8e70..761ac0d 100644
--- a/tools/kvm/kvm-run.c
+++ b/tools/kvm/kvm-run.c
@@ -47,8 +47,8 @@
#define MIN_RAM_SIZE_MB (64ULL)
#define MIN_RAM_SIZE_BYTE (MIN_RAM_SIZE_MB << MB_SHIFT)
-static struct kvm *kvm;
-static struct kvm_cpu *kvm_cpus[KVM_NR_CPUS];
+struct kvm *kvm;
+struct kvm_cpu *kvm_cpus[KVM_NR_CPUS];
__thread struct kvm_cpu *current_kvm_cpu;
static u64 ram_size;
diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
index 1d756e0..1e22566 100644
--- a/tools/kvm/kvm.c
+++ b/tools/kvm/kvm.c
@@ -6,6 +6,8 @@
#include "kvm/interrupt.h"
#include "kvm/mptable.h"
#include "kvm/util.h"
+#include "kvm/mutex.h"
+#include "kvm/kvm-cpu.h"
#include <linux/kvm.h>
@@ -25,6 +27,7 @@
#include <stdio.h>
#include <fcntl.h>
#include <time.h>
+#include <sys/eventfd.h>
#define DEFINE_KVM_EXIT_REASON(reason) [reason] = #reason
@@ -68,6 +71,10 @@ struct {
{ DEFINE_KVM_EXT(KVM_CAP_EXT_CPUID) },
};
+extern struct kvm_cpu *kvm_cpus[KVM_NR_CPUS];
+static int pause_event;
+static DEFINE_MUTEX(pause_lock);
+
static bool kvm__supports_extension(struct kvm *kvm, unsigned int extension)
{
int ret;
@@ -575,3 +582,41 @@ void kvm__dump_mem(struct kvm *kvm, unsigned long addr, unsigned long size)
p[n + 4], p[n + 5], p[n + 6], p[n + 7]);
}
}
+
+void kvm__pause(void)
+{
+ int i, paused_vcpus = 0;
+
+ mutex_lock(&pause_lock);
+
+ pause_event = eventfd(0, 0);
+ if (pause_event < 0)
+ die("Failed creating pause notification event");
+ for (i = 0; i < kvm.nrcpus; i++)
+ pthread_kill(kvm_cpus[i]->thread, SIGKVMPAUSE);
+
+ while (paused_vcpus < kvm.nrcpus) {
+ u64 cur_read;
+
+ if (read(pause_event, &cur_read, sizeof(cur_read)) < 0)
+ die("Failed reading pause event");
+ paused_vcpus += cur_read;
+ }
+ close(pause_event);
+}
+
+void kvm__continue(void)
+{
+ mutex_unlock(&pause_lock);
+}
+
+void kvm__notify_paused(void)
+{
+ u64 p = 1;
+
+ if (write(pause_event, &p, sizeof(p)) < 0)
+ die("Failed notifying of paused VCPU.");
+
+ mutex_lock(&pause_lock);
+ mutex_unlock(&pause_lock);
+}
--
1.7.5.rc3
next prev parent reply other threads:[~2011-05-29 17:33 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-05-29 17:32 [PATCH 1/4] kvm tools: Use correct value for user signal base Sasha Levin
2011-05-29 17:32 ` Sasha Levin [this message]
2011-05-29 17:56 ` [PATCH 2/4] kvm tools: Allow pausing guests Sasha Levin
2011-05-29 17:32 ` [PATCH 3/4] kvm tools: Add a brlock Sasha Levin
2011-05-29 18:47 ` Ingo Molnar
2011-05-29 19:30 ` Sasha Levin
2011-05-29 19:38 ` Ingo Molnar
2011-05-29 17:32 ` [PATCH 4/4] kvm tools: Use brlock in MMIO and IOPORT Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1306690348-23260-2-git-send-email-levinsasha928@gmail.com \
--to=levinsasha928@gmail.com \
--cc=asias.hejun@gmail.com \
--cc=avi@redhat.com \
--cc=gorcunov@gmail.com \
--cc=kvm@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=penberg@kernel.org \
--cc=prasadjoshi124@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox