~ubuntu-branches/ubuntu/trusty/qemu/trusty

« back to all changes in this revision

Viewing changes to debian/patches/linaro/0060-target-arm-add-support-for-smc.patch

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2014-02-04 12:13:08 UTC
  • mfrom: (10.1.45 sid)
  • Revision ID: package-import@ubuntu.com-20140204121308-1xq92lrfs75agw2g
Tags: 1.7.0+dfsg-3ubuntu1~ppa1
* Merge 1.7.0+dfsg-3 from debian.  Remaining changes:
  - debian/patches/ubuntu:
    * expose-vmx_qemu64cpu.patch
    * linaro (omap3) and arm64 patches
    * ubuntu/target-ppc-add-stubs-for-kvm-breakpoints: fix FTBFS
      on ppc
    * ubuntu/CVE-2013-4377.patch: fix denial of service via virtio
  - debian/qemu-system-x86.modprobe: set kvm_intel nested=1 options
  - debian/control:
    * add arm64 to Architectures
    * add qemu-common and qemu-system-aarch64 packages
  - debian/qemu-system-common.install: add debian/tmp/usr/lib
  - debian/qemu-system-common.preinst: add kvm group
  - debian/qemu-system-common.postinst: remove acl placed by udev,
    and add udevadm trigger.
  - qemu-system-x86.links: add eepro100.rom, remove pxe-virtio,
    pxe-e1000 and pxe-rtl8139.
  - add qemu-system-x86.qemu-kvm.upstart and .default
  - qemu-user-static.postinst-in: remove arm64 binfmt
  - debian/rules:
    * allow parallel build
    * add aarch64 to system_targets and sys_systems
    * add qemu-kvm-spice links
    * install qemu-system-x86.modprobe
  - add debian/qemu-system-common.links for OVMF.fd link
* Remove kvm-img, kvm-nbd, kvm-ifup and kvm-ifdown symlinks.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
From e02ac60868c370ec9a5464bfa4d65cf867f0f679 Mon Sep 17 00:00:00 2001
2
 
From: Peter Maydell <peter.maydell@linaro.org>
3
 
Date: Mon, 18 Feb 2013 16:58:34 +0000
4
 
Subject: [PATCH 60/70] target-arm: add support for smc
5
 
 
6
 
---
7
 
 target-arm/cpu.h       |  9 +++++---
8
 
 target-arm/helper.c    | 58 +++++++++++++++++++++++++++++++++-----------------
9
 
 target-arm/machine.c   |  6 +++---
10
 
 target-arm/translate.c | 47 ++++++++++++++++++++++++++++++----------
11
 
 4 files changed, 83 insertions(+), 37 deletions(-)
12
 
 
13
 
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
14
 
index 0f8cb4e..8c9f6a8 100644
15
 
--- a/target-arm/cpu.h
16
 
+++ b/target-arm/cpu.h
17
 
@@ -49,6 +49,7 @@
18
 
 #define EXCP_EXCEPTION_EXIT  8   /* Return from v7M exception.  */
19
 
 #define EXCP_KERNEL_TRAP     9   /* Jumped to kernel code page.  */
20
 
 #define EXCP_STREX          10
21
 
+#define EXCP_SMC            11   /* secure monitor call */
22
 
 
23
 
 #define ARMV7M_EXCP_RESET   1
24
 
 #define ARMV7M_EXCP_NMI     2
25
 
@@ -124,9 +125,9 @@ typedef struct CPUARMState {
26
 
     uint32_t spsr;
27
 
 
28
 
     /* Banked registers.  */
29
 
-    uint32_t banked_spsr[6];
30
 
-    uint32_t banked_r13[6];
31
 
-    uint32_t banked_r14[6];
32
 
+    uint32_t banked_spsr[7];
33
 
+    uint32_t banked_r13[7];
34
 
+    uint32_t banked_r14[7];
35
 
 
36
 
     /* These hold r8-r12.  */
37
 
     uint32_t usr_regs[5];
38
 
@@ -179,6 +180,7 @@ typedef struct CPUARMState {
39
 
         uint32_t c9_pmuserenr; /* perf monitor user enable */
40
 
         uint32_t c9_pminten; /* perf monitor interrupt enables */
41
 
         uint32_t c12_vbar; /* vector base address register */
42
 
+        uint32_t c12_mvbar; /* monitor vector base address register. */
43
 
         uint32_t c13_fcse; /* FCSE PID.  */
44
 
         uint32_t c13_context; /* Context ID.  */
45
 
         uint32_t c13_tls1; /* User RW Thread register.  */
46
 
@@ -404,6 +406,7 @@ enum arm_cpu_mode {
47
 
   ARM_CPU_MODE_FIQ = 0x11,
48
 
   ARM_CPU_MODE_IRQ = 0x12,
49
 
   ARM_CPU_MODE_SVC = 0x13,
50
 
+  ARM_CPU_MODE_SMC = 0x16,
51
 
   ARM_CPU_MODE_ABT = 0x17,
52
 
   ARM_CPU_MODE_UND = 0x1b,
53
 
   ARM_CPU_MODE_SYS = 0x1f
54
 
diff --git a/target-arm/helper.c b/target-arm/helper.c
55
 
index c4633be..9ff9699 100644
56
 
--- a/target-arm/helper.c
57
 
+++ b/target-arm/helper.c
58
 
@@ -543,13 +543,6 @@ static int pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
59
 
     return 0;
60
 
 }
61
 
 
62
 
-static int vbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
63
 
-                      uint64_t value)
64
 
-{
65
 
-    env->cp15.c12_vbar = value & ~0x1Ful;
66
 
-    return 0;
67
 
-}
68
 
-
69
 
 static int ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri,
70
 
                        uint64_t *value)
71
 
 {
72
 
@@ -1510,6 +1503,12 @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
73
 
     REGINFO_SENTINEL
74
 
 };
75
 
 
76
 
+static int vbar_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
77
 
+{
78
 
+    CPREG_FIELD32(env, ri) = value & ~0x1f;
79
 
+    return 0;
80
 
+}
81
 
+
82
 
 static const ARMCPRegInfo trustzone_cp_reginfo[] = {
83
 
     /* Dummy implementations of registers; we don't enforce the
84
 
      * 'secure mode only' access checks. TODO: revisit as part of
85
 
@@ -1529,7 +1528,8 @@ static const ARMCPRegInfo trustzone_cp_reginfo[] = {
86
 
       .fieldoffset = offsetof(CPUARMState, cp15.c12_vbar),
87
 
       .resetvalue = 0 },
88
 
     { .name = "MVBAR", .cp = 15, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 1,
89
 
-      .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
90
 
+      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c12_mvbar),
91
 
+      .writefn = vbar_write, .resetvalue = 0 },
92
 
     REGINFO_SENTINEL
93
 
 };
94
 
 
95
 
@@ -2204,6 +2204,8 @@ int bank_number(int mode)
96
 
         return 4;
97
 
     case ARM_CPU_MODE_FIQ:
98
 
         return 5;
99
 
+    case ARM_CPU_MODE_SMC:
100
 
+        return 6;
101
 
     }
102
 
     hw_error("bank number requested for bad CPSR mode value 0x%x\n", mode);
103
 
 }
104
 
@@ -2500,23 +2502,39 @@ void arm_cpu_do_interrupt(CPUState *cs)
105
 
         mask = CPSR_A | CPSR_I | CPSR_F;
106
 
         offset = 4;
107
 
         break;
108
 
+    case EXCP_SMC:
109
 
+        if (semihosting_enabled) {
110
 
+            cpu_abort(env, "SMC handling under semihosting not implemented\n");
111
 
+            return;
112
 
+        }
113
 
+        if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_SMC) {
114
 
+            env->cp15.c1_scr &= ~1;
115
 
+        }
116
 
+        offset = env->thumb ? 2 : 0;
117
 
+        new_mode = ARM_CPU_MODE_SMC;
118
 
+        addr = 0x08;
119
 
+        mask = CPSR_A | CPSR_I | CPSR_F;
120
 
+        break;
121
 
     default:
122
 
         cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
123
 
         return; /* Never happens.  Keep compiler happy.  */
124
 
     }
125
 
-    /* High vectors.  */
126
 
-    if (env->cp15.c1_sys & (1 << 13)) {
127
 
-        /* when enabled, base address cannot be remapped.  */
128
 
-        addr += 0xffff0000;
129
 
+    if (arm_feature(env, ARM_FEATURE_TRUSTZONE)) {
130
 
+        if (new_mode == ARM_CPU_MODE_SMC ||
131
 
+            (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_SMC) {
132
 
+            addr += env->cp15.c12_mvbar;
133
 
+        } else {
134
 
+            if (env->cp15.c1_sys & (1 << 13)) {
135
 
+                addr += 0xffff0000;
136
 
+            } else {
137
 
+                addr += env->cp15.c12_vbar;
138
 
+            }
139
 
+        }
140
 
     } else {
141
 
-        /* ARM v7 architectures provide a vector base address register to remap
142
 
-         * the interrupt vector table.
143
 
-         * This register is only followed in non-monitor mode, and has a secure
144
 
-         * and un-secure copy. Since the cpu is always in a un-secure operation
145
 
-         * and is never in monitor mode this feature is always active.
146
 
-         * Note: only bits 31:5 are valid.
147
 
-         */
148
 
-        addr += env->cp15.c12_vbar;
149
 
+        /* High vectors.  */
150
 
+        if (env->cp15.c1_sys & (1 << 13)) {
151
 
+            addr += 0xffff0000;
152
 
+        }
153
 
     }
154
 
     switch_mode (env, new_mode);
155
 
     env->spsr = cpsr_read(env);
156
 
diff --git a/target-arm/machine.c b/target-arm/machine.c
157
 
index 74f010f..3a41dd0 100644
158
 
--- a/target-arm/machine.c
159
 
+++ b/target-arm/machine.c
160
 
@@ -238,9 +238,9 @@ const VMStateDescription vmstate_arm_cpu = {
161
 
             .offset = 0,
162
 
         },
163
 
         VMSTATE_UINT32(env.spsr, ARMCPU),
164
 
-        VMSTATE_UINT32_ARRAY(env.banked_spsr, ARMCPU, 6),
165
 
-        VMSTATE_UINT32_ARRAY(env.banked_r13, ARMCPU, 6),
166
 
-        VMSTATE_UINT32_ARRAY(env.banked_r14, ARMCPU, 6),
167
 
+        VMSTATE_UINT32_ARRAY(env.banked_spsr, ARMCPU, 7),
168
 
+        VMSTATE_UINT32_ARRAY(env.banked_r13, ARMCPU, 7),
169
 
+        VMSTATE_UINT32_ARRAY(env.banked_r14, ARMCPU, 7),
170
 
         VMSTATE_UINT32_ARRAY(env.usr_regs, ARMCPU, 5),
171
 
         VMSTATE_UINT32_ARRAY(env.fiq_regs, ARMCPU, 5),
172
 
         /* The length-check must come before the arrays to avoid
173
 
diff --git a/target-arm/translate.c b/target-arm/translate.c
174
 
index 5f003e7..6954b56 100644
175
 
--- a/target-arm/translate.c
176
 
+++ b/target-arm/translate.c
177
 
@@ -60,6 +60,7 @@ static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE];
178
 
    conditional execution state has been updated.  */
179
 
 #define DISAS_WFI 4
180
 
 #define DISAS_SWI 5
181
 
+#define DISAS_SMC 6
182
 
 
183
 
 TCGv_ptr cpu_env;
184
 
 /* We reuse the same 64-bit temporaries for efficiency.  */
185
 
@@ -904,6 +905,12 @@ DO_GEN_ST(st8)
186
 
 DO_GEN_ST(st16)
187
 
 DO_GEN_ST(st32)
188
 
 
189
 
+static inline void gen_smc(CPUARMState *env, DisasContext *s)
190
 
+{
191
 
+    tcg_gen_movi_i32(cpu_R[15], s->pc);
192
 
+    s->is_jmp = DISAS_SMC;
193
 
+}
194
 
+
195
 
 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
196
 
 {
197
 
     if (s->aarch64) {
198
 
@@ -6878,8 +6885,13 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
199
 
         } else if ((insn & 0x0fe00000) == 0x0c400000) {
200
 
             /* Coprocessor double register transfer.  */
201
 
             ARCH(5TE);
202
 
+            /* XXX doesn't belong in the trustzone patch: should just UNDEF? */
203
 
+            cpu_abort(env, "unsupported coprocessor double register transfer\n");
204
 
         } else if ((insn & 0x0f000010) == 0x0e000010) {
205
 
             /* Additional coprocessor register transfer.  */
206
 
+            if (!disas_coproc_insn(env, s, insn)) {
207
 
+                return;
208
 
+            }
209
 
         } else if ((insn & 0x0ff10020) == 0x01000000) {
210
 
             uint32_t mask;
211
 
             uint32_t val;
212
 
@@ -7030,15 +7042,19 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
213
 
             store_reg(s, rd, tmp);
214
 
             break;
215
 
         case 7:
216
 
-            /* SMC instruction (op1 == 3)
217
 
-               and undefined instructions (op1 == 0 || op1 == 2)
218
 
-               will trap */
219
 
-            if (op1 != 1) {
220
 
+            if (op1 == 1) {
221
 
+                /* bkpt */
222
 
+                ARCH(5);
223
 
+                gen_exception_insn(s, 4, EXCP_BKPT);
224
 
+            } else if (op1 == 3) {
225
 
+                /* smi/smc */
226
 
+                if (!arm_feature(env, ARM_FEATURE_TRUSTZONE) || IS_USER(s)) {
227
 
+                    goto illegal_op;
228
 
+                }
229
 
+                gen_smc(env, s);
230
 
+            } else {
231
 
                 goto illegal_op;
232
 
             }
233
 
-            /* bkpt */
234
 
-            ARCH(5);
235
 
-            gen_exception_insn(s, 4, EXCP_BKPT);
236
 
             break;
237
 
         case 0x8: /* signed multiply */
238
 
         case 0xa:
239
 
@@ -8808,10 +8824,12 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
240
 
                     goto illegal_op;
241
 
 
242
 
                 if (insn & (1 << 26)) {
243
 
-                    /* Secure monitor call (v6Z) */
244
 
-                    qemu_log_mask(LOG_UNIMP,
245
 
-                                  "arm: unimplemented secure monitor call\n");
246
 
-                    goto illegal_op; /* not implemented.  */
247
 
+                    /* Secure monitor call / smc (v6Z) */
248
 
+                    if (!arm_feature(env, ARM_FEATURE_TRUSTZONE)
249
 
+                        || IS_USER(s)) {
250
 
+                        goto illegal_op;
251
 
+                    }
252
 
+                    gen_smc(env, s);
253
 
                 } else {
254
 
                     op = (insn >> 20) & 7;
255
 
                     switch (op) {
256
 
@@ -10205,6 +10223,8 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
257
 
             gen_set_condexec(dc);
258
 
             if (dc->is_jmp == DISAS_SWI) {
259
 
                 gen_exception(EXCP_SWI);
260
 
+            } else if (dc->is_jmp == DISAS_SMC) {
261
 
+                gen_exception(EXCP_SMC);
262
 
             } else {
263
 
                 gen_exception(EXCP_DEBUG);
264
 
             }
265
 
@@ -10217,6 +10237,8 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
266
 
         gen_set_condexec(dc);
267
 
         if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
268
 
             gen_exception(EXCP_SWI);
269
 
+        } else if (dc->is_jmp == DISAS_SMC && !dc->condjmp) {
270
 
+            gen_exception(EXCP_SMC);
271
 
         } else {
272
 
             /* FIXME: Single stepping a WFI insn will not halt
273
 
                the CPU.  */
274
 
@@ -10251,6 +10273,9 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
275
 
         case DISAS_SWI:
276
 
             gen_exception(EXCP_SWI);
277
 
             break;
278
 
+        case DISAS_SMC:
279
 
+            gen_exception(EXCP_SMC);
280
 
+            break;
281
 
         }
282
 
         if (dc->condjmp) {
283
 
             gen_set_label(dc->condlabel);
284
 
1.8.5.2
285