aboutsummaryrefslogtreecommitdiff
path: root/target/s390x/cpu.h
diff options
context:
space:
mode:
authorDavid Hildenbrand <david@redhat.com>2017-06-14 15:38:19 +0200
committerRichard Henderson <rth@twiddle.net>2017-06-23 08:40:46 -0700
commit3e7e5e0bc10d32d7cc41d0a39113473a3abfc657 (patch)
treed5385e9f8fdea4de9663176ddc0eb14298a6f2fa /target/s390x/cpu.h
parentc8bd95377babc3bd60f86cb3e5b24e74097cf6a9 (diff)
target/s390x: implement mvcos instruction
This adds support for the MOVE WITH OPTIONAL SPECIFICATIONS (MVCOS) instruction. Allow to enable it for the qemu cpu model using qemu-system-s390x ... -cpu qemu,mvcos=on ... This allows to boot linux kernel that uses it for uacccess. We are missing (as for most other part) low address protection checks, PSW key / storage key checks and support for AR-mode. We fake an ADDRESSING exception when called from problem state (which seems to rely on PSW key checks to be in place) and if AR-mode is used. user mode will always see a PRIVILEDGED exception. This patch is based on an original patch by Miroslav Benes (thanks!). Signed-off-by: David Hildenbrand <david@redhat.com> Message-Id: <20170614133819.18480-3-david@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'target/s390x/cpu.h')
-rw-r--r--target/s390x/cpu.h22
1 files changed, 21 insertions, 1 deletions
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 532a4a075c..5b94ace42c 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -304,6 +304,7 @@ void s390x_cpu_debug_excp_handler(CPUState *cs);
#undef PSW_MASK_WAIT
#undef PSW_MASK_PSTATE
#undef PSW_MASK_ASC
+#undef PSW_SHIFT_ASC
#undef PSW_MASK_CC
#undef PSW_MASK_PM
#undef PSW_MASK_64
@@ -320,6 +321,7 @@ void s390x_cpu_debug_excp_handler(CPUState *cs);
#define PSW_MASK_WAIT 0x0002000000000000ULL
#define PSW_MASK_PSTATE 0x0001000000000000ULL
#define PSW_MASK_ASC 0x0000C00000000000ULL
+#define PSW_SHIFT_ASC 46
#define PSW_MASK_CC 0x0000300000000000ULL
#define PSW_MASK_PM 0x00000F0000000000ULL
#define PSW_MASK_64 0x0000000100000000ULL
@@ -336,6 +338,12 @@ void s390x_cpu_debug_excp_handler(CPUState *cs);
#define PSW_ASC_SECONDARY 0x0000800000000000ULL
#define PSW_ASC_HOME 0x0000C00000000000ULL
+/* the address space values shifted */
+#define AS_PRIMARY 0
+#define AS_ACCREG 1
+#define AS_SECONDARY 2
+#define AS_HOME 3
+
/* tb flags */
#define FLAG_MASK_PER (PSW_MASK_PER >> 32)
@@ -354,6 +362,7 @@ void s390x_cpu_debug_excp_handler(CPUState *cs);
/* Control register 0 bits */
#define CR0_LOWPROT 0x0000000010000000ULL
+#define CR0_SECONDARY 0x0000000004000000ULL
#define CR0_EDAT 0x0000000000800000ULL
/* MMU */
@@ -361,7 +370,18 @@ void s390x_cpu_debug_excp_handler(CPUState *cs);
#define MMU_SECONDARY_IDX 1
#define MMU_HOME_IDX 2
-static inline int cpu_mmu_index (CPUS390XState *env, bool ifetch)
+static inline bool psw_key_valid(CPUS390XState *env, uint8_t psw_key)
+{
+ uint16_t pkm = env->cregs[3] >> 16;
+
+ if (env->psw.mask & PSW_MASK_PSTATE) {
+ /* PSW key has range 0..15, it is valid if the bit is 1 in the PKM */
+ return pkm & (0x80 >> psw_key);
+ }
+ return true;
+}
+
+static inline int cpu_mmu_index(CPUS390XState *env, bool ifetch)
{
switch (env->psw.mask & PSW_MASK_ASC) {
case PSW_ASC_PRIMARY: