Merge "Change requested in launchpad bug #1288352" into 5.0
[packages/centos6/qemu.git] / 0236-pl190-fix-read-of-VECTADDR.patch
1 From 12d4393d0830a2a63828d302f177a9b8e31f433a Mon Sep 17 00:00:00 2001
2 From: Brendan Fennell <bfennell@skynet.ie>
3 Date: Wed, 26 Sep 2012 16:46:28 +0100
4 Subject: [PATCH] pl190: fix read of VECTADDR
5
6 Reading VECTADDR was causing us to set the current priority to
7 the wrong value, the most obvious effect of which was that we
8 would return the vector for the wrong interrupt as the result
9 of the read.
10
11 Signed-off-by: Brendan Fennell <bfennell@skynet.ie>
12 Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13 (cherry picked from commit 14c126baf1c38607c5bd988878de85a06cefd8cf)
14
15 Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
16 ---
17  hw/pl190.c | 18 ++++++++++++------
18  1 file changed, 12 insertions(+), 6 deletions(-)
19
20 diff --git a/hw/pl190.c b/hw/pl190.c
21 index cb50afb..7332f4d 100644
22 --- a/hw/pl190.c
23 +++ b/hw/pl190.c
24 @@ -117,12 +117,18 @@ static uint64_t pl190_read(void *opaque, target_phys_addr_t offset,
25          return s->protected;
26      case 12: /* VECTADDR */
27          /* Read vector address at the start of an ISR.  Increases the
28 -           current priority level to that of the current interrupt.  */
29 -        for (i = 0; i < s->priority; i++)
30 -          {
31 -            if ((s->level | s->soft_level) & s->prio_mask[i])
32 -              break;
33 -          }
34 +         * current priority level to that of the current interrupt.
35 +         *
36 +         * Since an enabled interrupt X at priority P causes prio_mask[Y]
37 +         * to have bit X set for all Y > P, this loop will stop with
38 +         * i == the priority of the highest priority set interrupt.
39 +         */
40 +        for (i = 0; i < s->priority; i++) {
41 +            if ((s->level | s->soft_level) & s->prio_mask[i + 1]) {
42 +                break;
43 +            }
44 +        }
45 +
46          /* Reading this value with no pending interrupts is undefined.
47             We return the default address.  */
48          if (i == PL190_NUM_PRIO)
49 -- 
50 1.7.12.1
51