Re: [PATCH 2/4] kvm tools: Allow pausing guests

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I mixed up files, this patch misses:

	/* See if the guest is running */
	if (!kvm_cpus[i] || kvm_cpus[i]->thread == 0)
		return;

In the beginning of kvm__pause() and kvm__continue(). I'll send an
updated patch.

On Sun, 2011-05-29 at 20:32 +0300, Sasha Levin wrote:
> 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@xxxxxxxxx>
> ---
>  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);
> +}

-- 

Sasha.

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux