Skip to content

Commit 3ac8e38

Browse files
Dominik DingelMartin Schwidefsky
authored andcommitted
s390/mm: disable KSM for storage key enabled pages
When storage keys are enabled unmerge already merged pages and prevent new pages from being merged. Signed-off-by: Dominik Dingel <[email protected]> Acked-by: Christian Borntraeger <[email protected]> Reviewed-by: Paolo Bonzini <[email protected]> Signed-off-by: Martin Schwidefsky <[email protected]>
1 parent 2faee8f commit 3ac8e38

File tree

3 files changed

+28
-7
lines changed

3 files changed

+28
-7
lines changed

arch/s390/include/asm/pgtable.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1751,7 +1751,7 @@ static inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
17511751
extern int vmem_add_mapping(unsigned long start, unsigned long size);
17521752
extern int vmem_remove_mapping(unsigned long start, unsigned long size);
17531753
extern int s390_enable_sie(void);
1754-
extern void s390_enable_skey(void);
1754+
extern int s390_enable_skey(void);
17551755
extern void s390_reset_cmma(struct mm_struct *mm);
17561756

17571757
/*

arch/s390/kvm/priv.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,21 +156,25 @@ static int handle_store_cpu_address(struct kvm_vcpu *vcpu)
156156
return 0;
157157
}
158158

159-
static void __skey_check_enable(struct kvm_vcpu *vcpu)
159+
static int __skey_check_enable(struct kvm_vcpu *vcpu)
160160
{
161+
int rc = 0;
161162
if (!(vcpu->arch.sie_block->ictl & (ICTL_ISKE | ICTL_SSKE | ICTL_RRBE)))
162-
return;
163+
return rc;
163164

164-
s390_enable_skey();
165+
rc = s390_enable_skey();
165166
trace_kvm_s390_skey_related_inst(vcpu);
166167
vcpu->arch.sie_block->ictl &= ~(ICTL_ISKE | ICTL_SSKE | ICTL_RRBE);
168+
return rc;
167169
}
168170

169171

170172
static int handle_skey(struct kvm_vcpu *vcpu)
171173
{
172-
__skey_check_enable(vcpu);
174+
int rc = __skey_check_enable(vcpu);
173175

176+
if (rc)
177+
return rc;
174178
vcpu->stat.instruction_storage_key++;
175179

176180
if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
@@ -683,7 +687,10 @@ static int handle_pfmf(struct kvm_vcpu *vcpu)
683687
}
684688

685689
if (vcpu->run->s.regs.gprs[reg1] & PFMF_SK) {
686-
__skey_check_enable(vcpu);
690+
int rc = __skey_check_enable(vcpu);
691+
692+
if (rc)
693+
return rc;
687694
if (set_guest_storage_key(current->mm, useraddr,
688695
vcpu->run->s.regs.gprs[reg1] & PFMF_KEY,
689696
vcpu->run->s.regs.gprs[reg1] & PFMF_NQ))

arch/s390/mm/pgtable.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include <linux/rcupdate.h>
1919
#include <linux/slab.h>
2020
#include <linux/swapops.h>
21+
#include <linux/ksm.h>
22+
#include <linux/mman.h>
2123

2224
#include <asm/pgtable.h>
2325
#include <asm/pgalloc.h>
@@ -1275,22 +1277,34 @@ static int __s390_enable_skey(pte_t *pte, unsigned long addr,
12751277
return 0;
12761278
}
12771279

1278-
void s390_enable_skey(void)
1280+
int s390_enable_skey(void)
12791281
{
12801282
struct mm_walk walk = { .pte_entry = __s390_enable_skey };
12811283
struct mm_struct *mm = current->mm;
1284+
struct vm_area_struct *vma;
1285+
int rc = 0;
12821286

12831287
down_write(&mm->mmap_sem);
12841288
if (mm_use_skey(mm))
12851289
goto out_up;
12861290

12871291
mm->context.use_skey = 1;
1292+
for (vma = mm->mmap; vma; vma = vma->vm_next) {
1293+
if (ksm_madvise(vma, vma->vm_start, vma->vm_end,
1294+
MADV_UNMERGEABLE, &vma->vm_flags)) {
1295+
mm->context.use_skey = 0;
1296+
rc = -ENOMEM;
1297+
goto out_up;
1298+
}
1299+
}
1300+
mm->def_flags &= ~VM_MERGEABLE;
12881301

12891302
walk.mm = mm;
12901303
walk_page_range(0, TASK_SIZE, &walk);
12911304

12921305
out_up:
12931306
up_write(&mm->mmap_sem);
1307+
return rc;
12941308
}
12951309
EXPORT_SYMBOL_GPL(s390_enable_skey);
12961310

0 commit comments

Comments
 (0)