public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
To: Gregory Haskins <ghaskins-Et1tbQHTxzrQT0dZR+AlfA@public.gmane.org>
Cc: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
Subject: Re: [PATCH 3/4] KVM: Adds ability to preempt an executing VCPU
Date: Mon, 07 May 2007 12:57:08 +0300	[thread overview]
Message-ID: <463EF7F4.9020106@qumranet.com> (raw)
In-Reply-To: <20070502214325.16738.42702.stgit-sLgBBP33vUGnsjUZhwzVf9HuzzzSOjJt@public.gmane.org>

Gregory Haskins wrote:
> The VCPU executes synchronously w.r.t. userspace today, and therefore
> interrupt injection is pretty straight forward.  However, we will soon need
> to be able to inject interrupts asynchronous to the execution of the VCPU
> due to the introduction of SMP, paravirtualized drivers, and asynchronous
> hypercalls.  This patch adds support to the interrupt mechanism to force
> a VCPU to VMEXIT when a new interrupt is pending.
>
> Signed-off-by: Gregory Haskins <ghaskins-Et1tbQHTxzrQT0dZR+AlfA@public.gmane.org>
> ---
>
>  drivers/kvm/kvm.h      |    5 +++
>  drivers/kvm/kvm_main.c |   74 +++++++++++++++++++++++++++++++++++++++++++++++-
>  drivers/kvm/svm.c      |   43 ++++++++++++++++++++++++++++
>  drivers/kvm/vmx.c      |   43 ++++++++++++++++++++++++++++
>  4 files changed, 164 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
> index d41d653..15c8bec 100644
> --- a/drivers/kvm/kvm.h
> +++ b/drivers/kvm/kvm.h
> @@ -321,6 +321,8 @@ void kvm_io_bus_register_dev(struct kvm_io_bus *bus,
>  
>  #define NR_IRQ_WORDS KVM_IRQ_BITMAP_SIZE(unsigned long)
>  
> +#define KVM_SIGNAL_VIRTUAL_INTERRUPT 33 /* Hardcoded for now */
> +
>  /*
>   * structure for maintaining info for interrupting an executing VCPU
>   */
> @@ -329,6 +331,9 @@ struct kvm_vcpu_irq {
>  	struct kvm_irqdevice dev;
>  	int                  pending;
>  	int                  deferred;
> +	struct task_struct  *task;
> +	int                  signo;
> +	int                  guest_mode;
>  };
>  
>  struct kvm_vcpu {
> diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
> index 9aeb2f7..6acbd9b 100644
> --- a/drivers/kvm/kvm_main.c
> +++ b/drivers/kvm/kvm_main.c
> @@ -304,6 +304,10 @@ static struct kvm *kvm_create_vm(void)
>  		memset(&vcpu->irq, 0, sizeof(vcpu->irq));
>  		spin_lock_init(&vcpu->irq.lock);
>  		vcpu->irq.deferred = -1;
> +		/*
> +		 * This should be settable by userspace someday
> +		 */
> +		vcpu->irq.signo = KVM_SIGNAL_VIRTUAL_INTERRUPT;
>   

This needs to be fixed prior to merging.  Hopefully not by setting the 
signal number, bit by making the vcpu fd writable (userspace can attach 
a signal to the fd if it wishes).

>  
>  		vcpu->cpu = -1;
>  		vcpu->kvm = kvm;
> @@ -366,13 +370,20 @@ static void free_pio_guest_pages(struct kvm_vcpu *vcpu)
>  
>  static void kvm_free_vcpu(struct kvm_vcpu *vcpu)
>  {
> +	unsigned long irqsave;
> +
>  	if (!vcpu->vmcs)
>  		return;
>  
>  	vcpu_load(vcpu);
>  	kvm_mmu_destroy(vcpu);
>  	vcpu_put(vcpu);
> +
> +	spin_lock_irqsave(&vcpu->irq.lock, irqsave);
> +	vcpu->irq.task = NULL;
> +	spin_unlock_irqrestore(&vcpu->irq.lock, irqsave);
>   

Can irq.task be non-NULL here at all?  Also, we only free vcpus when we 
destroy the vm, and paravirt drivers would hopefully hold a ref to the 
vm, so there's nobody to race against here.

>  	kvm_irqdevice_destructor(&vcpu->irq.dev);
>  
> @@ -1868,6 +1880,10 @@ static int kvm_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
>  		kvm_arch_ops->decache_regs(vcpu);
>  	}
>  
> +	spin_lock_irqsave(&vcpu->irq.lock, irqsaved);
> +	vcpu->irq.task = current;
> +	spin_unlock_irqrestore(&vcpu->irq.lock, irqsaved);
> +
>   

Just assignment + __smp_wmb().

> +/*
>   * This function will be invoked whenever the vcpu->irq.dev raises its INTR
>   * line
>   */
> @@ -2318,10 +2348,52 @@ static void kvm_vcpu_intr(struct kvm_irqsink *this,
>  {
>  	struct kvm_vcpu *vcpu = (struct kvm_vcpu*)this->private;
>  	unsigned long flags;
> +	int direct_ipi = -1;
>  
>  	spin_lock_irqsave(&vcpu->irq.lock, flags);
> -	__set_bit(pin, &vcpu->irq.pending);
> +
> +	if (!test_bit(pin, &vcpu->irq.pending)) {
> +		/*
> +		 * Record the change..
> +		 */
> +		__set_bit(pin, &vcpu->irq.pending);
> +
> +		/*
> +		 * then wake up the vcpu (if necessary)
> +		 */
> +		if (vcpu->irq.task && (vcpu->irq.task != current)) {
> +			if (vcpu->irq.guest_mode) {
> +				/*
> +				 * If we are in guest mode, we can optimize
> +				 * the IPI by executing a function directly
> +				 * on the owning processor.
> +				 */
> +				direct_ipi = task_cpu(vcpu->irq.task);
> +				BUG_ON(direct_ipi == smp_processor_id());
> +			} else
> +				/*
> +				 * otherwise, we must assume that we could be
> +				 * blocked anywhere, including userspace. Send
> +				 * a signal to give everyone a chance to get
> +				 * notification
> +				 */
> +				send_sig(vcpu->irq.signo, vcpu->irq.task, 0);
> +		}
> +	}
> +
>  	spin_unlock_irqrestore(&vcpu->irq.lock, flags);
> +
> +	if (direct_ipi != -1) {
> +		/*
> +		 * Not sure if disabling preemption is needed.
> +		 * The kick_process() code does this so I copied it
> +		 */
> +		preempt_disable();
> +		smp_call_function_single(direct_ipi,
> +					 kvm_vcpu_guest_intr,
> +					 vcpu, 0, 0);
> +		preempt_enable();
> +	}
>   

I see why you must issue the IPI outside the spin_lock_irqsave(), but 
aren't you now opening a race?  vcpu enters guest mode, irq on other 
cpu, irq sets direct_ipi to wakeup guest, releases lock, vcpu exits to 
userspace (or migrates to another cpu), ipi is issued but nobody cares.


>  	/*
> +	 * Signal that we have transitioned back to host mode
> +	 */
> +	spin_lock_irqsave(&vcpu->irq.lock, irq_flags);
> +	vcpu->irq.guest_mode = 0;
> +	spin_unlock_irqrestore(&vcpu->irq.lock, irq_flags);
> +
>   

Assign + __smp_wmb().

> +	/*
> +	 * Signal that we have transitioned back to host mode
> +	 */
> +	spin_lock_irqsave(&vcpu->irq.lock, irq_flags);
> +	vcpu->irq.guest_mode = 0;
> +	spin_unlock_irqrestore(&vcpu->irq.lock, irq_flags);
>   

Again.


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


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/

  parent reply	other threads:[~2007-05-07  9:57 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-05-02 21:43 [PATCH 0/4] Kernel side patches for in-kernel APIC Gregory Haskins
     [not found] ` <20070502212713.16738.8133.stgit-sLgBBP33vUGnsjUZhwzVf9HuzzzSOjJt@public.gmane.org>
2007-05-02 21:43   ` [PATCH 1/4] KVM: Adds support for in-kernel mmio handlers Gregory Haskins
     [not found]     ` <20070502214315.16738.68984.stgit-sLgBBP33vUGnsjUZhwzVf9HuzzzSOjJt@public.gmane.org>
2007-05-07  9:30       ` Avi Kivity
     [not found]         ` <463EF198.1050303-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-05-07 14:37           ` Gregory Haskins
2007-05-02 21:43   ` [PATCH 2/4] KVM: Add irqdevice object Gregory Haskins
     [not found]     ` <20070502214320.16738.21505.stgit-sLgBBP33vUGnsjUZhwzVf9HuzzzSOjJt@public.gmane.org>
2007-05-07  9:42       ` Avi Kivity
     [not found]         ` <463EF493.9070300-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-05-07 14:39           ` Gregory Haskins
2007-05-02 21:43   ` [PATCH 3/4] KVM: Adds ability to preempt an executing VCPU Gregory Haskins
     [not found]     ` <20070502214325.16738.42702.stgit-sLgBBP33vUGnsjUZhwzVf9HuzzzSOjJt@public.gmane.org>
2007-05-07  9:57       ` Avi Kivity [this message]
     [not found]         ` <463EF7F4.9020106-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-05-07 14:52           ` Gregory Haskins
     [not found]             ` <463F04D8.BA47.005A.0-Et1tbQHTxzrQT0dZR+AlfA@public.gmane.org>
2007-05-08  8:13               ` Avi Kivity
     [not found]                 ` <46403117.2070000-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-05-08 11:48                   ` Gregory Haskins
     [not found]                     ` <46402B25.BA47.005A.0-Et1tbQHTxzrQT0dZR+AlfA@public.gmane.org>
2007-05-08 11:56                       ` Avi Kivity
2007-05-07 15:17           ` Gregory Haskins
     [not found]             ` <463F0AC7.BA47.005A.0-Et1tbQHTxzrQT0dZR+AlfA@public.gmane.org>
2007-05-08  8:26               ` Avi Kivity
     [not found]                 ` <4640341E.6090905-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-05-08 12:00                   ` Gregory Haskins
2007-05-02 21:43   ` [PATCH 4/4] KVM: Add support for in-kernel LAPIC model Gregory Haskins
     [not found]     ` <20070502214330.16738.51436.stgit-sLgBBP33vUGnsjUZhwzVf9HuzzzSOjJt@public.gmane.org>
2007-05-07 10:17       ` Avi Kivity
     [not found]         ` <463EFCC5.8050408-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-05-07 10:22           ` Avi Kivity
2007-05-07 15:10           ` Gregory Haskins
     [not found]             ` <463F0914.BA47.005A.0-Et1tbQHTxzrQT0dZR+AlfA@public.gmane.org>
2007-05-08  8:19               ` Avi Kivity
     [not found]                 ` <464032A3.2010303-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-05-08 11:59                   ` Gregory Haskins
     [not found]                     ` <46402DC0.BA47.005A.0-Et1tbQHTxzrQT0dZR+AlfA@public.gmane.org>
2007-05-13 10:21                       ` Avi Kivity
2007-05-03 18:57   ` [PATCH 0/4] Kernel side patches for in-kernel APIC Nakajima, Jun
     [not found]     ` <8FFF7E42E93CC646B632AB40643802A8028B114D-1a9uaKK1+wJcIJlls4ac1rfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-05-03 21:18       ` Gregory Haskins
     [not found]         ` <463A1935.BA47.005A.0-Et1tbQHTxzrQT0dZR+AlfA@public.gmane.org>
2007-05-06  7:49           ` Avi Kivity
     [not found]             ` <463D8887.5020007-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-05-07 14:36               ` Gregory Haskins
2007-05-06  7:45   ` Avi Kivity

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=463EF7F4.9020106@qumranet.com \
    --to=avi-atkuwr5tajbwk0htik3j/w@public.gmane.org \
    --cc=ghaskins-Et1tbQHTxzrQT0dZR+AlfA@public.gmane.org \
    --cc=kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@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