diff options
author | Christian Borntraeger <borntraeger@de.ibm.com> | 2017-07-06 10:12:58 +0200 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2017-07-13 11:28:29 +0200 |
commit | 97ca7bfc19605bc08e9183441b8b8545e84032d6 (patch) | |
tree | 0fc4bc83a0028e464791c35709aabc36eb3feb21 /arch | |
parent | 2daace78a8c94e2cd20164b8efc18171c56e92ec (diff) | |
download | linux-stable-97ca7bfc19605bc08e9183441b8b8545e84032d6.tar.gz linux-stable-97ca7bfc19605bc08e9183441b8b8545e84032d6.tar.bz2 linux-stable-97ca7bfc19605bc08e9183441b8b8545e84032d6.zip |
s390/mm: set change and reference bit on lazy key enablement
When we enable storage keys for a guest lazily, we reset the ACC and F
values. That is correct assuming that these are 0 on a clear reset and
the guest obviously has not used any key setting instruction.
We also zero out the change and reference bit. This is not correct as
the architecture prefers over-indication instead of under-indication
for the keyless->keyed transition.
This patch fixes the behaviour and always sets guest change and guest
reference for all guest storage keys on the keyless -> keyed switch.
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/s390/mm/pgtable.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index d4d409ba206b..4a1f7366b17a 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -591,11 +591,11 @@ void ptep_zap_key(struct mm_struct *mm, unsigned long addr, pte_t *ptep) unsigned long ptev; pgste_t pgste; - /* Clear storage key */ + /* Clear storage key ACC and F, but set R/C */ preempt_disable(); pgste = pgste_get_lock(ptep); - pgste_val(pgste) &= ~(PGSTE_ACC_BITS | PGSTE_FP_BIT | - PGSTE_GR_BIT | PGSTE_GC_BIT); + pgste_val(pgste) &= ~(PGSTE_ACC_BITS | PGSTE_FP_BIT); + pgste_val(pgste) |= PGSTE_GR_BIT | PGSTE_GC_BIT; ptev = pte_val(*ptep); if (!(ptev & _PAGE_INVALID) && (ptev & _PAGE_WRITE)) page_set_storage_key(ptev & PAGE_MASK, PAGE_DEFAULT_KEY, 1); |