x86/HVM: generalize IRQ raising on RTC_REG_B writes
authorJan Beulich <jbeulich@suse.com>
Wed, 23 Jan 2013 13:20:28 +0000 (14:20 +0100)
committerJan Beulich <jbeulich@suse.com>
Wed, 23 Jan 2013 13:20:28 +0000 (14:20 +0100)
Raise the RTC IRQ not only when UIE gets set while UF was already set,
but generalize this to cover AIE and PIE as well.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
xen/arch/x86/hvm/rtc.c

index f8d3bed6d9b03af985b3d5e75ab3c33f5cd03a68..a7315cc0c292989b0d9a531e334ee1ea51168470 100644 (file)
@@ -371,7 +371,7 @@ static int rtc_ioport_write(void *opaque, uint32_t addr, uint32_t data)
 {
     RTCState *s = opaque;
     struct domain *d = vrtc_domain(s);
-    uint32_t orig;
+    uint32_t orig, mask;
 
     spin_lock(&s->lock);
 
@@ -442,12 +442,17 @@ static int rtc_ioport_write(void *opaque, uint32_t addr, uint32_t data)
             if ( orig & RTC_SET )
                 rtc_set_time(s);
         }
-        /* if the interrupt is already set when the interrupt become
-         * enabled, raise an interrupt immediately*/
-        if ((data & RTC_UIE) && !(orig & RTC_UIE))
-            if (s->hw.cmos_data[RTC_REG_C] & RTC_UF)
+        /*
+         * If the interrupt is already set when the interrupt becomes
+         * enabled, raise an interrupt immediately.
+         * NB: RTC_{A,P,U}IE == RTC_{A,P,U}F respectively.
+         */
+        for ( mask = RTC_UIE; mask <= RTC_PIE; mask <<= 1 )
+            if ( (data & mask) && !(orig & mask) &&
+                 (s->hw.cmos_data[RTC_REG_C] & mask) )
             {
                 rtc_toggle_irq(s);
+                break;
             }
         s->hw.cmos_data[RTC_REG_B] = data;
         check_update_timer(s);