diff options
author | David Hildenbrand <david@redhat.com> | 2017-12-18 23:46:15 +0100 |
---|---|---|
committer | Cornelia Huck <cohuck@redhat.com> | 2018-01-22 11:04:52 +0100 |
commit | bb8794307252be791f1723eae47983f815882376 (patch) | |
tree | 166318699f161725c201fc9d58684c03cbf0ea28 /target/s390x | |
parent | e2d9f902378cc0b8de9bacfc9406e6c63bc236d7 (diff) | |
download | qemu-bb8794307252be791f1723eae47983f815882376.zip qemu-bb8794307252be791f1723eae47983f815882376.tar.gz qemu-bb8794307252be791f1723eae47983f815882376.tar.bz2 |
s390x/tcg: implement TEST PROTECTION
Linux uses TEST PROTECTION to sense for available memory locations.
Let's implement what we can for now (just as for the other instructions,
excluding AR mode and special protection mechanisms).
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20171218224616.21030-2-david@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Diffstat (limited to 'target/s390x')
-rw-r--r-- | target/s390x/helper.h | 2 | ||||
-rw-r--r-- | target/s390x/mem_helper.c | 41 | ||||
-rw-r--r-- | target/s390x/translate.c | 2 |
3 files changed, 41 insertions, 4 deletions
diff --git a/target/s390x/helper.h b/target/s390x/helper.h index 2f17b62..26c1b07 100644 --- a/target/s390x/helper.h +++ b/target/s390x/helper.h @@ -137,7 +137,7 @@ DEF_HELPER_FLAGS_4(lctlg, TCG_CALL_NO_WG, void, env, i32, i64, i32) DEF_HELPER_FLAGS_4(stctl, TCG_CALL_NO_WG, void, env, i32, i64, i32) DEF_HELPER_FLAGS_4(stctg, TCG_CALL_NO_WG, void, env, i32, i64, i32) DEF_HELPER_FLAGS_2(testblock, TCG_CALL_NO_WG, i32, env, i64) -DEF_HELPER_FLAGS_2(tprot, TCG_CALL_NO_RWG, i32, i64, i64) +DEF_HELPER_FLAGS_3(tprot, TCG_CALL_NO_RWG, i32, env, i64, i64) DEF_HELPER_FLAGS_2(iske, TCG_CALL_NO_RWG_SE, i64, env, i64) DEF_HELPER_FLAGS_3(sske, TCG_CALL_NO_RWG, void, env, i64, i64) DEF_HELPER_FLAGS_2(rrbe, TCG_CALL_NO_RWG, i32, env, i64) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index 2625d84..359e446 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -1717,9 +1717,46 @@ uint32_t HELPER(testblock)(CPUS390XState *env, uint64_t real_addr) return 0; } -uint32_t HELPER(tprot)(uint64_t a1, uint64_t a2) +uint32_t HELPER(tprot)(CPUS390XState *env, uint64_t a1, uint64_t a2) { - /* XXX implement */ + S390CPU *cpu = s390_env_get_cpu(env); + CPUState *cs = CPU(cpu); + + /* + * TODO: we currently don't handle all access protection types + * (including access-list and key-controlled) as well as AR mode. + */ + if (!s390_cpu_virt_mem_check_write(cpu, a1, 0, 1)) { + /* Fetching permitted; storing permitted */ + return 0; + } + switch (env->int_pgm_code) { + case PGM_PROTECTION: + /* Fetching permitted; storing not permitted */ + cs->exception_index = 0; + return 1; + case PGM_ADDRESSING: + /* Fetching not permitted; storing not permitted */ + cs->exception_index = 0; + return 2; + case PGM_ASCE_TYPE: + case PGM_REG_FIRST_TRANS: + case PGM_REG_SEC_TRANS: + case PGM_REG_THIRD_TRANS: + case PGM_SEGMENT_TRANS: + case PGM_PAGE_TRANS: + case PGM_ALET_SPEC: + case PGM_ALEN_SPEC: + case PGM_ALE_SEQ: + case PGM_ASTE_VALID: + case PGM_ASTE_SEQ: + case PGM_EXT_AUTH: + /* Translation not available */ + cs->exception_index = 0; + return 3; + } + /* any other exception is forwarded to the guest */ + s390_cpu_virt_mem_handle_exc(cpu, GETPC()); return 0; } diff --git a/target/s390x/translate.c b/target/s390x/translate.c index ac55886..df0b416 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -4532,7 +4532,7 @@ static ExitStatus op_testblock(DisasContext *s, DisasOps *o) static ExitStatus op_tprot(DisasContext *s, DisasOps *o) { - gen_helper_tprot(cc_op, o->addr1, o->in2); + gen_helper_tprot(cc_op, cpu_env, o->addr1, o->in2); set_cc_static(s); return NO_EXIT; } |