diff options
author | Aurelien Jarno <aurelien@aurel32.net> | 2015-05-25 01:47:23 +0200 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2015-06-05 01:37:58 +0200 |
commit | 1f65958d9c21fd3b461f6b645e7884866313c1f3 (patch) | |
tree | 975d2480f21da2537c11a4caccb2df82f0fb8a48 /target-s390x | |
parent | 9bebf9863bd16cc824231ad71959a338dc1819ac (diff) | |
download | qemu-1f65958d9c21fd3b461f6b645e7884866313c1f3.zip qemu-1f65958d9c21fd3b461f6b645e7884866313c1f3.tar.gz qemu-1f65958d9c21fd3b461f6b645e7884866313c1f3.tar.bz2 |
target-s390x: fix MMU index computation
The cpu_mmu_index function wrongly looks at PSW P bit to determine the
MMU index, while this bit actually only control the use of priviledge
instructions. The addressing mode is detected by looking at the PSW ASC
bits instead.
This used to work more or less correctly up to kernel 3.6 as the kernel
was running in primary space and userland in secondary space. Since
kernel 3.7 the default is to run the kernel in home space and userland
in primary space. While the current QEMU code seems to work it open some
security issues, like accessing the lowcore memory in R/W mode from a
userspace process once it has been accessed by the kernel (it is then
cached by the QEMU TLB).
At the same time change the MMU_USER_IDX value so that it matches the
value used in recent kernels.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'target-s390x')
-rw-r--r-- | target-s390x/cpu.h | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index 3140f75..adb9a84 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h @@ -48,7 +48,7 @@ #define MMU_MODE1_SUFFIX _secondary #define MMU_MODE2_SUFFIX _home -#define MMU_USER_IDX 1 +#define MMU_USER_IDX 0 #define MAX_EXT_QUEUE 16 #define MAX_IO_QUEUE 16 @@ -304,11 +304,18 @@ static inline CPU_DoubleU *get_freg(CPUS390XState *cs, int nr) static inline int cpu_mmu_index (CPUS390XState *env) { - if (env->psw.mask & PSW_MASK_PSTATE) { + switch (env->psw.mask & PSW_MASK_ASC) { + case PSW_ASC_PRIMARY: + return 0; + case PSW_ASC_SECONDARY: return 1; + case PSW_ASC_HOME: + return 2; + case PSW_ASC_ACCREG: + /* Fallthrough: access register mode is not yet supported */ + default: + abort(); } - - return 0; } static inline void cpu_get_tb_cpu_state(CPUS390XState* env, target_ulong *pc, |