[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[qemu-xen staging] hw/timer/imx_epit: Avoid assertion when CR.SWR is written



commit 13557fd392890cbd985bceba7f717e01efd674b8
Author:     Peter Maydell <peter.maydell@xxxxxxxxxx>
AuthorDate: Mon Jul 27 16:45:50 2020 +0100
Commit:     Peter Maydell <peter.maydell@xxxxxxxxxx>
CommitDate: Mon Aug 3 17:56:11 2020 +0100

    hw/timer/imx_epit: Avoid assertion when CR.SWR is written
    
    The imx_epit device has a software-controllable reset triggered by
    setting the SWR bit in the CR register. An error in commit cc2722ec83ad9
    means that we will end up assert()ing if the guest does this, because
    the code in imx_epit_write() starts ptimer transactions, and then
    imx_epit_reset() also starts ptimer transactions, triggering
    "ptimer_transaction_begin: Assertion `!s->in_transaction' failed".
    
    The cleanest way to avoid this double-transaction is to move the
    start-transaction for the CR write handling down below the check of
    the SWR bit.
    
    Fixes: https://bugs.launchpad.net/qemu/+bug/1880424
    Fixes: cc2722ec83ad944505fe
    Signed-off-by: Peter Maydell <peter.maydell@xxxxxxxxxx>
    Reviewed-by: Philippe Mathieu-Daudé <f4bug@xxxxxxxxx>
    Message-id: 20200727154550.3409-1-peter.maydell@xxxxxxxxxx
---
 hw/timer/imx_epit.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index baf6338e1a..ebd58254d1 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -199,15 +199,22 @@ static void imx_epit_write(void *opaque, hwaddr offset, 
uint64_t value,
 
     switch (offset >> 2) {
     case 0: /* CR */
-        ptimer_transaction_begin(s->timer_cmp);
-        ptimer_transaction_begin(s->timer_reload);
 
         oldcr = s->cr;
         s->cr = value & 0x03ffffff;
         if (s->cr & CR_SWR) {
             /* handle the reset */
             imx_epit_reset(DEVICE(s));
-        } else {
+            /*
+             * TODO: could we 'break' here? following operations appear
+             * to duplicate the work imx_epit_reset() already did.
+             */
+        }
+
+        ptimer_transaction_begin(s->timer_cmp);
+        ptimer_transaction_begin(s->timer_reload);
+
+        if (!(s->cr & CR_SWR)) {
             imx_epit_set_freq(s);
         }
 
--
generated by git-patchbot for /home/xen/git/qemu-xen.git#staging



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.