pfncache.c (7527B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Kernel-based Virtual Machine driver for Linux 4 * 5 * This module enables kernel and guest-mode vCPU access to guest physical 6 * memory with suitable invalidation mechanisms. 7 * 8 * Copyright © 2021 Amazon.com, Inc. or its affiliates. 9 * 10 * Authors: 11 * David Woodhouse <dwmw2@infradead.org> 12 */ 13 14#include <linux/kvm_host.h> 15#include <linux/kvm.h> 16#include <linux/highmem.h> 17#include <linux/module.h> 18#include <linux/errno.h> 19 20#include "kvm_mm.h" 21 22/* 23 * MMU notifier 'invalidate_range_start' hook. 24 */ 25void gfn_to_pfn_cache_invalidate_start(struct kvm *kvm, unsigned long start, 26 unsigned long end, bool may_block) 27{ 28 DECLARE_BITMAP(vcpu_bitmap, KVM_MAX_VCPUS); 29 struct gfn_to_pfn_cache *gpc; 30 bool evict_vcpus = false; 31 32 spin_lock(&kvm->gpc_lock); 33 list_for_each_entry(gpc, &kvm->gpc_list, list) { 34 write_lock_irq(&gpc->lock); 35 36 /* Only a single page so no need to care about length */ 37 if (gpc->valid && !is_error_noslot_pfn(gpc->pfn) && 38 gpc->uhva >= start && gpc->uhva < end) { 39 gpc->valid = false; 40 41 /* 42 * If a guest vCPU could be using the physical address, 43 * it needs to be forced out of guest mode. 44 */ 45 if (gpc->usage & KVM_GUEST_USES_PFN) { 46 if (!evict_vcpus) { 47 evict_vcpus = true; 48 bitmap_zero(vcpu_bitmap, KVM_MAX_VCPUS); 49 } 50 __set_bit(gpc->vcpu->vcpu_idx, vcpu_bitmap); 51 } 52 } 53 write_unlock_irq(&gpc->lock); 54 } 55 spin_unlock(&kvm->gpc_lock); 56 57 if (evict_vcpus) { 58 /* 59 * KVM needs to ensure the vCPU is fully out of guest context 60 * before allowing the invalidation to continue. 61 */ 62 unsigned int req = KVM_REQ_OUTSIDE_GUEST_MODE; 63 bool called; 64 65 /* 66 * If the OOM reaper is active, then all vCPUs should have 67 * been stopped already, so perform the request without 68 * KVM_REQUEST_WAIT and be sad if any needed to be IPI'd. 69 */ 70 if (!may_block) 71 req &= ~KVM_REQUEST_WAIT; 72 73 called = kvm_make_vcpus_request_mask(kvm, req, vcpu_bitmap); 74 75 WARN_ON_ONCE(called && !may_block); 76 } 77} 78 79bool kvm_gfn_to_pfn_cache_check(struct kvm *kvm, struct gfn_to_pfn_cache *gpc, 80 gpa_t gpa, unsigned long len) 81{ 82 struct kvm_memslots *slots = kvm_memslots(kvm); 83 84 if ((gpa & ~PAGE_MASK) + len > PAGE_SIZE) 85 return false; 86 87 if (gpc->gpa != gpa || gpc->generation != slots->generation || 88 kvm_is_error_hva(gpc->uhva)) 89 return false; 90 91 if (!gpc->valid) 92 return false; 93 94 return true; 95} 96EXPORT_SYMBOL_GPL(kvm_gfn_to_pfn_cache_check); 97 98static void __release_gpc(struct kvm *kvm, kvm_pfn_t pfn, void *khva, gpa_t gpa) 99{ 100 /* Unmap the old page if it was mapped before, and release it */ 101 if (!is_error_noslot_pfn(pfn)) { 102 if (khva) { 103 if (pfn_valid(pfn)) 104 kunmap(pfn_to_page(pfn)); 105#ifdef CONFIG_HAS_IOMEM 106 else 107 memunmap(khva); 108#endif 109 } 110 111 kvm_release_pfn(pfn, false); 112 } 113} 114 115static kvm_pfn_t hva_to_pfn_retry(struct kvm *kvm, unsigned long uhva) 116{ 117 unsigned long mmu_seq; 118 kvm_pfn_t new_pfn; 119 int retry; 120 121 do { 122 mmu_seq = kvm->mmu_notifier_seq; 123 smp_rmb(); 124 125 /* We always request a writeable mapping */ 126 new_pfn = hva_to_pfn(uhva, false, NULL, true, NULL); 127 if (is_error_noslot_pfn(new_pfn)) 128 break; 129 130 KVM_MMU_READ_LOCK(kvm); 131 retry = mmu_notifier_retry_hva(kvm, mmu_seq, uhva); 132 KVM_MMU_READ_UNLOCK(kvm); 133 if (!retry) 134 break; 135 136 cond_resched(); 137 } while (1); 138 139 return new_pfn; 140} 141 142int kvm_gfn_to_pfn_cache_refresh(struct kvm *kvm, struct gfn_to_pfn_cache *gpc, 143 gpa_t gpa, unsigned long len) 144{ 145 struct kvm_memslots *slots = kvm_memslots(kvm); 146 unsigned long page_offset = gpa & ~PAGE_MASK; 147 kvm_pfn_t old_pfn, new_pfn; 148 unsigned long old_uhva; 149 gpa_t old_gpa; 150 void *old_khva; 151 bool old_valid; 152 int ret = 0; 153 154 /* 155 * If must fit within a single page. The 'len' argument is 156 * only to enforce that. 157 */ 158 if (page_offset + len > PAGE_SIZE) 159 return -EINVAL; 160 161 write_lock_irq(&gpc->lock); 162 163 old_gpa = gpc->gpa; 164 old_pfn = gpc->pfn; 165 old_khva = gpc->khva - offset_in_page(gpc->khva); 166 old_uhva = gpc->uhva; 167 old_valid = gpc->valid; 168 169 /* If the userspace HVA is invalid, refresh that first */ 170 if (gpc->gpa != gpa || gpc->generation != slots->generation || 171 kvm_is_error_hva(gpc->uhva)) { 172 gfn_t gfn = gpa_to_gfn(gpa); 173 174 gpc->gpa = gpa; 175 gpc->generation = slots->generation; 176 gpc->memslot = __gfn_to_memslot(slots, gfn); 177 gpc->uhva = gfn_to_hva_memslot(gpc->memslot, gfn); 178 179 if (kvm_is_error_hva(gpc->uhva)) { 180 gpc->pfn = KVM_PFN_ERR_FAULT; 181 ret = -EFAULT; 182 goto out; 183 } 184 185 gpc->uhva += page_offset; 186 } 187 188 /* 189 * If the userspace HVA changed or the PFN was already invalid, 190 * drop the lock and do the HVA to PFN lookup again. 191 */ 192 if (!old_valid || old_uhva != gpc->uhva) { 193 unsigned long uhva = gpc->uhva; 194 void *new_khva = NULL; 195 196 /* Placeholders for "hva is valid but not yet mapped" */ 197 gpc->pfn = KVM_PFN_ERR_FAULT; 198 gpc->khva = NULL; 199 gpc->valid = true; 200 201 write_unlock_irq(&gpc->lock); 202 203 new_pfn = hva_to_pfn_retry(kvm, uhva); 204 if (is_error_noslot_pfn(new_pfn)) { 205 ret = -EFAULT; 206 goto map_done; 207 } 208 209 if (gpc->usage & KVM_HOST_USES_PFN) { 210 if (new_pfn == old_pfn) { 211 new_khva = old_khva; 212 old_pfn = KVM_PFN_ERR_FAULT; 213 old_khva = NULL; 214 } else if (pfn_valid(new_pfn)) { 215 new_khva = kmap(pfn_to_page(new_pfn)); 216#ifdef CONFIG_HAS_IOMEM 217 } else { 218 new_khva = memremap(pfn_to_hpa(new_pfn), PAGE_SIZE, MEMREMAP_WB); 219#endif 220 } 221 if (new_khva) 222 new_khva += page_offset; 223 else 224 ret = -EFAULT; 225 } 226 227 map_done: 228 write_lock_irq(&gpc->lock); 229 if (ret) { 230 gpc->valid = false; 231 gpc->pfn = KVM_PFN_ERR_FAULT; 232 gpc->khva = NULL; 233 } else { 234 /* At this point, gpc->valid may already have been cleared */ 235 gpc->pfn = new_pfn; 236 gpc->khva = new_khva; 237 } 238 } else { 239 /* If the HVA→PFN mapping was already valid, don't unmap it. */ 240 old_pfn = KVM_PFN_ERR_FAULT; 241 old_khva = NULL; 242 } 243 244 out: 245 write_unlock_irq(&gpc->lock); 246 247 __release_gpc(kvm, old_pfn, old_khva, old_gpa); 248 249 return ret; 250} 251EXPORT_SYMBOL_GPL(kvm_gfn_to_pfn_cache_refresh); 252 253void kvm_gfn_to_pfn_cache_unmap(struct kvm *kvm, struct gfn_to_pfn_cache *gpc) 254{ 255 void *old_khva; 256 kvm_pfn_t old_pfn; 257 gpa_t old_gpa; 258 259 write_lock_irq(&gpc->lock); 260 261 gpc->valid = false; 262 263 old_khva = gpc->khva - offset_in_page(gpc->khva); 264 old_gpa = gpc->gpa; 265 old_pfn = gpc->pfn; 266 267 /* 268 * We can leave the GPA → uHVA map cache intact but the PFN 269 * lookup will need to be redone even for the same page. 270 */ 271 gpc->khva = NULL; 272 gpc->pfn = KVM_PFN_ERR_FAULT; 273 274 write_unlock_irq(&gpc->lock); 275 276 __release_gpc(kvm, old_pfn, old_khva, old_gpa); 277} 278EXPORT_SYMBOL_GPL(kvm_gfn_to_pfn_cache_unmap); 279 280 281int kvm_gfn_to_pfn_cache_init(struct kvm *kvm, struct gfn_to_pfn_cache *gpc, 282 struct kvm_vcpu *vcpu, enum pfn_cache_usage usage, 283 gpa_t gpa, unsigned long len) 284{ 285 WARN_ON_ONCE(!usage || (usage & KVM_GUEST_AND_HOST_USE_PFN) != usage); 286 287 if (!gpc->active) { 288 rwlock_init(&gpc->lock); 289 290 gpc->khva = NULL; 291 gpc->pfn = KVM_PFN_ERR_FAULT; 292 gpc->uhva = KVM_HVA_ERR_BAD; 293 gpc->vcpu = vcpu; 294 gpc->usage = usage; 295 gpc->valid = false; 296 gpc->active = true; 297 298 spin_lock(&kvm->gpc_lock); 299 list_add(&gpc->list, &kvm->gpc_list); 300 spin_unlock(&kvm->gpc_lock); 301 } 302 return kvm_gfn_to_pfn_cache_refresh(kvm, gpc, gpa, len); 303} 304EXPORT_SYMBOL_GPL(kvm_gfn_to_pfn_cache_init); 305 306void kvm_gfn_to_pfn_cache_destroy(struct kvm *kvm, struct gfn_to_pfn_cache *gpc) 307{ 308 if (gpc->active) { 309 spin_lock(&kvm->gpc_lock); 310 list_del(&gpc->list); 311 spin_unlock(&kvm->gpc_lock); 312 313 kvm_gfn_to_pfn_cache_unmap(kvm, gpc); 314 gpc->active = false; 315 } 316} 317EXPORT_SYMBOL_GPL(kvm_gfn_to_pfn_cache_destroy);