aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/vmx.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/vmx.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/vmx.c')
-rw-r--r--drivers/kvm/vmx.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index f4618b9edf9c..440cacfda89c 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -1412,6 +1412,8 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
1412 goto out; 1412 goto out;
1413 } 1413 }
1414 1414
1415 vmx->vcpu.rmode.active = 0;
1416
1415 vmx->vcpu.regs[VCPU_REGS_RDX] = get_rdx_init_val(); 1417 vmx->vcpu.regs[VCPU_REGS_RDX] = get_rdx_init_val();
1416 set_cr8(&vmx->vcpu, 0); 1418 set_cr8(&vmx->vcpu, 0);
1417 msr = 0xfee00000 | MSR_IA32_APICBASE_ENABLE; 1419 msr = 0xfee00000 | MSR_IA32_APICBASE_ENABLE;
@@ -1425,8 +1427,13 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
1425 * GUEST_CS_BASE should really be 0xffff0000, but VT vm86 mode 1427 * GUEST_CS_BASE should really be 0xffff0000, but VT vm86 mode
1426 * insists on having GUEST_CS_BASE == GUEST_CS_SELECTOR << 4. Sigh. 1428 * insists on having GUEST_CS_BASE == GUEST_CS_SELECTOR << 4. Sigh.
1427 */ 1429 */
1428 vmcs_write16(GUEST_CS_SELECTOR, 0xf000); 1430 if (vmx->vcpu.vcpu_id == 0) {
1429 vmcs_writel(GUEST_CS_BASE, 0x000f0000); 1431 vmcs_write16(GUEST_CS_SELECTOR, 0xf000);
1432 vmcs_writel(GUEST_CS_BASE, 0x000f0000);
1433 } else {
1434 vmcs_write16(GUEST_CS_SELECTOR, vmx->vcpu.sipi_vector << 8);
1435 vmcs_writel(GUEST_CS_BASE, vmx->vcpu.sipi_vector << 12);
1436 }
1430 vmcs_write32(GUEST_CS_LIMIT, 0xffff); 1437 vmcs_write32(GUEST_CS_LIMIT, 0xffff);
1431 vmcs_write32(GUEST_CS_AR_BYTES, 0x9b); 1438 vmcs_write32(GUEST_CS_AR_BYTES, 0x9b);
1432 1439
@@ -1451,7 +1458,10 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
1451 vmcs_writel(GUEST_SYSENTER_EIP, 0); 1458 vmcs_writel(GUEST_SYSENTER_EIP, 0);
1452 1459
1453 vmcs_writel(GUEST_RFLAGS, 0x02); 1460 vmcs_writel(GUEST_RFLAGS, 0x02);
1454 vmcs_writel(GUEST_RIP, 0xfff0); 1461 if (vmx->vcpu.vcpu_id == 0)
1462 vmcs_writel(GUEST_RIP, 0xfff0);
1463 else
1464 vmcs_writel(GUEST_RIP, 0);
1455 vmcs_writel(GUEST_RSP, 0); 1465 vmcs_writel(GUEST_RSP, 0);
1456 1466
1457 //todo: dr0 = dr1 = dr2 = dr3 = 0; dr6 = 0xffff0ff0 1467 //todo: dr0 = dr1 = dr2 = dr3 = 0; dr6 = 0xffff0ff0
@@ -2201,6 +2211,14 @@ static int vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2201 u8 fail; 2211 u8 fail;
2202 int r; 2212 int r;
2203 2213
2214 if (unlikely(vcpu->mp_state == VCPU_MP_STATE_SIPI_RECEIVED)) {
2215 printk("vcpu %d received sipi with vector # %x\n",
2216 vcpu->vcpu_id, vcpu->sipi_vector);
2217 kvm_lapic_reset(vcpu);
2218 vmx_vcpu_setup(vmx);
2219 vcpu->mp_state = VCPU_MP_STATE_RUNNABLE;
2220 }
2221
2204preempted: 2222preempted:
2205 if (vcpu->guest_debug.enabled) 2223 if (vcpu->guest_debug.enabled)
2206 kvm_guest_debug_pre(vcpu); 2224 kvm_guest_debug_pre(vcpu);