From: Janosch Frank <frankja@linux.ibm.com>
Date: Tue, 16 Jul 2019 13:08:37 +0200
Subject: KVM: s390: protvirt: Secure memory is not mergeable
Git-commit: fa0c5eabbdd33012b369cf75d6a39389cc9ae707
Patch-mainline: v5.7-rc1
References: jsc#SLE-7512 bsc#1165545
KSM will not work on secure pages, because when the kernel reads a
secure page, it will be encrypted and hence no two pages will look the
same.
Let's mark the guest pages as unmergeable when we transition to secure
mode.
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
[borntraeger@de.ibm.com: patch merging, splitting, fixing]
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
arch/s390/include/asm/gmap.h | 1 +
arch/s390/kvm/kvm-s390.c | 6 ++++++
arch/s390/mm/gmap.c | 30 ++++++++++++++++++++----------
3 files changed, 27 insertions(+), 10 deletions(-)
--- a/arch/s390/include/asm/gmap.h
+++ b/arch/s390/include/asm/gmap.h
@@ -147,4 +147,5 @@ int gmap_mprotect_notify(struct gmap *,
void gmap_sync_dirty_log_pmd(struct gmap *gmap, unsigned long dirty_bitmap[4],
unsigned long gaddr, unsigned long vmaddr);
+int gmap_mark_unmergeable(void);
#endif /* _ASM_S390_GMAP_H */
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -2233,6 +2233,12 @@ static int kvm_s390_handle_pv(struct kvm
if (r)
break;
+ down_write(¤t->mm->mmap_sem);
+ r = gmap_mark_unmergeable();
+ up_write(¤t->mm->mmap_sem);
+ if (r)
+ break;
+
r = kvm_s390_pv_init_vm(kvm, &cmd->rc, &cmd->rrc);
if (r)
break;
--- a/arch/s390/mm/gmap.c
+++ b/arch/s390/mm/gmap.c
@@ -2552,6 +2552,22 @@ int s390_enable_sie(void)
}
EXPORT_SYMBOL_GPL(s390_enable_sie);
+int gmap_mark_unmergeable(void)
+{
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma;
+
+ for (vma = mm->mmap; vma; vma = vma->vm_next) {
+ if (ksm_madvise(vma, vma->vm_start, vma->vm_end,
+ MADV_UNMERGEABLE, &vma->vm_flags)) {
+ return -ENOMEM;
+ }
+ }
+ mm->def_flags &= ~VM_MERGEABLE;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(gmap_mark_unmergeable);
+
/*
* Enable storage key handling from now on and initialize the storage
* keys with the default key.
@@ -2596,7 +2612,6 @@ int s390_enable_skey(void)
.pte_entry = __s390_enable_skey_pte,
};
struct mm_struct *mm = current->mm;
- struct vm_area_struct *vma;
int rc = 0;
down_write(&mm->mmap_sem);
@@ -2604,16 +2619,11 @@ int s390_enable_skey(void)
goto out_up;
mm->context.uses_skeys = 1;
- for (vma = mm->mmap; vma; vma = vma->vm_next) {
- if (ksm_madvise(vma, vma->vm_start, vma->vm_end,
- MADV_UNMERGEABLE, &vma->vm_flags)) {
- mm->context.uses_skeys = 0;
- rc = -ENOMEM;
- goto out_up;
- }
+ rc = gmap_mark_unmergeable();
+ if (rc) {
+ mm->context.uses_skeys = 0;
+ goto out_up;
}
- mm->def_flags &= ~VM_MERGEABLE;
-
walk.mm = mm;
walk_page_range(0, TASK_SIZE, &walk);