diff options
author | Paul Mackerras <paulus@ozlabs.org> | 2017-08-30 06:12:33 +0200 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2017-09-01 08:39:52 +0200 |
commit | c22435a5f3d8f85ea162ae523a6ba60a58521ba5 (patch) | |
tree | 563668ca7609494d8e4ea5cac5b2f0ae74d02dd1 /arch/powerpc/include | |
parent | powerpc: Make load/store emulation use larger memory accesses (diff) | |
download | linux-c22435a5f3d8f85ea162ae523a6ba60a58521ba5.tar.xz linux-c22435a5f3d8f85ea162ae523a6ba60a58521ba5.zip |
powerpc: Emulate FP/vector/VSX loads/stores correctly when regs not live
At present, the analyse_instr/emulate_step code checks for the
relevant MSR_FP/VEC/VSX bit being set when a FP/VMX/VSX load
or store is decoded, but doesn't recheck the bit before reading or
writing the relevant FP/VMX/VSX register in emulate_step().
Since we don't have preemption disabled, it is possible that we get
preempted between checking the MSR bit and doing the register access.
If that happened, then the registers would have been saved to the
thread_struct for the current process. Accesses to the CPU registers
would then potentially read stale values, or write values that would
never be seen by the user process.
Another way that the registers can become non-live is if a page
fault occurs when accessing user memory, and the page fault code
calls a copy routine that wants to use the VMX or VSX registers.
To fix this, the code for all the FP/VMX/VSX loads gets restructured
so that it forms an image in a local variable of the desired register
contents, then disables preemption, checks the MSR bit and either
sets the CPU register or writes the value to the thread struct.
Similarly, the code for stores checks the MSR bit, copies either the
CPU register or the thread struct to a local variable, then reenables
preemption and then copies the register image to memory.
If the instruction being emulated is in the kernel, then we must not
use the register values in the thread_struct. In this case, if the
relevant MSR enable bit is not set, then emulate_step refuses to
emulate the instruction.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/include')
-rw-r--r-- | arch/powerpc/include/asm/sstep.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/arch/powerpc/include/asm/sstep.h b/arch/powerpc/include/asm/sstep.h index 4fcc2c9a6ed5..474a99255689 100644 --- a/arch/powerpc/include/asm/sstep.h +++ b/arch/powerpc/include/asm/sstep.h @@ -119,6 +119,7 @@ union vsx_reg { unsigned long d[2]; float fp[4]; double dp[2]; + __vector128 v; }; /* |