]> xenbits.xensource.com Git - xen.git/commitdiff
x86/hvm: do not register hpet mmio during s3 cycle
authorEric Chanudet <chanudete@ainfosec.com>
Thu, 16 Nov 2017 11:01:28 +0000 (12:01 +0100)
committerJan Beulich <jbeulich@suse.com>
Thu, 16 Nov 2017 11:01:28 +0000 (12:01 +0100)
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 <chanudete@ainfosec.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
master commit: 015d6738ddff4074668c1d4887bbffd507ed1a7f
master date: 2017-11-14 17:09:50 +0100

xen/arch/x86/hvm/hpet.c

index 3ea895a0fb8d44d7b5f2fe29f645b4a62a3ab88c..f7aed7f69e74e2ec5f28425665098483d4753af1 100644 (file)
@@ -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));
 }
 
 /*