s390/gmap: return proper error code on ksm unsharing

If a signal is pending we might return -ENOMEM instead of -EINTR.
We should propagate the proper error during KSM unsharing.
unmerge_ksm_pages returns -ERESTARTSYS on signal_pending. This gets
translated by entry.S to -EINTR. It is important to get this error
code so that userspace can retry.

To make this clearer we also add -EINTR to the documentation of the
PV_ENABLE call, which calls unmerge_ksm_pages.

Fixes: 3ac8e38015 ("s390/mm: disable KSM for storage key enabled pages")
Reviewed-by: Janosch Frank <frankja@linux.vnet.ibm.com>
Reported-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Tested-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
This commit is contained in:
Christian Borntraeger 2020-03-27 08:06:42 +01:00
parent f3dd18d444
commit 7a2653612b
2 changed files with 11 additions and 4 deletions

View File

@ -4677,6 +4677,12 @@ KVM_PV_ENABLE
command has succeeded, any CPU added via hotplug will become command has succeeded, any CPU added via hotplug will become
protected during its creation as well. protected during its creation as well.
Errors:
===== =============================
EINTR an unmasked signal is pending
===== =============================
KVM_PV_DISABLE KVM_PV_DISABLE
Deregister the VM from the Ultravisor and reclaim the memory that Deregister the VM from the Ultravisor and reclaim the memory that

View File

@ -2552,12 +2552,13 @@ int gmap_mark_unmergeable(void)
{ {
struct mm_struct *mm = current->mm; struct mm_struct *mm = current->mm;
struct vm_area_struct *vma; struct vm_area_struct *vma;
int ret;
for (vma = mm->mmap; vma; vma = vma->vm_next) { for (vma = mm->mmap; vma; vma = vma->vm_next) {
if (ksm_madvise(vma, vma->vm_start, vma->vm_end, ret = ksm_madvise(vma, vma->vm_start, vma->vm_end,
MADV_UNMERGEABLE, &vma->vm_flags)) { MADV_UNMERGEABLE, &vma->vm_flags);
return -ENOMEM; if (ret)
} return ret;
} }
mm->def_flags &= ~VM_MERGEABLE; mm->def_flags &= ~VM_MERGEABLE;
return 0; return 0;