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

« back to all changes in this revision

Viewing changes to debian/patches/ubuntu/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
-- 
 
285
1.8.5.2
 
286