hvm/hpet: correctly gate the virtual HPET on HVM_PARAM_HPET_ENABLE
authorAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 19 Jan 2015 11:16:44 +0000 (12:16 +0100)
committerJan Beulich <jbeulich@suse.com>
Mon, 19 Jan 2015 11:16:44 +0000 (12:16 +0100)
c/s 3f8e22de7 "x86 hvm: Allow HPET to be configured as a per-domain config
option" introduced the parameter to conditionally enable the HPET.

However, having the check in hpet_range() does not have the intended effect.
As currently implemented, when the HPET is disabled, the range is not claimed
and an ioreq is forwarded to qemu, which implements an HPET itself.

Properly disable the HPET by always claiming the range, dropping writes and
reading ~0.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
xen/arch/x86/hvm/hpet.c

index bdfc6fc75084b36a6f33ff10dffd2fa21c2a1a0b..d898169ab486f173a817ee117c7a5ae16dcf49e0 100644 (file)
@@ -173,6 +173,12 @@ static int hpet_read(
     unsigned long result;
     uint64_t val;
 
+    if ( !v->domain->arch.hvm_domain.params[HVM_PARAM_HPET_ENABLED] )
+    {
+        result = ~0ul;
+        goto out;
+    }
+
     addr &= HPET_MMAP_SIZE-1;
 
     if ( hpet_check_access_length(addr, length) != 0 )
@@ -309,6 +315,9 @@ static int hpet_write(
 #define set_start_timer(n)   (__set_bit((n), &start_timers))
 #define set_restart_timer(n) (set_stop_timer(n),set_start_timer(n))
 
+    if ( !v->domain->arch.hvm_domain.params[HVM_PARAM_HPET_ENABLED] )
+        goto out;
+
     addr &= HPET_MMAP_SIZE-1;
 
     if ( hpet_check_access_length(addr, length) != 0 )
@@ -491,9 +500,8 @@ static int hpet_write(
 
 static int hpet_range(struct vcpu *v, unsigned long addr)
 {
-    return (v->domain->arch.hvm_domain.params[HVM_PARAM_HPET_ENABLED] &&
-            (addr >= HPET_BASE_ADDRESS) &&
-            (addr < (HPET_BASE_ADDRESS + HPET_MMAP_SIZE)));
+    return ( (addr >= HPET_BASE_ADDRESS) &&
+             (addr < (HPET_BASE_ADDRESS + HPET_MMAP_SIZE)) );
 }
 
 const struct hvm_mmio_handler hpet_mmio_handler = {