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
Родитель f3dd18d444
Коммит 7a2653612b
2 изменённых файлов: 11 добавлений и 4 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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;