From a0bc38e063a1fbade2f796e862aade6c5a68407a Mon Sep 17 00:00:00 2001 From: Eric Chanudet Date: Thu, 16 Nov 2017 11:45:38 +0100 Subject: [PATCH] x86/hvm: do not register hpet mmio during s3 cycle Do it once at domain creation (hpet_init). Sleep -> Resume cycles will end up crashing an HVM guest with hpet as the sequence during resume takes the path: -> hvm_s3_suspend -> hpet_reset -> hpet_deinit -> hpet_init -> register_mmio_handler -> hvm_next_io_handler register_mmio_handler will use a new io handler each time, until eventually it reaches NR_IO_HANDLERS, then hvm_next_io_handler calls domain_crash. Signed-off-by: Eric Chanudet Reviewed-by: Jan Beulich master commit: 015d6738ddff4074668c1d4887bbffd507ed1a7f master date: 2017-11-14 17:09:50 +0100 --- xen/arch/x86/hvm/hpet.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/xen/arch/x86/hvm/hpet.c b/xen/arch/x86/hvm/hpet.c index 3ea895a0fb..f7aed7f69e 100644 --- a/xen/arch/x86/hvm/hpet.c +++ b/xen/arch/x86/hvm/hpet.c @@ -635,14 +635,10 @@ static int hpet_load(struct domain *d, hvm_domain_context_t *h) HVM_REGISTER_SAVE_RESTORE(HPET, hpet_save, hpet_load, 1, HVMSR_PER_DOM); -void hpet_init(struct domain *d) +static void hpet_set(HPETState *h) { - HPETState *h = domain_vhpet(d); int i; - if ( !has_vhpet(d) ) - return; - memset(h, 0, sizeof(HPETState)); rwlock_init(&h->lock); @@ -668,7 +664,14 @@ void hpet_init(struct domain *d) h->hpet.comparator64[i] = ~0ULL; h->pt[i].source = PTSRC_isa; } +} + +void hpet_init(struct domain *d) +{ + if ( !has_vhpet(d) ) + return; + hpet_set(domain_vhpet(d)); register_mmio_handler(d, &hpet_mmio_ops); d->arch.hvm_domain.params[HVM_PARAM_HPET_ENABLED] = 1; } @@ -697,8 +700,11 @@ void hpet_deinit(struct domain *d) void hpet_reset(struct domain *d) { + if ( !has_vhpet(d) ) + return; + hpet_deinit(d); - hpet_init(d); + hpet_set(domain_vhpet(d)); } /* -- 2.39.5