public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
To: Leonard Norrgard
	<leonard.norrgard-g2GXA8XeJSExHbG02/KK1g@public.gmane.org>
Cc: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
Subject: Re: patch for review: kvm: implement guest rebooting
Date: Mon, 22 Jan 2007 12:09:51 +0200	[thread overview]
Message-ID: <45B48D6F.1050307@qumranet.com> (raw)
In-Reply-To: <45B456E9.3000709-g2GXA8XeJSExHbG02/KK1g@public.gmane.org>

Leonard Norrgard wrote:
> I've been looking at the guest reboot problem, which currently reboots
> the host on svm when a Linux guest issues "# shutdown -r now".
>   

Obviously a major issue, which we've neglected.  Thanks for addressing it.

> The patch below stops the rebooting of the host and handles the request
> to reboot the guest in an orderly fashion, so it's a big step forward,
> but it doesn't yet succeed in rebooting of the guest, instead the VM exits.
>
> The basic approach is to intercept the shutdown. The patch includes some
> possible alternatives to reboot, while searching for the best approach:
>
> 1) Call kvm_qemu_destroy(); and immediately after kvm_qemu_create_context();
>   

I don't like this approach.  It means memory needs to be deallocated and 
reallocated.  There's some likelyhood of the reallocation failing, so a 
reboot can turn into a dead VM.  Memory contents is not preserved, while 
a real reset does preserve memory.

More fundamentally, a real cpu can undergo a reset, and so should a 
virtual cpu.


> 2) New ioctl to reset a vcpu
>   

Definitely the way to go.  It'll possibly be needed for guest smp too.

> 3) I also tried calling init_vmcb from shutdown_intercept, but that had
> no noticable effect
>   

I think "shutdown" in this context is processor shutdown, not a vcpu 
reset.  IIRC a processor shutdown can be caused by invalid state or 
hardware errors.

We should intercept it, but it's not that important IMO.  (We should 
also find out what it means exactly)

> Method 1 seems promising, but currently results in kvm exiting due to
> "do_interrupt: unexpect" errors.
>
> Method 2 currently results in vmrun returning KVM_EXIT_TYPE_FAIL_ENTRY.
>
>   

Looks like not everything was initialized correctly...

> - Both of methods 1 and 2 need an API version bump
> - This code is safe to run without having to fear a host reboot
> - SVM only, at the moment
> - svm_reset_vcpu() was initially just the one-line call to init_vmcb(),
> there's some leftover cruft now...
> - A printf has been added to cpu_reset(), if this prints, qemu has
> called all registered reset handlers.
>
> Please comment. The Patch is relative to kvm-11.
>
>
>   
> ------------------------------------------------------------------------
>
> Index: kernel/kvm_main.c
> ===================================================================
> --- kernel/kvm_main.c	(revision 2211)
> +++ kernel/kvm_main.c	(working copy)
> @@ -1764,6 +1764,23 @@
>  	return r;
>  }
>  
> +static int kvm_dev_ioctl_reset_vcpu(struct kvm *kvm, struct kvm_reset_vcpu *slot)
> +{
> +	struct kvm_vcpu *vcpu;
> +
> +	if (!valid_vcpu(slot->vcpu))
> +		return -EINVAL;
> +	vcpu = vcpu_load(kvm, slot->vcpu);
> +	if (!vcpu)
> +		return -ENOENT;
> +
> +	kvm_arch_ops->reset_vcpu(vcpu);
> +
> +	vcpu_put(vcpu);
> +
> +	return 0;
> +}
> +
>  static long kvm_dev_ioctl(struct file *filp,
>  			  unsigned int ioctl, unsigned long arg)
>  {
> @@ -1780,6 +1797,13 @@
>  			goto out;
>  		break;
>  	}
> +	case KVM_RESET_VCPU: {
> +		struct kvm_reset_vcpu kvm_reset_vcpu;
>   

Empty line here.

> +		if (copy_from_user(&kvm_reset_vcpu, (void *)arg, sizeof kvm_reset_vcpu))
> +			goto out;
> +		r = kvm_dev_ioctl_reset_vcpu(kvm, &kvm_reset_vcpu);
> +		break;
> +	}
>  	case KVM_RUN: {
>  		struct kvm_run kvm_run;
>  
> Index: kernel/include/linux/kvm.h
> ===================================================================
> --- kernel/include/linux/kvm.h	(revision 2211)
> +++ kernel/include/linux/kvm.h	(working copy)
> @@ -11,7 +11,7 @@
>  #include <asm/types.h>
>  #include <linux/ioctl.h>
>  
> -#define KVM_API_VERSION 2
> +#define KVM_API_VERSION 3
>  
>  /*
>   * Architectural interrupt line count, and the size of the bitmap needed
> @@ -46,6 +46,7 @@
>  	KVM_EXIT_HLT              = 5,
>  	KVM_EXIT_MMIO             = 6,
>  	KVM_EXIT_IRQ_WINDOW_OPEN  = 7,
> +	KVM_EXIT_SHUTDOWN         = 8,
>  };
>  
>  /* for KVM_RUN */
> @@ -218,6 +219,12 @@
>  	};
>  };
>  
> +/* for KVM_RESET_VCPU */
> +struct kvm_reset_vcpu {
> +	/* in */
> +	__u32 vcpu;
> +};
> +
>   

Why define the structure?  Since ioctl() passes one argument, it can be 
the vcpu number.


>  #define KVMIO 0xAE
>  
>  #define KVM_GET_API_VERSION       _IO(KVMIO, 1)
> @@ -235,5 +242,6 @@
>  #define KVM_GET_MSRS              _IOWR(KVMIO, 13, struct kvm_msrs)
>  #define KVM_SET_MSRS              _IOWR(KVMIO, 14, struct kvm_msrs)
>  #define KVM_GET_MSR_INDEX_LIST    _IOWR(KVMIO, 15, struct kvm_msr_list)
> +#define KVM_RESET_VCPU            _IO(KVMIO, 16)
>   

If you're passing a structure, this needs to be _IOR(KVMIO, 16, struct 
kvm_reset_vcpu).


> @@ -582,6 +583,21 @@
>  	return r;
>  }
>  
> +static void svm_reset_vcpu(struct kvm_vcpu *vcpu)
> +{
> +	printk("....svm_reset_vcpu\n");
> +	memset(vcpu->svm->vmcb, 0, PAGE_SIZE);
> +	//vcpu->svm->vmcb_pa = page_to_pfn(page) << PAGE_SHIFT;
> +	vcpu->svm->cr0 = 0x00000010;
> +	vcpu->svm->asid_generation = 0;
> +	memset(vcpu->svm->db_regs, 0, sizeof(vcpu->svm->db_regs));
> +	init_vmcb(vcpu->svm->vmcb);
> +
> +	fx_init(vcpu);
> +
> +	init_vmcb(vcpu->svm->vmcb);
> +}
>   

You will need to reset the mmu context as well, as we're transitioning 
from protected mode to real mode.  Look at the set_sregs ioctl for an 
example.  This should be done from common code.

Perhaps init_vmcb relies on the save area being cleared.  Try zeroing 
vmcb->save in init_vmcb().

>  
> @@ -1690,6 +1715,8 @@
>  	.run = svm_vcpu_run,
>  	.skip_emulated_instruction = skip_emulated_instruction,
>  	.vcpu_setup = svm_vcpu_setup,
> +
> +	.reset_vcpu = svm_reset_vcpu,
>  };
>   

It would be nice to call reset_vcpu() as part of the normal vcpu 
creating sequence, to avoid having a rarely-used code path.

-- 
error compiling committee.c: too many arguments to function


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

      parent reply	other threads:[~2007-01-22 10:09 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-01-22  6:17 patch for review: kvm: implement guest rebooting Leonard Norrgard
     [not found] ` <45B456E9.3000709-g2GXA8XeJSExHbG02/KK1g@public.gmane.org>
2007-01-22 10:09   ` Avi Kivity [this message]

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=45B48D6F.1050307@qumranet.com \
    --to=avi-atkuwr5tajbwk0htik3j/w@public.gmane.org \
    --cc=kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
    --cc=leonard.norrgard-g2GXA8XeJSExHbG02/KK1g@public.gmane.org \
    /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