aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/kvm_main.c
diff options
context:
space:
mode:
authorHe, Qing <qing.he@intel.com>2007-09-03 10:07:41 -0400
committerAvi Kivity <avi@qumranet.com>2007-10-13 04:18:26 -0400
commitc5ec153402b6d276fe20029da1059ba42a4b55e5 (patch)
treea323fd0466f606b66fc7239e78569863d62f6300 /drivers/kvm/kvm_main.c
parent932f72adbe76f098922c746737cb0bd75fc21e27 (diff)
KVM: enable in-kernel APIC INIT/SIPI handling
This patch enables INIT/SIPI handling using in-kernel APIC by introducing a ->mp_state field to emulate the SMP state transition. [avi: remove smp_processor_id() warning] Signed-off-by: Qing He <qing.he@intel.com> Signed-off-by: Xin Li <xin.b.li@intel.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers/kvm/kvm_main.c')
-rw-r--r--drivers/kvm/kvm_main.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 02af24e8350c..d0a5a2b3d599 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -249,6 +249,10 @@ int kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id)
249 vcpu->mmu.root_hpa = INVALID_PAGE; 249 vcpu->mmu.root_hpa = INVALID_PAGE;
250 vcpu->kvm = kvm; 250 vcpu->kvm = kvm;
251 vcpu->vcpu_id = id; 251 vcpu->vcpu_id = id;
252 if (!irqchip_in_kernel(kvm) || id == 0)
253 vcpu->mp_state = VCPU_MP_STATE_RUNNABLE;
254 else
255 vcpu->mp_state = VCPU_MP_STATE_UNINITIALIZED;
252 init_waitqueue_head(&vcpu->wq); 256 init_waitqueue_head(&vcpu->wq);
253 257
254 page = alloc_page(GFP_KERNEL | __GFP_ZERO); 258 page = alloc_page(GFP_KERNEL | __GFP_ZERO);
@@ -1371,7 +1375,7 @@ EXPORT_SYMBOL_GPL(emulate_instruction);
1371/* 1375/*
1372 * The vCPU has executed a HLT instruction with in-kernel mode enabled. 1376 * The vCPU has executed a HLT instruction with in-kernel mode enabled.
1373 */ 1377 */
1374static void kvm_vcpu_kernel_halt(struct kvm_vcpu *vcpu) 1378static void kvm_vcpu_block(struct kvm_vcpu *vcpu)
1375{ 1379{
1376 DECLARE_WAITQUEUE(wait, current); 1380 DECLARE_WAITQUEUE(wait, current);
1377 1381
@@ -1380,24 +1384,28 @@ static void kvm_vcpu_kernel_halt(struct kvm_vcpu *vcpu)
1380 /* 1384 /*
1381 * We will block until either an interrupt or a signal wakes us up 1385 * We will block until either an interrupt or a signal wakes us up
1382 */ 1386 */
1383 while(!(irqchip_in_kernel(vcpu->kvm) && kvm_cpu_has_interrupt(vcpu)) 1387 while (!kvm_cpu_has_interrupt(vcpu)
1384 && !vcpu->irq_summary 1388 && !signal_pending(current)
1385 && !signal_pending(current)) { 1389 && vcpu->mp_state != VCPU_MP_STATE_RUNNABLE
1390 && vcpu->mp_state != VCPU_MP_STATE_SIPI_RECEIVED) {
1386 set_current_state(TASK_INTERRUPTIBLE); 1391 set_current_state(TASK_INTERRUPTIBLE);
1387 vcpu_put(vcpu); 1392 vcpu_put(vcpu);
1388 schedule(); 1393 schedule();
1389 vcpu_load(vcpu); 1394 vcpu_load(vcpu);
1390 } 1395 }
1391 1396
1397 __set_current_state(TASK_RUNNING);
1392 remove_wait_queue(&vcpu->wq, &wait); 1398 remove_wait_queue(&vcpu->wq, &wait);
1393 set_current_state(TASK_RUNNING);
1394} 1399}
1395 1400
1396int kvm_emulate_halt(struct kvm_vcpu *vcpu) 1401int kvm_emulate_halt(struct kvm_vcpu *vcpu)
1397{ 1402{
1398 ++vcpu->stat.halt_exits; 1403 ++vcpu->stat.halt_exits;
1399 if (irqchip_in_kernel(vcpu->kvm)) { 1404 if (irqchip_in_kernel(vcpu->kvm)) {
1400 kvm_vcpu_kernel_halt(vcpu); 1405 vcpu->mp_state = VCPU_MP_STATE_HALTED;
1406 kvm_vcpu_block(vcpu);
1407 if (vcpu->mp_state != VCPU_MP_STATE_RUNNABLE)
1408 return -EINTR;
1401 return 1; 1409 return 1;
1402 } else { 1410 } else {
1403 vcpu->run->exit_reason = KVM_EXIT_HLT; 1411 vcpu->run->exit_reason = KVM_EXIT_HLT;
@@ -2001,6 +2009,12 @@ static int kvm_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2001 2009
2002 vcpu_load(vcpu); 2010 vcpu_load(vcpu);
2003 2011
2012 if (unlikely(vcpu->mp_state == VCPU_MP_STATE_UNINITIALIZED)) {
2013 kvm_vcpu_block(vcpu);
2014 vcpu_put(vcpu);
2015 return -EAGAIN;
2016 }
2017
2004 if (vcpu->sigset_active) 2018 if (vcpu->sigset_active)
2005 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved); 2019 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
2006 2020