/*free_xen_event_channel(v, v->arch.hvm_vcpu.xen_port);*/
}
+
+void hvm_vcpu_reset(struct vcpu *v)
+{
+ vcpu_pause(v);
+
+ vlapic_reset(vcpu_vlapic(v));
+
+ hvm_funcs.vcpu_initialise(v);
+
+ set_bit(_VCPUF_down, &v->vcpu_flags);
+ clear_bit(_VCPUF_initialised, &v->vcpu_flags);
+ clear_bit(_VCPUF_fpu_initialised, &v->vcpu_flags);
+ clear_bit(_VCPUF_fpu_dirtied, &v->vcpu_flags);
+ clear_bit(_VCPUF_blocked, &v->vcpu_flags);
+
+ vcpu_unpause(v);
+}
+
static void hvm_vcpu_down(void)
{
struct vcpu *v = current;
*/
int hvm_bringup_ap(int vcpuid, int trampoline_vector)
{
- struct vcpu *bsp = current, *v;
- struct domain *d = bsp->domain;
+ struct vcpu *v;
+ struct domain *d = current->domain;
struct vcpu_guest_context *ctxt;
int rc = 0;
BUG_ON(!is_hvm_domain(d));
- if ( bsp->vcpu_id != 0 )
- {
- gdprintk(XENLOG_ERR, "Not calling hvm_bringup_ap from BSP context.\n");
- domain_crash(bsp->domain);
- return -EINVAL;
- }
-
if ( (v = d->vcpu[vcpuid]) == NULL )
return -ENOENT;
goto out;
}
- if ( test_and_clear_bit(_VCPUF_down, &d->vcpu[vcpuid]->vcpu_flags) )
- vcpu_wake(d->vcpu[vcpuid]);
+ if ( test_and_clear_bit(_VCPUF_down, &v->vcpu_flags) )
+ vcpu_wake(v);
gdprintk(XENLOG_INFO, "AP %d bringup suceeded.\n", vcpuid);
out:
struct arch_svm_struct *arch_svm = &v->arch.hvm_svm;
int rc;
- if ( (arch_svm->vmcb = alloc_vmcb()) == NULL )
+ if ( (arch_svm->vmcb == NULL) &&
+ (arch_svm->vmcb = alloc_vmcb()) == NULL )
{
printk("Failed to create a new VMCB\n");
return -ENOMEM;
#define vlapic_base_address(vlapic) \
(vlapic->hw.apic_base_msr & MSR_IA32_APICBASE_BASE)
-static int vlapic_reset(struct vlapic *vlapic);
-
/*
* Generic APIC bitmap vector update & search routines.
*/
break;
case APIC_DM_SMI:
+ gdprintk(XENLOG_WARNING, "Ignoring guest SMI\n");
+ break;
+
case APIC_DM_NMI:
- gdprintk(XENLOG_WARNING, "Ignoring guest SMI/NMI\n");
+ gdprintk(XENLOG_WARNING, "Ignoring guest NMI\n");
break;
case APIC_DM_INIT:
break;
/* FIXME How to check the situation after vcpu reset? */
if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
- {
- gdprintk(XENLOG_ERR, "Reset hvm vcpu not supported yet\n");
- goto exit_and_crash;
- }
+ hvm_vcpu_reset(v);
v->arch.hvm_vcpu.init_sipi_sipi_state =
HVM_VCPU_INIT_SIPI_SIPI_STATE_WAIT_SIPI;
result = 1;
}
/* Reset the VLPAIC back to its power-on/reset state. */
-static int vlapic_reset(struct vlapic *vlapic)
+void vlapic_reset(struct vlapic *vlapic)
{
struct vcpu *v = vlapic_vcpu(vlapic);
int i;
vlapic_set_reg(vlapic, APIC_SPIV, 0xff);
vlapic->hw.disabled |= VLAPIC_SW_DISABLED;
-
- return 1;
}
#ifdef HVM_DEBUG_SUSPEND
{
dprintk(XENLOG_ERR, "malloc vlapic regs error for vcpu %x\n",
v->vcpu_id);
- xfree(vlapic);
return -ENOMEM;
}
vmx_vmcs_enter(v);
+ v->arch.hvm_vmx.cpu_cr2 = 0;
+ v->arch.hvm_vmx.cpu_cr3 = 0;
+ memset(&v->arch.hvm_vmx.msr_state, 0, sizeof(v->arch.hvm_vmx.msr_state));
+ v->arch.hvm_vmx.vmxassist_enabled = 0;
+
/* VMCS controls. */
__vmwrite(PIN_BASED_VM_EXEC_CONTROL, vmx_pin_based_exec_control);
__vmwrite(VM_EXIT_CONTROLS, vmx_vmexit_control);
int vmx_create_vmcs(struct vcpu *v)
{
- if ( (v->arch.hvm_vmx.vmcs = vmx_alloc_vmcs()) == NULL )
- return -ENOMEM;
-
- __vmx_clear_vmcs(v);
+ if ( v->arch.hvm_vmx.vmcs == NULL )
+ {
+ if ( (v->arch.hvm_vmx.vmcs = vmx_alloc_vmcs()) == NULL )
+ return -ENOMEM;
+
+ __vmx_clear_vmcs(v);
+ }
construct_vmcs(v);
int hvm_vcpu_initialise(struct vcpu *v);
void hvm_vcpu_destroy(struct vcpu *v);
+void hvm_vcpu_reset(struct vcpu *vcpu);
void hvm_send_assist_req(struct vcpu *v);
int vlapic_init(struct vcpu *v);
void vlapic_destroy(struct vcpu *v);
+void vlapic_reset(struct vlapic *vlapic);
+
void vlapic_msr_set(struct vlapic *vlapic, uint64_t value);
int vlapic_accept_pic_intr(struct vcpu *v);