aboutsummaryrefslogtreecommitdiff
path: root/target/s390x/tcg/mem_helper.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2021-09-07 17:46:13 +0100
committerPeter Maydell <peter.maydell@linaro.org>2021-09-07 17:46:13 +0100
commitabf7aee72ea66944a62962603e4c2381f5e473e7 (patch)
treed1ac53b1c2fc78c6b77ad3fee67b9b433f91bd0e /target/s390x/tcg/mem_helper.c
parentf9128631fbeb40a55f7bc145397981c963d40909 (diff)
parent30e398f796d882d829162a16ab7c920f7422da3b (diff)
Merge remote-tracking branch 'remotes/thuth-gitlab/tags/s390x-pull-request-2021-09-07' into staging
* Some CSS related fixes * Storage key related fixes * Test SIGILL and SIGSEGV handling in usermode emulation * Fix SETPREFIX instruction * Replace PAGE_SIZE, PAGE_SHIFT and PAGE_MASK to fix Alpine compilation * Add more feature to gen16 default model # gpg: Signature made Tue 07 Sep 2021 14:07:38 BST # gpg: using RSA key 27B88847EEE0250118F3EAB92ED9D774FE702DB5 # gpg: issuer "thuth@redhat.com" # gpg: Good signature from "Thomas Huth <th.huth@gmx.de>" [full] # gpg: aka "Thomas Huth <thuth@redhat.com>" [full] # gpg: aka "Thomas Huth <huth@tuxfamily.org>" [full] # gpg: aka "Thomas Huth <th.huth@posteo.de>" [unknown] # Primary key fingerprint: 27B8 8847 EEE0 2501 18F3 EAB9 2ED9 D774 FE70 2DB5 * remotes/thuth-gitlab/tags/s390x-pull-request-2021-09-07: s390x/cpumodel: Add more feature to gen16 default model s390x: Replace PAGE_SIZE, PAGE_SHIFT and PAGE_MASK hw/s390x/s390-skeys: lazy storage key enablement under TCG hw/s390x/s390-skeys: rename skeys_enabled to skeys_are_enabled hw/s390x/s390-skeys: check if an address is valid before dumping the key hw/s390x/s390-skeys: use memory mapping to detect which storage keys to dump hw/s390x/s390-skeys: use memory mapping to detect which storage keys to migrate s390x/mmu_helper: avoid setting the storage key if nothing changed s390x/mmu_helper: move address validation into mmu_translate*() s390x/mmu_helper: fixup mmu_translate() documentation s390x/mmu_helper: no need to pass access type to mmu_translate_asce() s390x/tcg: check for addressing exceptions for RRBE, SSKE and ISKE s390x/tcg: convert real to absolute address for RRBE, SSKE and ISKE s390x/tcg: fix ignoring bit 63 when setting the storage key in SSKE s390x/tcg: wrap address for RRBE s390x/ioinst: Fix wrong MSCH alignment check on little endian s390x/tcg: fix and optimize SPX (SET PREFIX) tests/tcg/s390x: Test SIGILL and SIGSEGV handling css: fix actl handling for unit exceptions vfio-ccw: forward halt/clear errors Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/s390x/tcg/mem_helper.c')
-rw-r--r--target/s390x/tcg/mem_helper.c53
1 files changed, 38 insertions, 15 deletions
diff --git a/target/s390x/tcg/mem_helper.c b/target/s390x/tcg/mem_helper.c
index 21a4de4067..0bf775a37d 100644
--- a/target/s390x/tcg/mem_helper.c
+++ b/target/s390x/tcg/mem_helper.c
@@ -28,6 +28,7 @@
#include "qemu/int128.h"
#include "qemu/atomic128.h"
#include "tcg/tcg.h"
+#include "trace.h"
#if !defined(CONFIG_USER_ONLY)
#include "hw/s390x/storage-keys.h"
@@ -2171,22 +2172,28 @@ uint32_t HELPER(tprot)(CPUS390XState *env, uint64_t a1, uint64_t a2)
/* insert storage key extended */
uint64_t HELPER(iske)(CPUS390XState *env, uint64_t r2)
{
- MachineState *ms = MACHINE(qdev_get_machine());
static S390SKeysState *ss;
static S390SKeysClass *skeyclass;
uint64_t addr = wrap_address(env, r2);
uint8_t key;
+ int rc;
- if (addr > ms->ram_size) {
- return 0;
+ addr = mmu_real2abs(env, addr);
+ if (!mmu_absolute_addr_valid(addr, false)) {
+ tcg_s390_program_interrupt(env, PGM_ADDRESSING, GETPC());
}
if (unlikely(!ss)) {
ss = s390_get_skeys_device();
skeyclass = S390_SKEYS_GET_CLASS(ss);
+ if (skeyclass->enable_skeys && !skeyclass->enable_skeys(ss)) {
+ tlb_flush_all_cpus_synced(env_cpu(env));
+ }
}
- if (skeyclass->get_skeys(ss, addr / TARGET_PAGE_SIZE, 1, &key)) {
+ rc = skeyclass->get_skeys(ss, addr / TARGET_PAGE_SIZE, 1, &key);
+ if (rc) {
+ trace_get_skeys_nonzero(rc);
return 0;
}
return key;
@@ -2195,23 +2202,30 @@ uint64_t HELPER(iske)(CPUS390XState *env, uint64_t r2)
/* set storage key extended */
void HELPER(sske)(CPUS390XState *env, uint64_t r1, uint64_t r2)
{
- MachineState *ms = MACHINE(qdev_get_machine());
static S390SKeysState *ss;
static S390SKeysClass *skeyclass;
uint64_t addr = wrap_address(env, r2);
uint8_t key;
+ int rc;
- if (addr > ms->ram_size) {
- return;
+ addr = mmu_real2abs(env, addr);
+ if (!mmu_absolute_addr_valid(addr, false)) {
+ tcg_s390_program_interrupt(env, PGM_ADDRESSING, GETPC());
}
if (unlikely(!ss)) {
ss = s390_get_skeys_device();
skeyclass = S390_SKEYS_GET_CLASS(ss);
+ if (skeyclass->enable_skeys && !skeyclass->enable_skeys(ss)) {
+ tlb_flush_all_cpus_synced(env_cpu(env));
+ }
}
- key = (uint8_t) r1;
- skeyclass->set_skeys(ss, addr / TARGET_PAGE_SIZE, 1, &key);
+ key = r1 & 0xfe;
+ rc = skeyclass->set_skeys(ss, addr / TARGET_PAGE_SIZE, 1, &key);
+ if (rc) {
+ trace_set_skeys_nonzero(rc);
+ }
/*
* As we can only flush by virtual address and not all the entries
* that point to a physical address we have to flush the whole TLB.
@@ -2222,28 +2236,37 @@ void HELPER(sske)(CPUS390XState *env, uint64_t r1, uint64_t r2)
/* reset reference bit extended */
uint32_t HELPER(rrbe)(CPUS390XState *env, uint64_t r2)
{
- MachineState *ms = MACHINE(qdev_get_machine());
+ uint64_t addr = wrap_address(env, r2);
static S390SKeysState *ss;
static S390SKeysClass *skeyclass;
uint8_t re, key;
+ int rc;
- if (r2 > ms->ram_size) {
- return 0;
+ addr = mmu_real2abs(env, addr);
+ if (!mmu_absolute_addr_valid(addr, false)) {
+ tcg_s390_program_interrupt(env, PGM_ADDRESSING, GETPC());
}
if (unlikely(!ss)) {
ss = s390_get_skeys_device();
skeyclass = S390_SKEYS_GET_CLASS(ss);
+ if (skeyclass->enable_skeys && !skeyclass->enable_skeys(ss)) {
+ tlb_flush_all_cpus_synced(env_cpu(env));
+ }
}
- if (skeyclass->get_skeys(ss, r2 / TARGET_PAGE_SIZE, 1, &key)) {
+ rc = skeyclass->get_skeys(ss, addr / TARGET_PAGE_SIZE, 1, &key);
+ if (rc) {
+ trace_get_skeys_nonzero(rc);
return 0;
}
re = key & (SK_R | SK_C);
key &= ~SK_R;
- if (skeyclass->set_skeys(ss, r2 / TARGET_PAGE_SIZE, 1, &key)) {
+ rc = skeyclass->set_skeys(ss, addr / TARGET_PAGE_SIZE, 1, &key);
+ if (rc) {
+ trace_set_skeys_nonzero(rc);
return 0;
}
/*
@@ -2441,7 +2464,7 @@ uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr)
tcg_s390_program_interrupt(env, PGM_SPECIAL_OP, GETPC());
}
- exc = mmu_translate(env, addr, 0, asc, &ret, &flags, &tec);
+ exc = mmu_translate(env, addr, MMU_S390_LRA, asc, &ret, &flags, &tec);
if (exc) {
cc = 3;
ret = exc | 0x80000000;