aboutsummaryrefslogtreecommitdiff
path: root/target/s390x/tcg
diff options
context:
space:
mode:
authorDavid Hildenbrand <david@redhat.com>2021-09-03 17:55:05 +0200
committerThomas Huth <thuth@redhat.com>2021-09-06 16:24:05 +0200
commiteaa0feea7532429c3a9bec357ec4f77cb156fab0 (patch)
tree4cdb62c716adf06d53b248bda1f6276d3d7f4f19 /target/s390x/tcg
parent06d8a10a70b7ef14ebf88b874858f73f2dee1109 (diff)
downloadqemu-eaa0feea7532429c3a9bec357ec4f77cb156fab0.zip
qemu-eaa0feea7532429c3a9bec357ec4f77cb156fab0.tar.gz
qemu-eaa0feea7532429c3a9bec357ec4f77cb156fab0.tar.bz2
s390x/tcg: check for addressing exceptions for RRBE, SSKE and ISKE
Let's replace the ram_size check by a proper physical address space check (for example, to prepare for memory hotplug), trigger addressing exceptions and trace the return value of the storage key getter/setter. Provide an helper mmu_absolute_addr_valid() to be used in other context soon. Always test for "read" instead of "write" as we are not actually modifying the page itself. Signed-off-by: David Hildenbrand <david@redhat.com> Acked-by: Thomas Huth <thuth@redhat.com> Message-Id: <20210903155514.44772-5-david@redhat.com> Signed-off-by: Thomas Huth <thuth@redhat.com>
Diffstat (limited to 'target/s390x/tcg')
-rw-r--r--target/s390x/tcg/mem_helper.c36
1 files changed, 23 insertions, 13 deletions
diff --git a/target/s390x/tcg/mem_helper.c b/target/s390x/tcg/mem_helper.c
index dd506d8..a44a107 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,15 +2172,15 @@ 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;
addr = mmu_real2abs(env, addr);
- if (addr > ms->ram_size) {
- return 0;
+ if (!mmu_absolute_addr_valid(addr, false)) {
+ tcg_s390_program_interrupt(env, PGM_ADDRESSING, GETPC());
}
if (unlikely(!ss)) {
@@ -2187,7 +2188,9 @@ uint64_t HELPER(iske)(CPUS390XState *env, uint64_t r2)
skeyclass = S390_SKEYS_GET_CLASS(ss);
}
- 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;
@@ -2196,15 +2199,15 @@ 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;
addr = mmu_real2abs(env, addr);
- if (addr > ms->ram_size) {
- return;
+ if (!mmu_absolute_addr_valid(addr, false)) {
+ tcg_s390_program_interrupt(env, PGM_ADDRESSING, GETPC());
}
if (unlikely(!ss)) {
@@ -2213,7 +2216,10 @@ void HELPER(sske)(CPUS390XState *env, uint64_t r1, uint64_t r2)
}
key = r1 & 0xfe;
- skeyclass->set_skeys(ss, addr / TARGET_PAGE_SIZE, 1, &key);
+ 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.
@@ -2224,15 +2230,15 @@ 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;
addr = mmu_real2abs(env, addr);
- if (addr > ms->ram_size) {
- return 0;
+ if (!mmu_absolute_addr_valid(addr, false)) {
+ tcg_s390_program_interrupt(env, PGM_ADDRESSING, GETPC());
}
if (unlikely(!ss)) {
@@ -2240,14 +2246,18 @@ uint32_t HELPER(rrbe)(CPUS390XState *env, uint64_t r2)
skeyclass = S390_SKEYS_GET_CLASS(ss);
}
- 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;
}
re = key & (SK_R | SK_C);
key &= ~SK_R;
- if (skeyclass->set_skeys(ss, addr / 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;
}
/*