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

« back to all changes in this revision

Viewing changes to debian/patches/ubuntu/arm64/0018-target-arm-Clean-up-handling-of-AArch64-PSTATE.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 68c50a55125fe875eba92c6e414086b64c7c0798 Mon Sep 17 00:00:00 2001
 
2
From: Peter Maydell <peter.maydell@linaro.org>
 
3
Date: Tue, 17 Dec 2013 19:42:30 +0000
 
4
Subject: [PATCH 18/49] target-arm: Clean up handling of AArch64 PSTATE
 
5
 
 
6
The env->pstate field is a little odd since it doesn't strictly
 
7
speaking represent an architectural register. However it's convenient
 
8
for QEMU to use it to hold the various PSTATE architectural bits
 
9
in the same format the architecture specifies for SPSR registers
 
10
(since this is the same format the kernel uses for signal handlers
 
11
and the KVM register). Add some structure to how we deal with it:
 
12
 * document what env->pstate is
 
13
 * add some #defines for various bits in it
 
14
 * add helpers for reading/writing it taking account of caching
 
15
   of NZCV, and use them where appropriate
 
16
 * reset it on startup
 
17
 
 
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
 
19
Message-id: 1385645602-18662-3-git-send-email-peter.maydell@linaro.org
 
20
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
 
21
---
 
22
 linux-user/signal.c        |  6 ++--
 
23
 target-arm/cpu.c           |  6 ++++
 
24
 target-arm/cpu.h           | 70 ++++++++++++++++++++++++++++++++++++++--------
 
25
 target-arm/gdbstub64.c     |  4 +--
 
26
 target-arm/translate-a64.c | 12 ++++----
 
27
 5 files changed, 78 insertions(+), 20 deletions(-)
 
28
 
 
29
diff --git a/linux-user/signal.c b/linux-user/signal.c
 
30
index 7751c47..4e7148a 100644
 
31
--- a/linux-user/signal.c
 
32
+++ b/linux-user/signal.c
 
33
@@ -1171,7 +1171,7 @@ static int target_setup_sigframe(struct target_rt_sigframe *sf,
 
34
     }
 
35
     __put_user(env->xregs[31], &sf->uc.tuc_mcontext.sp);
 
36
     __put_user(env->pc, &sf->uc.tuc_mcontext.pc);
 
37
-    __put_user(env->pstate, &sf->uc.tuc_mcontext.pstate);
 
38
+    __put_user(pstate_read(env), &sf->uc.tuc_mcontext.pstate);
 
39
 
 
40
     __put_user(/*current->thread.fault_address*/ 0,
 
41
             &sf->uc.tuc_mcontext.fault_address);
 
42
@@ -1210,6 +1210,7 @@ static int target_restore_sigframe(CPUARMState *env,
 
43
     struct target_aux_context *aux =
 
44
         (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
 
45
     uint32_t magic, size;
 
46
+    uint64_t pstate;
 
47
 
 
48
     target_to_host_sigset(&set, &sf->uc.tuc_sigmask);
 
49
     sigprocmask(SIG_SETMASK, &set, NULL);
 
50
@@ -1220,7 +1221,8 @@ static int target_restore_sigframe(CPUARMState *env,
 
51
 
 
52
     __get_user(env->xregs[31], &sf->uc.tuc_mcontext.sp);
 
53
     __get_user(env->pc, &sf->uc.tuc_mcontext.pc);
 
54
-    __get_user(env->pstate, &sf->uc.tuc_mcontext.pstate);
 
55
+    __get_user(pstate, &sf->uc.tuc_mcontext.pstate);
 
56
+    pstate_write(env, pstate);
 
57
 
 
58
     __get_user(magic, &aux->fpsimd.head.magic);
 
59
     __get_user(size, &aux->fpsimd.head.size);
 
60
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
 
61
index 0635e78..42057ad 100644
 
62
--- a/target-arm/cpu.c
 
63
+++ b/target-arm/cpu.c
 
64
@@ -88,6 +88,12 @@ static void arm_cpu_reset(CPUState *s)
 
65
     if (arm_feature(env, ARM_FEATURE_AARCH64)) {
 
66
         /* 64 bit CPUs always start in 64 bit mode */
 
67
         env->aarch64 = 1;
 
68
+#if defined(CONFIG_USER_ONLY)
 
69
+        env->pstate = PSTATE_MODE_EL0t;
 
70
+#else
 
71
+        env->pstate = PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F
 
72
+            | PSTATE_MODE_EL1h;
 
73
+#endif
 
74
     }
 
75
 
 
76
 #if defined(CONFIG_USER_ONLY)
 
77
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
 
78
index c3f007f..d15fdcd 100644
 
79
--- a/target-arm/cpu.h
 
80
+++ b/target-arm/cpu.h
 
81
@@ -113,8 +113,15 @@ typedef struct CPUARMState {
 
82
     /* Regs for A64 mode.  */
 
83
     uint64_t xregs[32];
 
84
     uint64_t pc;
 
85
-    /* TODO: pstate doesn't correspond to an architectural register;
 
86
-     * it would be better modelled as the underlying fields.
 
87
+    /* PSTATE isn't an architectural register for ARMv8. However, it is
 
88
+     * convenient for us to assemble the underlying state into a 32 bit format
 
89
+     * identical to the architectural format used for the SPSR. (This is also
 
90
+     * what the Linux kernel's 'pstate' field in signal handlers and KVM's
 
91
+     * 'pstate' register are.) Of the PSTATE bits:
 
92
+     *  NZCV are kept in the split out env->CF/VF/NF/ZF, (which have the same
 
93
+     *    semantics as for AArch32, as described in the comments on each field)
 
94
+     *  nRW (also known as M[4]) is kept, inverted, in env->aarch64
 
95
+     *  all other bits are stored in their correct places in env->pstate
 
96
      */
 
97
     uint32_t pstate;
 
98
     uint32_t aarch64; /* 1 if CPU is in aarch64 state; inverse of PSTATE.nRW */
 
99
@@ -309,15 +316,6 @@ static inline bool is_a64(CPUARMState *env)
 
100
     return env->aarch64;
 
101
 }
 
102
 
 
103
-#define PSTATE_N_SHIFT 3
 
104
-#define PSTATE_N  (1 << PSTATE_N_SHIFT)
 
105
-#define PSTATE_Z_SHIFT 2
 
106
-#define PSTATE_Z  (1 << PSTATE_Z_SHIFT)
 
107
-#define PSTATE_C_SHIFT 1
 
108
-#define PSTATE_C  (1 << PSTATE_C_SHIFT)
 
109
-#define PSTATE_V_SHIFT 0
 
110
-#define PSTATE_V  (1 << PSTATE_V_SHIFT)
 
111
-
 
112
 /* you can call this signal handler from your SIGBUS and SIGSEGV
 
113
    signal handlers to inform the virtual CPU of exceptions. non zero
 
114
    is returned if the signal was handled by the virtual CPU.  */
 
115
@@ -352,6 +350,56 @@ int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, int rw,
 
116
 /* Execution state bits.  MRS read as zero, MSR writes ignored.  */
 
117
 #define CPSR_EXEC (CPSR_T | CPSR_IT | CPSR_J)
 
118
 
 
119
+/* Bit definitions for ARMv8 SPSR (PSTATE) format.
 
120
+ * Only these are valid when in AArch64 mode; in
 
121
+ * AArch32 mode SPSRs are basically CPSR-format.
 
122
+ */
 
123
+#define PSTATE_M (0xFU)
 
124
+#define PSTATE_nRW (1U << 4)
 
125
+#define PSTATE_F (1U << 6)
 
126
+#define PSTATE_I (1U << 7)
 
127
+#define PSTATE_A (1U << 8)
 
128
+#define PSTATE_D (1U << 9)
 
129
+#define PSTATE_IL (1U << 20)
 
130
+#define PSTATE_SS (1U << 21)
 
131
+#define PSTATE_V (1U << 28)
 
132
+#define PSTATE_C (1U << 29)
 
133
+#define PSTATE_Z (1U << 30)
 
134
+#define PSTATE_N (1U << 31)
 
135
+#define PSTATE_NZCV (PSTATE_N | PSTATE_Z | PSTATE_C | PSTATE_V)
 
136
+#define CACHED_PSTATE_BITS (PSTATE_NZCV)
 
137
+/* Mode values for AArch64 */
 
138
+#define PSTATE_MODE_EL3h 13
 
139
+#define PSTATE_MODE_EL3t 12
 
140
+#define PSTATE_MODE_EL2h 9
 
141
+#define PSTATE_MODE_EL2t 8
 
142
+#define PSTATE_MODE_EL1h 5
 
143
+#define PSTATE_MODE_EL1t 4
 
144
+#define PSTATE_MODE_EL0t 0
 
145
+
 
146
+/* Return the current PSTATE value. For the moment we don't support 32<->64 bit
 
147
+ * interprocessing, so we don't attempt to sync with the cpsr state used by
 
148
+ * the 32 bit decoder.
 
149
+ */
 
150
+static inline uint32_t pstate_read(CPUARMState *env)
 
151
+{
 
152
+    int ZF;
 
153
+
 
154
+    ZF = (env->ZF == 0);
 
155
+    return (env->NF & 0x80000000) | (ZF << 30)
 
156
+        | (env->CF << 29) | ((env->VF & 0x80000000) >> 3)
 
157
+        | env->pstate;
 
158
+}
 
159
+
 
160
+static inline void pstate_write(CPUARMState *env, uint32_t val)
 
161
+{
 
162
+    env->ZF = (~val) & PSTATE_Z;
 
163
+    env->NF = val;
 
164
+    env->CF = (val >> 29) & 1;
 
165
+    env->VF = (val << 3) & 0x80000000;
 
166
+    env->pstate = val & ~CACHED_PSTATE_BITS;
 
167
+}
 
168
+
 
169
 /* Return the current CPSR value.  */
 
170
 uint32_t cpsr_read(CPUARMState *env);
 
171
 /* Set the CPSR.  Note that some bits of mask must be all-set or all-clear.  */
 
172
diff --git a/target-arm/gdbstub64.c b/target-arm/gdbstub64.c
 
173
index 7cb6a7c..e8a8295 100644
 
174
--- a/target-arm/gdbstub64.c
 
175
+++ b/target-arm/gdbstub64.c
 
176
@@ -37,7 +37,7 @@ int aarch64_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
 
177
         return gdb_get_reg64(mem_buf, env->pc);
 
178
         break;
 
179
     case 33:
 
180
-        return gdb_get_reg32(mem_buf, env->pstate);
 
181
+        return gdb_get_reg32(mem_buf, pstate_read(env));
 
182
     }
 
183
     /* Unknown register.  */
 
184
     return 0;
 
185
@@ -65,7 +65,7 @@ int aarch64_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
 
186
         return 8;
 
187
     case 33:
 
188
         /* CPSR */
 
189
-        env->pstate = tmp;
 
190
+        pstate_write(env, tmp);
 
191
         return 4;
 
192
     }
 
193
     /* Unknown register.  */
 
194
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
 
195
index f120088..932b601 100644
 
196
--- a/target-arm/translate-a64.c
 
197
+++ b/target-arm/translate-a64.c
 
198
@@ -67,6 +67,7 @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
 
199
 {
 
200
     ARMCPU *cpu = ARM_CPU(cs);
 
201
     CPUARMState *env = &cpu->env;
 
202
+    uint32_t psr = pstate_read(env);
 
203
     int i;
 
204
 
 
205
     cpu_fprintf(f, "PC=%016"PRIx64"  SP=%016"PRIx64"\n",
 
206
@@ -79,11 +80,12 @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
 
207
             cpu_fprintf(f, " ");
 
208
         }
 
209
     }
 
210
-    cpu_fprintf(f, "PSTATE=%c%c%c%c\n",
 
211
-        env->pstate & PSTATE_N ? 'n' : '.',
 
212
-        env->pstate & PSTATE_Z ? 'z' : '.',
 
213
-        env->pstate & PSTATE_C ? 'c' : '.',
 
214
-        env->pstate & PSTATE_V ? 'v' : '.');
 
215
+    cpu_fprintf(f, "PSTATE=%08x (flags %c%c%c%c)\n",
 
216
+                psr,
 
217
+                psr & PSTATE_N ? 'N' : '-',
 
218
+                psr & PSTATE_Z ? 'Z' : '-',
 
219
+                psr & PSTATE_C ? 'C' : '-',
 
220
+                psr & PSTATE_V ? 'V' : '-');
 
221
     cpu_fprintf(f, "\n");
 
222
 }
 
223
 
 
224
-- 
 
225
1.8.5.2
 
226