s390x/mmu: Better storage key reference and change bit handling

Any access sets the reference bit. In case we have a read-fault, we
should not allow writes to the TLB entry if the change bit was not
already set.

This is a preparation for proper storage-key reference/change bit handling
in TCG and a fix for KVM whereby read accesses would set the change
bit (old KVM versions without the ioctl to carry out the translation).

Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190816084708.602-6-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
This commit is contained in:
David Hildenbrand 2019-08-16 10:47:07 +02:00 committed by Cornelia Huck
parent 5b773a1107
commit 2d3bb388ad

View File

@ -421,13 +421,27 @@ nodat:
return 0;
}
if (*flags & PAGE_READ) {
key |= SK_R;
switch (rw) {
case MMU_DATA_LOAD:
case MMU_INST_FETCH:
/*
* The TLB entry has to remain write-protected on read-faults if
* the storage key does not indicate a change already. Otherwise
* we might miss setting the change bit on write accesses.
*/
if (!(key & SK_C)) {
*flags &= ~PAGE_WRITE;
}
break;
case MMU_DATA_STORE:
key |= SK_C;
break;
default:
g_assert_not_reached();
}
if (*flags & PAGE_WRITE) {
key |= SK_C;
}
/* Any store/fetch sets the reference bit */
key |= SK_R;
r = skeyclass->set_skeys(ss, *raddr / TARGET_PAGE_SIZE, 1, &key);
if (r) {