| From f2d3155e2a6bac44d16f04415a321e8707d895c6 Mon Sep 17 00:00:00 2001 |
| From: Nico Boehr <nrb@linux.ibm.com> |
| Date: Fri, 27 Jan 2023 15:05:32 +0100 |
| Subject: KVM: s390: disable migration mode when dirty tracking is disabled |
| |
| From: Nico Boehr <nrb@linux.ibm.com> |
| |
| commit f2d3155e2a6bac44d16f04415a321e8707d895c6 upstream. |
| |
| Migration mode is a VM attribute which enables tracking of changes in |
| storage attributes (PGSTE). It assumes dirty tracking is enabled on all |
| memslots to keep a dirty bitmap of pages with changed storage attributes. |
| |
| When enabling migration mode, we currently check that dirty tracking is |
| enabled for all memslots. However, userspace can disable dirty tracking |
| without disabling migration mode. |
| |
| Since migration mode is pointless with dirty tracking disabled, disable |
| migration mode whenever userspace disables dirty tracking on any slot. |
| |
| Also update the documentation to clarify that dirty tracking must be |
| enabled when enabling migration mode, which is already enforced by the |
| code in kvm_s390_vm_start_migration(). |
| |
| Also highlight in the documentation for KVM_S390_GET_CMMA_BITS that it |
| can now fail with -EINVAL when dirty tracking is disabled while |
| migration mode is on. Move all the error codes to a table so this stays |
| readable. |
| |
| To disable migration mode, slots_lock should be held, which is taken |
| in kvm_set_memory_region() and thus held in |
| kvm_arch_prepare_memory_region(). |
| |
| Restructure the prepare code a bit so all the sanity checking is done |
| before disabling migration mode. This ensures migration mode isn't |
| disabled when some sanity check fails. |
| |
| Cc: stable@vger.kernel.org |
| Fixes: 190df4a212a7 ("KVM: s390: CMMA tracking, ESSA emulation, migration mode") |
| Signed-off-by: Nico Boehr <nrb@linux.ibm.com> |
| Reviewed-by: Janosch Frank <frankja@linux.ibm.com> |
| Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com> |
| Link: https://lore.kernel.org/r/20230127140532.230651-2-nrb@linux.ibm.com |
| Message-Id: <20230127140532.230651-2-nrb@linux.ibm.com> |
| [frankja@linux.ibm.com: fixed commit message typo, moved api.rst error table upwards] |
| Signed-off-by: Janosch Frank <frankja@linux.ibm.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| Documentation/virt/kvm/api.txt | 18 ++++++++++++------ |
| Documentation/virt/kvm/devices/vm.txt | 4 ++++ |
| arch/s390/kvm/kvm-s390.c | 16 ++++++++++++++++ |
| 3 files changed, 32 insertions(+), 6 deletions(-) |
| |
| --- a/Documentation/virt/kvm/api.txt |
| +++ b/Documentation/virt/kvm/api.txt |
| @@ -3615,6 +3615,18 @@ Type: vm ioctl |
| Parameters: struct kvm_s390_cmma_log (in, out) |
| Returns: 0 on success, a negative value on error |
| |
| +Errors: |
| + |
| + ====== ============================================================= |
| + ENOMEM not enough memory can be allocated to complete the task |
| + ENXIO if CMMA is not enabled |
| + EINVAL if KVM_S390_CMMA_PEEK is not set but migration mode was not enabled |
| + EINVAL if KVM_S390_CMMA_PEEK is not set but dirty tracking has been |
| + disabled (and thus migration mode was automatically disabled) |
| + EFAULT if the userspace address is invalid or if no page table is |
| + present for the addresses (e.g. when using hugepages). |
| + ====== ============================================================= |
| + |
| This ioctl is used to get the values of the CMMA bits on the s390 |
| architecture. It is meant to be used in two scenarios: |
| - During live migration to save the CMMA values. Live migration needs |
| @@ -3691,12 +3703,6 @@ mask is unused. |
| |
| values points to the userspace buffer where the result will be stored. |
| |
| -This ioctl can fail with -ENOMEM if not enough memory can be allocated to |
| -complete the task, with -ENXIO if CMMA is not enabled, with -EINVAL if |
| -KVM_S390_CMMA_PEEK is not set but migration mode was not enabled, with |
| --EFAULT if the userspace address is invalid or if no page table is |
| -present for the addresses (e.g. when using hugepages). |
| - |
| 4.108 KVM_S390_SET_CMMA_BITS |
| |
| Capability: KVM_CAP_S390_CMMA_MIGRATION |
| --- a/Documentation/virt/kvm/devices/vm.txt |
| +++ b/Documentation/virt/kvm/devices/vm.txt |
| @@ -254,6 +254,10 @@ Allows userspace to start migration mode |
| Setting this attribute when migration mode is already active will have |
| no effects. |
| |
| +Dirty tracking must be enabled on all memslots, else -EINVAL is returned. When |
| +dirty tracking is disabled on any memslot, migration mode is automatically |
| +stopped. |
| + |
| Parameters: none |
| Returns: -ENOMEM if there is not enough free memory to start migration mode |
| -EINVAL if the state of the VM is invalid (e.g. no memory defined) |
| --- a/arch/s390/kvm/kvm-s390.c |
| +++ b/arch/s390/kvm/kvm-s390.c |
| @@ -4527,6 +4527,22 @@ int kvm_arch_prepare_memory_region(struc |
| if (mem->guest_phys_addr + mem->memory_size > kvm->arch.mem_limit) |
| return -EINVAL; |
| |
| + if (!kvm->arch.migration_mode) |
| + return 0; |
| + |
| + /* |
| + * Turn off migration mode when: |
| + * - userspace creates a new memslot with dirty logging off, |
| + * - userspace modifies an existing memslot (MOVE or FLAGS_ONLY) and |
| + * dirty logging is turned off. |
| + * Migration mode expects dirty page logging being enabled to store |
| + * its dirty bitmap. |
| + */ |
| + if (change != KVM_MR_DELETE && |
| + !(mem->flags & KVM_MEM_LOG_DIRTY_PAGES)) |
| + WARN(kvm_s390_vm_stop_migration(kvm), |
| + "Failed to stop migration mode"); |
| + |
| return 0; |
| } |
| |