mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
x86/vlapic: Move lapic migration checks to the check hooks
While doing this, factor out checks common to architectural and hidden state. Signed-off-by: Alejandro Vallejo <alejandro.vallejo@cloud.com> Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
This commit is contained in:
1 parent
e305256e69
commit
eb48045d74
1 file changed
+57
-29
+57
-29
@@ -1571,60 +1571,88 @@ static void lapic_load_fixup(struct vlapic *vlapic)
|
||||
v, vlapic->loaded.id, vlapic->loaded.ldr, good_ldr);
|
||||
}
|
||||
|
||||
static int cf_check lapic_load_hidden(struct domain *d, hvm_domain_context_t *h)
|
||||
{
|
||||
unsigned int vcpuid = hvm_load_instance(h);
|
||||
struct vcpu *v;
|
||||
struct vlapic *s;
|
||||
|
||||
static int lapic_check_common(const struct domain *d, unsigned int vcpuid)
|
||||
{
|
||||
if ( !has_vlapic(d) )
|
||||
return -ENODEV;
|
||||
|
||||
/* Which vlapic to load? */
|
||||
if ( vcpuid >= d->max_vcpus || (v = d->vcpu[vcpuid]) == NULL )
|
||||
if ( !domain_vcpu(d, vcpuid) )
|
||||
{
|
||||
dprintk(XENLOG_G_ERR, "HVM restore: dom%d has no apic%u\n",
|
||||
dprintk(XENLOG_G_ERR, "HVM restore: dom%d has no vCPU %u\n",
|
||||
d->domain_id, vcpuid);
|
||||
return -EINVAL;
|
||||
}
|
||||
s = vcpu_vlapic(v);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cf_check lapic_check_hidden(const struct domain *d,
|
||||
hvm_domain_context_t *h)
|
||||
{
|
||||
unsigned int vcpuid = hvm_load_instance(h);
|
||||
struct hvm_hw_lapic s;
|
||||
int rc = lapic_check_common(d, vcpuid);
|
||||
|
||||
if ( rc )
|
||||
return rc;
|
||||
|
||||
if ( hvm_load_entry_zeroextend(LAPIC, h, &s) != 0 )
|
||||
return -ENODATA;
|
||||
|
||||
/* EN=0 with EXTD=1 is illegal */
|
||||
if ( (s.apic_base_msr & (APIC_BASE_ENABLE | APIC_BASE_EXTD)) ==
|
||||
APIC_BASE_EXTD )
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cf_check lapic_load_hidden(struct domain *d, hvm_domain_context_t *h)
|
||||
{
|
||||
unsigned int vcpuid = hvm_load_instance(h);
|
||||
struct vcpu *v = d->vcpu[vcpuid];
|
||||
struct vlapic *s = vcpu_vlapic(v);
|
||||
|
||||
if ( hvm_load_entry_zeroextend(LAPIC, h, &s->hw) != 0 )
|
||||
{
|
||||
ASSERT_UNREACHABLE();
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
s->loaded.hw = 1;
|
||||
if ( s->loaded.regs )
|
||||
lapic_load_fixup(s);
|
||||
|
||||
if ( !(s->hw.apic_base_msr & APIC_BASE_ENABLE) &&
|
||||
unlikely(vlapic_x2apic_mode(s)) )
|
||||
return -EINVAL;
|
||||
|
||||
hvm_update_vlapic_mode(v);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cf_check lapic_check_regs(const struct domain *d,
|
||||
hvm_domain_context_t *h)
|
||||
{
|
||||
unsigned int vcpuid = hvm_load_instance(h);
|
||||
int rc;
|
||||
|
||||
if ( (rc = lapic_check_common(d, vcpuid)) )
|
||||
return rc;
|
||||
|
||||
if ( !hvm_get_entry(LAPIC_REGS, h) )
|
||||
return -ENODATA;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cf_check lapic_load_regs(struct domain *d, hvm_domain_context_t *h)
|
||||
{
|
||||
unsigned int vcpuid = hvm_load_instance(h);
|
||||
struct vcpu *v;
|
||||
struct vlapic *s;
|
||||
|
||||
if ( !has_vlapic(d) )
|
||||
return -ENODEV;
|
||||
|
||||
/* Which vlapic to load? */
|
||||
if ( vcpuid >= d->max_vcpus || (v = d->vcpu[vcpuid]) == NULL )
|
||||
{
|
||||
dprintk(XENLOG_G_ERR, "HVM restore: dom%d has no apic%u\n",
|
||||
d->domain_id, vcpuid);
|
||||
return -EINVAL;
|
||||
}
|
||||
s = vcpu_vlapic(v);
|
||||
struct vcpu *v = d->vcpu[vcpuid];
|
||||
struct vlapic *s = vcpu_vlapic(v);
|
||||
|
||||
if ( hvm_load_entry(LAPIC_REGS, h, s->regs) != 0 )
|
||||
return -EINVAL;
|
||||
ASSERT_UNREACHABLE();
|
||||
|
||||
s->loaded.id = vlapic_get_reg(s, APIC_ID);
|
||||
s->loaded.ldr = vlapic_get_reg(s, APIC_LDR);
|
||||
@@ -1641,9 +1669,9 @@ static int cf_check lapic_load_regs(struct domain *d, hvm_domain_context_t *h)
|
||||
return 0;
|
||||
}
|
||||
|
||||
HVM_REGISTER_SAVE_RESTORE(LAPIC, lapic_save_hidden, NULL,
|
||||
HVM_REGISTER_SAVE_RESTORE(LAPIC, lapic_save_hidden, lapic_check_hidden,
|
||||
lapic_load_hidden, 1, HVMSR_PER_VCPU);
|
||||
HVM_REGISTER_SAVE_RESTORE(LAPIC_REGS, lapic_save_regs, NULL,
|
||||
HVM_REGISTER_SAVE_RESTORE(LAPIC_REGS, lapic_save_regs, lapic_check_regs,
|
||||
lapic_load_regs, 1, HVMSR_PER_VCPU);
|
||||
|
||||
int vlapic_init(struct vcpu *v)
|
||||
|
||||