mirror of
https://github.com/xen-project/xen.git
synced 2026-10-30 03:00:05 +01:00
hvm: vcpu reset support for x86 INIT IPI, needed for CPU hotplug.
Signed-off-by: Xin Li <xin.b.li@intel.com>
This commit is contained in:
1 parent
15587769c8
commit
e471d8c8bf
6 files changed
+45
-27
No files matched your search
+22
-11
@@ -273,6 +273,24 @@ void hvm_vcpu_destroy(struct vcpu *v)
|
||||
/*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;
|
||||
@@ -624,20 +642,13 @@ void hvm_hypercall_page_initialise(struct domain *d,
|
||||
*/
|
||||
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;
|
||||
|
||||
@@ -668,8 +679,8 @@ int hvm_bringup_ap(int vcpuid, int trampoline_vector)
|
||||
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:
|
||||
|
||||
@@ -209,7 +209,8 @@ int svm_create_vmcb(struct vcpu *v)
|
||||
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;
|
||||
|
||||
@@ -83,8 +83,6 @@ static unsigned int vlapic_lvt_mask[VLAPIC_LVT_NUM] =
|
||||
#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.
|
||||
*/
|
||||
@@ -293,8 +291,11 @@ static int vlapic_accept_irq(struct vcpu *v, int delivery_mode,
|
||||
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:
|
||||
@@ -303,10 +304,7 @@ static int vlapic_accept_irq(struct vcpu *v, int delivery_mode,
|
||||
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;
|
||||
@@ -764,7 +762,7 @@ int cpu_get_apic_interrupt(struct vcpu *v, int *mode)
|
||||
}
|
||||
|
||||
/* 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;
|
||||
@@ -793,8 +791,6 @@ static int vlapic_reset(struct vlapic *vlapic)
|
||||
|
||||
vlapic_set_reg(vlapic, APIC_SPIV, 0xff);
|
||||
vlapic->hw.disabled |= VLAPIC_SW_DISABLED;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef HVM_DEBUG_SUSPEND
|
||||
@@ -922,7 +918,6 @@ int vlapic_init(struct vcpu *v)
|
||||
{
|
||||
dprintk(XENLOG_ERR, "malloc vlapic regs error for vcpu %x\n",
|
||||
v->vcpu_id);
|
||||
xfree(vlapic);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
@@ -295,6 +295,11 @@ static void construct_vmcs(struct vcpu *v)
|
||||
|
||||
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);
|
||||
@@ -448,10 +453,13 @@ static void construct_vmcs(struct vcpu *v)
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -153,6 +153,7 @@ void hvm_domain_destroy(struct domain *d);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -78,6 +78,8 @@ int cpu_get_apic_interrupt(struct vcpu *v, int *mode);
|
||||
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);
|
||||
|
||||