int i;
HPETState *h = domain_vhpet(d);
- if ( !has_vhpet(d) )
+ if ( !has_vhpet(d) || !d->arch.hvm.pl_time || !h->stime_freq )
return;
write_lock(&h->lock);
for ( i = 0; i < HPET_TIMER_NUM; i++ )
if ( timer_enabled(h, i) )
hpet_stop_timer(h, i, guest_time);
+
+ h->hpet.config = 0;
}
write_unlock(&h->lock);
return 0;
fail2:
- rtc_deinit(d);
stdvga_deinit(d);
vioapic_deinit(d);
fail1:
if ( is_hardware_domain(d) )
xfree(d->arch.hvm.io_bitmap);
- xfree(d->arch.hvm.io_handler);
- xfree(d->arch.hvm.params);
- xfree(d->arch.hvm.pl_time);
- xfree(d->arch.hvm.irq);
+ XFREE(d->arch.hvm.io_handler);
+ XFREE(d->arch.hvm.params);
+ XFREE(d->arch.hvm.pl_time);
+ XFREE(d->arch.hvm.irq);
fail0:
hvm_destroy_cacheattr_region_list(d);
destroy_perdomain_mapping(d, PERDOMAIN_VIRT_START, 0);
fail:
- viridian_domain_deinit(d);
+ hvm_domain_relinquish_resources(d);
return rc;
}
+/* This function and all its descendants need to be to be idempotent. */
void hvm_domain_relinquish_resources(struct domain *d)
{
if ( hvm_funcs.domain_relinquish_resources )
/* Stop all asynchronous timer actions. */
rtc_deinit(d);
- if ( d->vcpu != NULL && d->vcpu[0] != NULL )
- {
- pmtimer_deinit(d);
- hpet_deinit(d);
- }
+ pmtimer_deinit(d);
+ hpet_deinit(d);
}
void hvm_domain_destroy(struct domain *d)
struct list_head *ioport_list, *tmp;
struct g2m_ioport *ioport;
+ /*
+ * This function would not be called when domain initialization fails
+ * (late enough), so do so here. This requires the function and all its
+ * descendants to be idempotent.
+ */
+ hvm_domain_relinquish_resources(d);
+
XFREE(d->arch.hvm.io_handler);
XFREE(d->arch.hvm.params);
if ( hvm_funcs.domain_destroy )
alternative_vcall(hvm_funcs.domain_destroy, d);
- rtc_deinit(d);
stdvga_deinit(d);
vioapic_deinit(d);
handler->portio.action = action;
}
-void relocate_portio_handler(struct domain *d, unsigned int old_port,
+bool relocate_portio_handler(struct domain *d, unsigned int old_port,
unsigned int new_port, unsigned int size)
{
unsigned int i;
(handler->portio.size = size) )
{
handler->portio.port = new_port;
- break;
+ return true;
}
}
+
+ return false;
}
bool_t hvm_mmio_internal(paddr_t gpa)
struct domain *d, unsigned int port, unsigned int size,
portio_action_t action);
-void relocate_portio_handler(
+bool relocate_portio_handler(
struct domain *d, unsigned int old_port, unsigned int new_port,
unsigned int size);