1 // SPDX-License-Identifier: GPL-2.0 2 3 #include <linux/kvm_types.h> 4 #include <linux/kvm_host.h> 5 6 #include "s390.h" 7 #include "gmap.h" 8 #include "dat.h" 9 #include "kvm_mmu.h" 10 11 /* 12 * Get (and clear) the dirty memory log for a memory slot. 13 */ 14 int s390_kvm_mmu_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log) 15 { 16 int r; 17 unsigned long n; 18 struct kvm_memory_slot *memslot; 19 int is_dirty; 20 21 if (kvm_is_ucontrol(kvm)) 22 return -EINVAL; 23 24 mutex_lock(&kvm->slots_lock); 25 26 r = -EINVAL; 27 if (log->slot >= KVM_USER_MEM_SLOTS) 28 goto out; 29 30 r = kvm_get_dirty_log(kvm, log, &is_dirty, &memslot); 31 if (r) 32 goto out; 33 34 /* Clear the dirty log */ 35 if (is_dirty) { 36 n = kvm_dirty_bitmap_bytes(memslot); 37 memset(memslot->dirty_bitmap, 0, n); 38 } 39 r = 0; 40 out: 41 mutex_unlock(&kvm->slots_lock); 42 return r; 43 } 44 45 int s390_kvm_mmu_prepare_memory_region(struct kvm *kvm, 46 const struct kvm_memory_slot *old, 47 struct kvm_memory_slot *new, 48 enum kvm_mr_change change) 49 { 50 if (kvm_is_ucontrol(kvm) && new && new->id < KVM_USER_MEM_SLOTS) 51 return -EINVAL; 52 53 /* When we are protected, we should not change the memory slots */ 54 if (kvm_s390_pv_get_handle(kvm)) 55 return -EINVAL; 56 57 if (change != KVM_MR_DELETE && change != KVM_MR_FLAGS_ONLY) { 58 /* 59 * A few sanity checks. The memory in userland is ok to be 60 * fragmented into various different vmas. It is okay to mmap() 61 * and munmap() stuff in this slot after doing this call at any 62 * time. 63 */ 64 if (new->userspace_addr & ~PAGE_MASK) 65 return -EINVAL; 66 if ((new->base_gfn + new->npages) * PAGE_SIZE > kvm->arch.mem_limit) 67 return -EINVAL; 68 if (!asce_contains_gfn(kvm->arch.gmap->asce, new->base_gfn + new->npages - 1)) 69 return -EINVAL; 70 } 71 72 if (!kvm_s390_is_migration_mode(kvm)) 73 return 0; 74 75 /* 76 * Turn off migration mode when: 77 * - userspace creates a new memslot with dirty logging off, 78 * - userspace modifies an existing memslot (MOVE or FLAGS_ONLY) and 79 * dirty logging is turned off. 80 * Migration mode expects dirty page logging being enabled to store 81 * its dirty bitmap. 82 */ 83 if (change != KVM_MR_DELETE && 84 !(new->flags & KVM_MEM_LOG_DIRTY_PAGES)) 85 WARN(kvm_s390_vm_stop_migration(kvm), 86 "Failed to stop migration mode"); 87 88 return 0; 89 } 90 91 void s390_kvm_mmu_commit_memory_region(struct kvm *kvm, 92 struct kvm_memory_slot *old, 93 const struct kvm_memory_slot *new, 94 enum kvm_mr_change change) 95 { 96 struct kvm_s390_mmu_cache *mc __free(kvm_s390_mmu_cache) = NULL; 97 int rc = 0; 98 99 guard(mutex)(&kvm->slots_arch_lock); 100 101 if (change == KVM_MR_FLAGS_ONLY) 102 return; 103 104 mc = kvm_s390_new_mmu_cache(); 105 if (!mc) { 106 rc = -ENOMEM; 107 goto out; 108 } 109 110 scoped_guard(write_lock, &kvm->mmu_lock) { 111 kvm_s390_update_cmma_dirty(kvm, old); 112 switch (change) { 113 case KVM_MR_DELETE: 114 rc = dat_delete_slot(mc, kvm->arch.gmap->asce, old->base_gfn, old->npages); 115 break; 116 case KVM_MR_MOVE: 117 rc = dat_delete_slot(mc, kvm->arch.gmap->asce, old->base_gfn, old->npages); 118 if (rc) 119 break; 120 fallthrough; 121 case KVM_MR_CREATE: 122 rc = dat_create_slot(mc, kvm->arch.gmap->asce, new->base_gfn, new->npages); 123 break; 124 case KVM_MR_FLAGS_ONLY: 125 break; 126 default: 127 WARN(1, "Unknown KVM MR CHANGE: %d\n", change); 128 } 129 } 130 out: 131 if (rc) 132 pr_warn("failed to commit memory region\n"); 133 } 134