Register a check callback for the IOAPIC HVM save/restore entry, following the pattern established by vpic_check() for the virtual PIC. The function first verifies the target domain actually has a virtual IO-APIC, returning -ENODEV otherwise. It then iterates all redirection table entries and rejects any saved state where reserved bit fields are non-zero, ensuring the state being loaded, represents actually reachable hardware state before the restore is committed.
Signed-off-by: Julian Vetter <[email protected]> --- Changes in V3: - As suggested by Jan, added new patch that does a generic check of the vIOAPIC state before migration --- xen/arch/x86/hvm/vioapic.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c index 7c725f9e47..b9acdd8af6 100644 --- a/xen/arch/x86/hvm/vioapic.c +++ b/xen/arch/x86/hvm/vioapic.c @@ -594,6 +594,35 @@ int vioapic_get_trigger_mode(const struct domain *d, unsigned int gsi) return vioapic->redirtbl[pin].fields.trig_mode; } +static int cf_check ioapic_check(const struct domain *d, hvm_domain_context_t *h) +{ + const HVM_SAVE_TYPE(IOAPIC) *s; + unsigned int i; + + if ( !has_vioapic(d) ) + return -ENODEV; + + s = hvm_get_entry(IOAPIC, h); + if ( !s ) + return -ENODATA; + + for ( i = 0; i < ARRAY_SIZE(s->redirtbl); i++ ) + { + const union vioapic_redir_entry *e = &s->redirtbl[i]; + + /* + * Check to-be-loaded values are within valid range, for them to + * represent actually reachable state. + */ + if ( e->fields.reserve || + e->fields.reserved[0] || e->fields.reserved[1] || + e->fields.reserved[2] || e->fields.reserved[3] ) + return -EINVAL; + } + + return 0; +} + static int cf_check ioapic_save(struct vcpu *v, hvm_domain_context_t *h) { const struct domain *d = v->domain; -- 2.51.0 -- | Vates XCP-ng & Xen Orchestra - Vates solutions web: https://vates.tech
