diff options
author | He, Qing <qing.he@intel.com> | 2007-09-03 10:07:41 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2007-10-13 04:18:26 -0400 |
commit | c5ec153402b6d276fe20029da1059ba42a4b55e5 (patch) | |
tree | a323fd0466f606b66fc7239e78569863d62f6300 /drivers/kvm/vmx.c | |
parent | 932f72adbe76f098922c746737cb0bd75fc21e27 (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.c | 24 |
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 | |||
2204 | preempted: | 2222 | preempted: |
2205 | if (vcpu->guest_debug.enabled) | 2223 | if (vcpu->guest_debug.enabled) |
2206 | kvm_guest_debug_pre(vcpu); | 2224 | kvm_guest_debug_pre(vcpu); |