summary refs log tree commit diff stats
path: root/results/classifier/zero-shot/118/none/1226531
blob: fef3c68291eba91c6ac188d047247d0f137d2b64 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
user-level: 0.581
risc-v: 0.577
permissions: 0.537
peripherals: 0.505
VMM: 0.493
PID: 0.481
TCG: 0.449
semantic: 0.449
architecture: 0.448
arm: 0.445
ppc: 0.442
mistranslation: 0.408
vnc: 0.398
assembly: 0.379
performance: 0.378
graphic: 0.375
register: 0.366
hypervisor: 0.365
device: 0.364
network: 0.363
socket: 0.350
files: 0.347
kernel: 0.343
KVM: 0.341
boot: 0.329
debug: 0.314
virtual: 0.296
x86: 0.277
i386: 0.200

Incorrect logic in ARMv7M interrupt handler

On ARMv7M interrupts handlers will be called even if emulated code executes "cpsid i" instruction.

Underlying cause described below:

In cpu-exec.c:cpu_exec there is a block of code that determines if an interrupt should be raised or not:


                    /* ARMv7-M interrupt return works by loading a magic value
                       into the PC.  On real hardware the load causes the
                       return to occur.  The qemu implementation performs the
                       jump normally, then does the exception return when the
                       CPU tries to execute code at the magic address.
                       This will cause the magic PC value to be pushed to
                       the stack if an interrupt occurred at the wrong time.
                       We avoid this by disabling interrupts when
                       pc contains a magic address.  */
                    if (interrupt_request & CPU_INTERRUPT_HARD
                        && ((IS_M(env) && env->regs[15] < 0xfffffff0)
                            || !(env->uncached_cpsr & CPSR_I))) {
                        env->exception_index = EXCP_IRQ;
                        cc->do_interrupt(cpu);
                        next_tb = 0;
                    }

I'm not convinced the logic is correct.
The logic for ARMv7M should be:

If an interrupt is pending (interrupt_request & CPU_INTERRUPT_HARD)
AND
Interrupts are not disabled ( !(env->uncached_cpsr & CPSR_I) )
AND
PC doesn't have a magic value (env->regs[15] < 0xfffffff0)

The current logic seems fires the interrupt if interrupts are enabled OR the PC isn't magic, which is basically all the time.

I'm not sure what the cleanest patch for this would be.

On 17 September 2013 11:44, benno <email address hidden> wrote:
> I'm not convinced the logic is correct.

It's not. There have been a few attempts by people to submit patches
to this though, but none of them have actually been sufficiently
convincing. See for instance
http://lists.nongnu.org/archive/html/qemu-devel/2013-05/msg04546.html

If somebody produces a patch which comes with a good rationale
for its change (ie with reference to the architecture manual and to
what QEMU means when it sets "CPSR_I" on M profile) I'll apply
it. But because the v7M code is currently not really maintained and
v7M interrupts are complex I'm reluctant to apply patches which
only come with "seems to fix things for me" levels of justification.

-- PMM


We finally fixed this longstanding ARMv7M emulation bug in the 2.10 release (by rewriting the NVIC handling entirely).