All of lore.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.