1ca9f4942SBharata B Rao // SPDX-License-Identifier: GPL-2.0 2ca9f4942SBharata B Rao /* 3ca9f4942SBharata B Rao * Secure pages management: Migration of pages between normal and secure 4ca9f4942SBharata B Rao * memory of KVM guests. 5ca9f4942SBharata B Rao * 6ca9f4942SBharata B Rao * Copyright 2018 Bharata B Rao, IBM Corp. <bharata@linux.ibm.com> 7ca9f4942SBharata B Rao */ 8ca9f4942SBharata B Rao 9ca9f4942SBharata B Rao /* 10ca9f4942SBharata B Rao * A pseries guest can be run as secure guest on Ultravisor-enabled 11ca9f4942SBharata B Rao * POWER platforms. On such platforms, this driver will be used to manage 12ca9f4942SBharata B Rao * the movement of guest pages between the normal memory managed by 13ca9f4942SBharata B Rao * hypervisor (HV) and secure memory managed by Ultravisor (UV). 14ca9f4942SBharata B Rao * 15ca9f4942SBharata B Rao * The page-in or page-out requests from UV will come to HV as hcalls and 16ca9f4942SBharata B Rao * HV will call back into UV via ultracalls to satisfy these page requests. 17ca9f4942SBharata B Rao * 18ca9f4942SBharata B Rao * Private ZONE_DEVICE memory equal to the amount of secure memory 19ca9f4942SBharata B Rao * available in the platform for running secure guests is hotplugged. 20ca9f4942SBharata B Rao * Whenever a page belonging to the guest becomes secure, a page from this 21ca9f4942SBharata B Rao * private device memory is used to represent and track that secure page 2260f0a643SBharata B Rao * on the HV side. Some pages (like virtio buffers, VPA pages etc) are 2360f0a643SBharata B Rao * shared between UV and HV. However such pages aren't represented by 2460f0a643SBharata B Rao * device private memory and mappings to shared memory exist in both 2560f0a643SBharata B Rao * UV and HV page tables. 26ca9f4942SBharata B Rao */ 27ca9f4942SBharata B Rao 28ca9f4942SBharata B Rao /* 29ca9f4942SBharata B Rao * Notes on locking 30ca9f4942SBharata B Rao * 31ca9f4942SBharata B Rao * kvm->arch.uvmem_lock is a per-guest lock that prevents concurrent 32ca9f4942SBharata B Rao * page-in and page-out requests for the same GPA. Concurrent accesses 33ca9f4942SBharata B Rao * can either come via UV (guest vCPUs requesting for same page) 34ca9f4942SBharata B Rao * or when HV and guest simultaneously access the same page. 35ca9f4942SBharata B Rao * This mutex serializes the migration of page from HV(normal) to 36ca9f4942SBharata B Rao * UV(secure) and vice versa. So the serialization points are around 37ca9f4942SBharata B Rao * migrate_vma routines and page-in/out routines. 38ca9f4942SBharata B Rao * 39ca9f4942SBharata B Rao * Per-guest mutex comes with a cost though. Mainly it serializes the 40ca9f4942SBharata B Rao * fault path as page-out can occur when HV faults on accessing secure 41ca9f4942SBharata B Rao * guest pages. Currently UV issues page-in requests for all the guest 42ca9f4942SBharata B Rao * PFNs one at a time during early boot (UV_ESM uvcall), so this is 43ca9f4942SBharata B Rao * not a cause for concern. Also currently the number of page-outs caused 44ca9f4942SBharata B Rao * by HV touching secure pages is very very low. If an when UV supports 45ca9f4942SBharata B Rao * overcommitting, then we might see concurrent guest driven page-outs. 46ca9f4942SBharata B Rao * 47ca9f4942SBharata B Rao * Locking order 48ca9f4942SBharata B Rao * 49ca9f4942SBharata B Rao * 1. kvm->srcu - Protects KVM memslots 50c1e8d7c6SMichel Lespinasse * 2. kvm->mm->mmap_lock - find_vma, migrate_vma_pages and helpers, ksm_madvise 51ca9f4942SBharata B Rao * 3. kvm->arch.uvmem_lock - protects read/writes to uvmem slots thus acting 52ca9f4942SBharata B Rao * as sync-points for page-in/out 53ca9f4942SBharata B Rao */ 54ca9f4942SBharata B Rao 55ca9f4942SBharata B Rao /* 56ca9f4942SBharata B Rao * Notes on page size 57ca9f4942SBharata B Rao * 58ca9f4942SBharata B Rao * Currently UV uses 2MB mappings internally, but will issue H_SVM_PAGE_IN 59ca9f4942SBharata B Rao * and H_SVM_PAGE_OUT hcalls in PAGE_SIZE(64K) granularity. HV tracks 60ca9f4942SBharata B Rao * secure GPAs at 64K page size and maintains one device PFN for each 61ca9f4942SBharata B Rao * 64K secure GPA. UV_PAGE_IN and UV_PAGE_OUT calls by HV are also issued 62ca9f4942SBharata B Rao * for 64K page at a time. 63ca9f4942SBharata B Rao * 64ca9f4942SBharata B Rao * HV faulting on secure pages: When HV touches any secure page, it 65ca9f4942SBharata B Rao * faults and issues a UV_PAGE_OUT request with 64K page size. Currently 66ca9f4942SBharata B Rao * UV splits and remaps the 2MB page if necessary and copies out the 67ca9f4942SBharata B Rao * required 64K page contents. 68ca9f4942SBharata B Rao * 6960f0a643SBharata B Rao * Shared pages: Whenever guest shares a secure page, UV will split and 7060f0a643SBharata B Rao * remap the 2MB page if required and issue H_SVM_PAGE_IN with 64K page size. 7160f0a643SBharata B Rao * 72008e359cSBharata B Rao * HV invalidating a page: When a regular page belonging to secure 73008e359cSBharata B Rao * guest gets unmapped, HV informs UV with UV_PAGE_INVAL of 64K 74008e359cSBharata B Rao * page size. Using 64K page size is correct here because any non-secure 75008e359cSBharata B Rao * page will essentially be of 64K page size. Splitting by UV during sharing 76008e359cSBharata B Rao * and page-out ensures this. 77008e359cSBharata B Rao * 78008e359cSBharata B Rao * Page fault handling: When HV handles page fault of a page belonging 79008e359cSBharata B Rao * to secure guest, it sends that to UV with a 64K UV_PAGE_IN request. 80008e359cSBharata B Rao * Using 64K size is correct here too as UV would have split the 2MB page 81008e359cSBharata B Rao * into 64k mappings and would have done page-outs earlier. 82008e359cSBharata B Rao * 83ca9f4942SBharata B Rao * In summary, the current secure pages handling code in HV assumes 84ca9f4942SBharata B Rao * 64K page size and in fact fails any page-in/page-out requests of 85ca9f4942SBharata B Rao * non-64K size upfront. If and when UV starts supporting multiple 86ca9f4942SBharata B Rao * page-sizes, we need to break this assumption. 87ca9f4942SBharata B Rao */ 88ca9f4942SBharata B Rao 89ca9f4942SBharata B Rao #include <linux/pagemap.h> 90ca9f4942SBharata B Rao #include <linux/migrate.h> 91ca9f4942SBharata B Rao #include <linux/kvm_host.h> 92ca9f4942SBharata B Rao #include <linux/ksm.h> 9313a9a5d1SMarc Zyngier #include <linux/of.h> 94ca9f4942SBharata B Rao #include <asm/ultravisor.h> 95ca9f4942SBharata B Rao #include <asm/mman.h> 96ca9f4942SBharata B Rao #include <asm/kvm_ppc.h> 97dfaa973aSRam Pai #include <asm/kvm_book3s_uvmem.h> 98ca9f4942SBharata B Rao 99ca9f4942SBharata B Rao static struct dev_pagemap kvmppc_uvmem_pgmap; 100ca9f4942SBharata B Rao static unsigned long *kvmppc_uvmem_bitmap; 101ca9f4942SBharata B Rao static DEFINE_SPINLOCK(kvmppc_uvmem_bitmap_lock); 102ca9f4942SBharata B Rao 103651a6310SRam Pai /* 104651a6310SRam Pai * States of a GFN 105651a6310SRam Pai * --------------- 106651a6310SRam Pai * The GFN can be in one of the following states. 107651a6310SRam Pai * 108651a6310SRam Pai * (a) Secure - The GFN is secure. The GFN is associated with 109651a6310SRam Pai * a Secure VM, the contents of the GFN is not accessible 110651a6310SRam Pai * to the Hypervisor. This GFN can be backed by a secure-PFN, 111651a6310SRam Pai * or can be backed by a normal-PFN with contents encrypted. 112651a6310SRam Pai * The former is true when the GFN is paged-in into the 113651a6310SRam Pai * ultravisor. The latter is true when the GFN is paged-out 114651a6310SRam Pai * of the ultravisor. 115651a6310SRam Pai * 116651a6310SRam Pai * (b) Shared - The GFN is shared. The GFN is associated with a 117651a6310SRam Pai * a secure VM. The contents of the GFN is accessible to 118651a6310SRam Pai * Hypervisor. This GFN is backed by a normal-PFN and its 119651a6310SRam Pai * content is un-encrypted. 120651a6310SRam Pai * 121651a6310SRam Pai * (c) Normal - The GFN is a normal. The GFN is associated with 122651a6310SRam Pai * a normal VM. The contents of the GFN is accesible to 123651a6310SRam Pai * the Hypervisor. Its content is never encrypted. 124651a6310SRam Pai * 125651a6310SRam Pai * States of a VM. 126651a6310SRam Pai * --------------- 127651a6310SRam Pai * 128651a6310SRam Pai * Normal VM: A VM whose contents are always accessible to 129651a6310SRam Pai * the hypervisor. All its GFNs are normal-GFNs. 130651a6310SRam Pai * 131651a6310SRam Pai * Secure VM: A VM whose contents are not accessible to the 132651a6310SRam Pai * hypervisor without the VM's consent. Its GFNs are 133651a6310SRam Pai * either Shared-GFN or Secure-GFNs. 134651a6310SRam Pai * 135651a6310SRam Pai * Transient VM: A Normal VM that is transitioning to secure VM. 136651a6310SRam Pai * The transition starts on successful return of 137651a6310SRam Pai * H_SVM_INIT_START, and ends on successful return 138651a6310SRam Pai * of H_SVM_INIT_DONE. This transient VM, can have GFNs 139651a6310SRam Pai * in any of the three states; i.e Secure-GFN, Shared-GFN, 140651a6310SRam Pai * and Normal-GFN. The VM never executes in this state 141651a6310SRam Pai * in supervisor-mode. 142651a6310SRam Pai * 143651a6310SRam Pai * Memory slot State. 144651a6310SRam Pai * ----------------------------- 145651a6310SRam Pai * The state of a memory slot mirrors the state of the 146651a6310SRam Pai * VM the memory slot is associated with. 147651a6310SRam Pai * 148651a6310SRam Pai * VM State transition. 149651a6310SRam Pai * -------------------- 150651a6310SRam Pai * 151651a6310SRam Pai * A VM always starts in Normal Mode. 152651a6310SRam Pai * 153651a6310SRam Pai * H_SVM_INIT_START moves the VM into transient state. During this 154651a6310SRam Pai * time the Ultravisor may request some of its GFNs to be shared or 155651a6310SRam Pai * secured. So its GFNs can be in one of the three GFN states. 156651a6310SRam Pai * 157651a6310SRam Pai * H_SVM_INIT_DONE moves the VM entirely from transient state to 158651a6310SRam Pai * secure-state. At this point any left-over normal-GFNs are 159651a6310SRam Pai * transitioned to Secure-GFN. 160651a6310SRam Pai * 161651a6310SRam Pai * H_SVM_INIT_ABORT moves the transient VM back to normal VM. 162651a6310SRam Pai * All its GFNs are moved to Normal-GFNs. 163651a6310SRam Pai * 164651a6310SRam Pai * UV_TERMINATE transitions the secure-VM back to normal-VM. All 165651a6310SRam Pai * the secure-GFN and shared-GFNs are tranistioned to normal-GFN 166651a6310SRam Pai * Note: The contents of the normal-GFN is undefined at this point. 167651a6310SRam Pai * 168651a6310SRam Pai * GFN state implementation: 169651a6310SRam Pai * ------------------------- 170651a6310SRam Pai * 171651a6310SRam Pai * Secure GFN is associated with a secure-PFN; also called uvmem_pfn, 172651a6310SRam Pai * when the GFN is paged-in. Its pfn[] has KVMPPC_GFN_UVMEM_PFN flag 173651a6310SRam Pai * set, and contains the value of the secure-PFN. 174651a6310SRam Pai * It is associated with a normal-PFN; also called mem_pfn, when 175651a6310SRam Pai * the GFN is pagedout. Its pfn[] has KVMPPC_GFN_MEM_PFN flag set. 176651a6310SRam Pai * The value of the normal-PFN is not tracked. 177651a6310SRam Pai * 178651a6310SRam Pai * Shared GFN is associated with a normal-PFN. Its pfn[] has 179651a6310SRam Pai * KVMPPC_UVMEM_SHARED_PFN flag set. The value of the normal-PFN 180651a6310SRam Pai * is not tracked. 181651a6310SRam Pai * 182651a6310SRam Pai * Normal GFN is associated with normal-PFN. Its pfn[] has 183651a6310SRam Pai * no flag set. The value of the normal-PFN is not tracked. 184651a6310SRam Pai * 185651a6310SRam Pai * Life cycle of a GFN 186651a6310SRam Pai * -------------------- 187651a6310SRam Pai * 188651a6310SRam Pai * -------------------------------------------------------------- 189651a6310SRam Pai * | | Share | Unshare | SVM |H_SVM_INIT_DONE| 190651a6310SRam Pai * | |operation |operation | abort/ | | 191651a6310SRam Pai * | | | | terminate | | 192651a6310SRam Pai * ------------------------------------------------------------- 193651a6310SRam Pai * | | | | | | 194651a6310SRam Pai * | Secure | Shared | Secure |Normal |Secure | 195651a6310SRam Pai * | | | | | | 196651a6310SRam Pai * | Shared | Shared | Secure |Normal |Shared | 197651a6310SRam Pai * | | | | | | 198651a6310SRam Pai * | Normal | Shared | Secure |Normal |Secure | 199651a6310SRam Pai * -------------------------------------------------------------- 200651a6310SRam Pai * 201651a6310SRam Pai * Life cycle of a VM 202651a6310SRam Pai * -------------------- 203651a6310SRam Pai * 204651a6310SRam Pai * -------------------------------------------------------------------- 205651a6310SRam Pai * | | start | H_SVM_ |H_SVM_ |H_SVM_ |UV_SVM_ | 206651a6310SRam Pai * | | VM |INIT_START|INIT_DONE|INIT_ABORT |TERMINATE | 207651a6310SRam Pai * | | | | | | | 208651a6310SRam Pai * --------- ---------------------------------------------------------- 209651a6310SRam Pai * | | | | | | | 210651a6310SRam Pai * | Normal | Normal | Transient|Error |Error |Normal | 211651a6310SRam Pai * | | | | | | | 212651a6310SRam Pai * | Secure | Error | Error |Error |Error |Normal | 213651a6310SRam Pai * | | | | | | | 214651a6310SRam Pai * |Transient| N/A | Error |Secure |Normal |Normal | 215651a6310SRam Pai * -------------------------------------------------------------------- 216651a6310SRam Pai */ 217651a6310SRam Pai 218651a6310SRam Pai #define KVMPPC_GFN_UVMEM_PFN (1UL << 63) 219651a6310SRam Pai #define KVMPPC_GFN_MEM_PFN (1UL << 62) 220651a6310SRam Pai #define KVMPPC_GFN_SHARED (1UL << 61) 221651a6310SRam Pai #define KVMPPC_GFN_SECURE (KVMPPC_GFN_UVMEM_PFN | KVMPPC_GFN_MEM_PFN) 222651a6310SRam Pai #define KVMPPC_GFN_FLAG_MASK (KVMPPC_GFN_SECURE | KVMPPC_GFN_SHARED) 223651a6310SRam Pai #define KVMPPC_GFN_PFN_MASK (~KVMPPC_GFN_FLAG_MASK) 224ca9f4942SBharata B Rao 225ca9f4942SBharata B Rao struct kvmppc_uvmem_slot { 226ca9f4942SBharata B Rao struct list_head list; 227ca9f4942SBharata B Rao unsigned long nr_pfns; 228ca9f4942SBharata B Rao unsigned long base_pfn; 229ca9f4942SBharata B Rao unsigned long *pfns; 230ca9f4942SBharata B Rao }; 231ca9f4942SBharata B Rao struct kvmppc_uvmem_page_pvt { 232ca9f4942SBharata B Rao struct kvm *kvm; 233ca9f4942SBharata B Rao unsigned long gpa; 23460f0a643SBharata B Rao bool skip_page_out; 235651a6310SRam Pai bool remove_gfn; 236ca9f4942SBharata B Rao }; 237ca9f4942SBharata B Rao 2389a5788c6SPaul Mackerras bool kvmppc_uvmem_available(void) 2399a5788c6SPaul Mackerras { 2409a5788c6SPaul Mackerras /* 2419a5788c6SPaul Mackerras * If kvmppc_uvmem_bitmap != NULL, then there is an ultravisor 2429a5788c6SPaul Mackerras * and our data structures have been initialized successfully. 2439a5788c6SPaul Mackerras */ 2449a5788c6SPaul Mackerras return !!kvmppc_uvmem_bitmap; 2459a5788c6SPaul Mackerras } 2469a5788c6SPaul Mackerras 247ca9f4942SBharata B Rao int kvmppc_uvmem_slot_init(struct kvm *kvm, const struct kvm_memory_slot *slot) 248ca9f4942SBharata B Rao { 249ca9f4942SBharata B Rao struct kvmppc_uvmem_slot *p; 250ca9f4942SBharata B Rao 251ca9f4942SBharata B Rao p = kzalloc(sizeof(*p), GFP_KERNEL); 252ca9f4942SBharata B Rao if (!p) 253ca9f4942SBharata B Rao return -ENOMEM; 254ca9f4942SBharata B Rao p->pfns = vzalloc(array_size(slot->npages, sizeof(*p->pfns))); 255ca9f4942SBharata B Rao if (!p->pfns) { 256ca9f4942SBharata B Rao kfree(p); 257ca9f4942SBharata B Rao return -ENOMEM; 258ca9f4942SBharata B Rao } 259ca9f4942SBharata B Rao p->nr_pfns = slot->npages; 260ca9f4942SBharata B Rao p->base_pfn = slot->base_gfn; 261ca9f4942SBharata B Rao 262ca9f4942SBharata B Rao mutex_lock(&kvm->arch.uvmem_lock); 263ca9f4942SBharata B Rao list_add(&p->list, &kvm->arch.uvmem_pfns); 264ca9f4942SBharata B Rao mutex_unlock(&kvm->arch.uvmem_lock); 265ca9f4942SBharata B Rao 266ca9f4942SBharata B Rao return 0; 267ca9f4942SBharata B Rao } 268ca9f4942SBharata B Rao 269ca9f4942SBharata B Rao /* 270ca9f4942SBharata B Rao * All device PFNs are already released by the time we come here. 271ca9f4942SBharata B Rao */ 272ca9f4942SBharata B Rao void kvmppc_uvmem_slot_free(struct kvm *kvm, const struct kvm_memory_slot *slot) 273ca9f4942SBharata B Rao { 274ca9f4942SBharata B Rao struct kvmppc_uvmem_slot *p, *next; 275ca9f4942SBharata B Rao 276ca9f4942SBharata B Rao mutex_lock(&kvm->arch.uvmem_lock); 277ca9f4942SBharata B Rao list_for_each_entry_safe(p, next, &kvm->arch.uvmem_pfns, list) { 278ca9f4942SBharata B Rao if (p->base_pfn == slot->base_gfn) { 279ca9f4942SBharata B Rao vfree(p->pfns); 280ca9f4942SBharata B Rao list_del(&p->list); 281ca9f4942SBharata B Rao kfree(p); 282ca9f4942SBharata B Rao break; 283ca9f4942SBharata B Rao } 284ca9f4942SBharata B Rao } 285ca9f4942SBharata B Rao mutex_unlock(&kvm->arch.uvmem_lock); 286ca9f4942SBharata B Rao } 287ca9f4942SBharata B Rao 288651a6310SRam Pai static void kvmppc_mark_gfn(unsigned long gfn, struct kvm *kvm, 289651a6310SRam Pai unsigned long flag, unsigned long uvmem_pfn) 290ca9f4942SBharata B Rao { 291ca9f4942SBharata B Rao struct kvmppc_uvmem_slot *p; 292ca9f4942SBharata B Rao 293ca9f4942SBharata B Rao list_for_each_entry(p, &kvm->arch.uvmem_pfns, list) { 294ca9f4942SBharata B Rao if (gfn >= p->base_pfn && gfn < p->base_pfn + p->nr_pfns) { 295ca9f4942SBharata B Rao unsigned long index = gfn - p->base_pfn; 296ca9f4942SBharata B Rao 297651a6310SRam Pai if (flag == KVMPPC_GFN_UVMEM_PFN) 298651a6310SRam Pai p->pfns[index] = uvmem_pfn | flag; 299651a6310SRam Pai else 300651a6310SRam Pai p->pfns[index] = flag; 301ca9f4942SBharata B Rao return; 302ca9f4942SBharata B Rao } 303ca9f4942SBharata B Rao } 304ca9f4942SBharata B Rao } 305ca9f4942SBharata B Rao 306651a6310SRam Pai /* mark the GFN as secure-GFN associated with @uvmem pfn device-PFN. */ 307651a6310SRam Pai static void kvmppc_gfn_secure_uvmem_pfn(unsigned long gfn, 308651a6310SRam Pai unsigned long uvmem_pfn, struct kvm *kvm) 309ca9f4942SBharata B Rao { 310651a6310SRam Pai kvmppc_mark_gfn(gfn, kvm, KVMPPC_GFN_UVMEM_PFN, uvmem_pfn); 311ca9f4942SBharata B Rao } 312ca9f4942SBharata B Rao 313651a6310SRam Pai /* mark the GFN as secure-GFN associated with a memory-PFN. */ 314651a6310SRam Pai static void kvmppc_gfn_secure_mem_pfn(unsigned long gfn, struct kvm *kvm) 315651a6310SRam Pai { 316651a6310SRam Pai kvmppc_mark_gfn(gfn, kvm, KVMPPC_GFN_MEM_PFN, 0); 317651a6310SRam Pai } 318651a6310SRam Pai 319651a6310SRam Pai /* mark the GFN as a shared GFN. */ 320651a6310SRam Pai static void kvmppc_gfn_shared(unsigned long gfn, struct kvm *kvm) 321651a6310SRam Pai { 322651a6310SRam Pai kvmppc_mark_gfn(gfn, kvm, KVMPPC_GFN_SHARED, 0); 323651a6310SRam Pai } 324651a6310SRam Pai 325651a6310SRam Pai /* mark the GFN as a non-existent GFN. */ 326651a6310SRam Pai static void kvmppc_gfn_remove(unsigned long gfn, struct kvm *kvm) 327651a6310SRam Pai { 328651a6310SRam Pai kvmppc_mark_gfn(gfn, kvm, 0, 0); 329651a6310SRam Pai } 330651a6310SRam Pai 331651a6310SRam Pai /* return true, if the GFN is a secure-GFN backed by a secure-PFN */ 332ca9f4942SBharata B Rao static bool kvmppc_gfn_is_uvmem_pfn(unsigned long gfn, struct kvm *kvm, 333ca9f4942SBharata B Rao unsigned long *uvmem_pfn) 334ca9f4942SBharata B Rao { 335ca9f4942SBharata B Rao struct kvmppc_uvmem_slot *p; 336ca9f4942SBharata B Rao 337ca9f4942SBharata B Rao list_for_each_entry(p, &kvm->arch.uvmem_pfns, list) { 338ca9f4942SBharata B Rao if (gfn >= p->base_pfn && gfn < p->base_pfn + p->nr_pfns) { 339ca9f4942SBharata B Rao unsigned long index = gfn - p->base_pfn; 340ca9f4942SBharata B Rao 341651a6310SRam Pai if (p->pfns[index] & KVMPPC_GFN_UVMEM_PFN) { 342ca9f4942SBharata B Rao if (uvmem_pfn) 343ca9f4942SBharata B Rao *uvmem_pfn = p->pfns[index] & 344651a6310SRam Pai KVMPPC_GFN_PFN_MASK; 345ca9f4942SBharata B Rao return true; 346ca9f4942SBharata B Rao } else 347ca9f4942SBharata B Rao return false; 348ca9f4942SBharata B Rao } 349ca9f4942SBharata B Rao } 350ca9f4942SBharata B Rao return false; 351ca9f4942SBharata B Rao } 352ca9f4942SBharata B Rao 353dfaa973aSRam Pai /* 354dfaa973aSRam Pai * starting from *gfn search for the next available GFN that is not yet 355dfaa973aSRam Pai * transitioned to a secure GFN. return the value of that GFN in *gfn. If a 356dfaa973aSRam Pai * GFN is found, return true, else return false 357dfaa973aSRam Pai * 358dfaa973aSRam Pai * Must be called with kvm->arch.uvmem_lock held. 359dfaa973aSRam Pai */ 360dfaa973aSRam Pai static bool kvmppc_next_nontransitioned_gfn(const struct kvm_memory_slot *memslot, 361dfaa973aSRam Pai struct kvm *kvm, unsigned long *gfn) 362dfaa973aSRam Pai { 363dfaa973aSRam Pai struct kvmppc_uvmem_slot *p; 364dfaa973aSRam Pai bool ret = false; 365dfaa973aSRam Pai unsigned long i; 366dfaa973aSRam Pai 367dfaa973aSRam Pai list_for_each_entry(p, &kvm->arch.uvmem_pfns, list) 368dfaa973aSRam Pai if (*gfn >= p->base_pfn && *gfn < p->base_pfn + p->nr_pfns) 369dfaa973aSRam Pai break; 370dfaa973aSRam Pai if (!p) 371dfaa973aSRam Pai return ret; 372dfaa973aSRam Pai /* 373dfaa973aSRam Pai * The code below assumes, one to one correspondence between 374dfaa973aSRam Pai * kvmppc_uvmem_slot and memslot. 375dfaa973aSRam Pai */ 376dfaa973aSRam Pai for (i = *gfn; i < p->base_pfn + p->nr_pfns; i++) { 377dfaa973aSRam Pai unsigned long index = i - p->base_pfn; 378dfaa973aSRam Pai 379dfaa973aSRam Pai if (!(p->pfns[index] & KVMPPC_GFN_FLAG_MASK)) { 380dfaa973aSRam Pai *gfn = i; 381dfaa973aSRam Pai ret = true; 382dfaa973aSRam Pai break; 383dfaa973aSRam Pai } 384dfaa973aSRam Pai } 385dfaa973aSRam Pai return ret; 386dfaa973aSRam Pai } 387dfaa973aSRam Pai 3882027a24aSRam Pai static int kvmppc_memslot_page_merge(struct kvm *kvm, 3892027a24aSRam Pai const struct kvm_memory_slot *memslot, bool merge) 3902027a24aSRam Pai { 3912027a24aSRam Pai unsigned long gfn = memslot->base_gfn; 3922027a24aSRam Pai unsigned long end, start = gfn_to_hva(kvm, gfn); 3932027a24aSRam Pai int ret = 0; 3942027a24aSRam Pai struct vm_area_struct *vma; 3952027a24aSRam Pai int merge_flag = (merge) ? MADV_MERGEABLE : MADV_UNMERGEABLE; 3962027a24aSRam Pai 3972027a24aSRam Pai if (kvm_is_error_hva(start)) 3982027a24aSRam Pai return H_STATE; 3992027a24aSRam Pai 4002027a24aSRam Pai end = start + (memslot->npages << PAGE_SHIFT); 4012027a24aSRam Pai 4022027a24aSRam Pai mmap_write_lock(kvm->mm); 4032027a24aSRam Pai do { 4042027a24aSRam Pai vma = find_vma_intersection(kvm->mm, start, end); 4052027a24aSRam Pai if (!vma) { 4062027a24aSRam Pai ret = H_STATE; 4072027a24aSRam Pai break; 4082027a24aSRam Pai } 4092027a24aSRam Pai ret = ksm_madvise(vma, vma->vm_start, vma->vm_end, 4102027a24aSRam Pai merge_flag, &vma->vm_flags); 4112027a24aSRam Pai if (ret) { 4122027a24aSRam Pai ret = H_STATE; 4132027a24aSRam Pai break; 4142027a24aSRam Pai } 4152027a24aSRam Pai start = vma->vm_end; 4162027a24aSRam Pai } while (end > vma->vm_end); 4172027a24aSRam Pai 4182027a24aSRam Pai mmap_write_unlock(kvm->mm); 4192027a24aSRam Pai return ret; 4202027a24aSRam Pai } 4212027a24aSRam Pai 422a2ce7200SLaurent Dufour static void __kvmppc_uvmem_memslot_delete(struct kvm *kvm, 4232027a24aSRam Pai const struct kvm_memory_slot *memslot) 4242027a24aSRam Pai { 4252027a24aSRam Pai uv_unregister_mem_slot(kvm->arch.lpid, memslot->id); 4262027a24aSRam Pai kvmppc_uvmem_slot_free(kvm, memslot); 4272027a24aSRam Pai kvmppc_memslot_page_merge(kvm, memslot, true); 4282027a24aSRam Pai } 4292027a24aSRam Pai 430a2ce7200SLaurent Dufour static int __kvmppc_uvmem_memslot_create(struct kvm *kvm, 4312027a24aSRam Pai const struct kvm_memory_slot *memslot) 4322027a24aSRam Pai { 4332027a24aSRam Pai int ret = H_PARAMETER; 4342027a24aSRam Pai 4352027a24aSRam Pai if (kvmppc_memslot_page_merge(kvm, memslot, false)) 4362027a24aSRam Pai return ret; 4372027a24aSRam Pai 4382027a24aSRam Pai if (kvmppc_uvmem_slot_init(kvm, memslot)) 4392027a24aSRam Pai goto out1; 4402027a24aSRam Pai 4412027a24aSRam Pai ret = uv_register_mem_slot(kvm->arch.lpid, 4422027a24aSRam Pai memslot->base_gfn << PAGE_SHIFT, 4432027a24aSRam Pai memslot->npages * PAGE_SIZE, 4442027a24aSRam Pai 0, memslot->id); 4452027a24aSRam Pai if (ret < 0) { 4462027a24aSRam Pai ret = H_PARAMETER; 4472027a24aSRam Pai goto out; 4482027a24aSRam Pai } 4492027a24aSRam Pai return 0; 4502027a24aSRam Pai out: 4512027a24aSRam Pai kvmppc_uvmem_slot_free(kvm, memslot); 4522027a24aSRam Pai out1: 4532027a24aSRam Pai kvmppc_memslot_page_merge(kvm, memslot, true); 4542027a24aSRam Pai return ret; 4552027a24aSRam Pai } 4562027a24aSRam Pai 457ca9f4942SBharata B Rao unsigned long kvmppc_h_svm_init_start(struct kvm *kvm) 458ca9f4942SBharata B Rao { 459ca9f4942SBharata B Rao struct kvm_memslots *slots; 4602027a24aSRam Pai struct kvm_memory_slot *memslot, *m; 461ca9f4942SBharata B Rao int ret = H_SUCCESS; 462ca9f4942SBharata B Rao int srcu_idx; 463ca9f4942SBharata B Rao 464377f02d4SLaurent Dufour kvm->arch.secure_guest = KVMPPC_SECURE_INIT_START; 465377f02d4SLaurent Dufour 466ca9f4942SBharata B Rao if (!kvmppc_uvmem_bitmap) 467ca9f4942SBharata B Rao return H_UNSUPPORTED; 468ca9f4942SBharata B Rao 469ca9f4942SBharata B Rao /* Only radix guests can be secure guests */ 470ca9f4942SBharata B Rao if (!kvm_is_radix(kvm)) 471ca9f4942SBharata B Rao return H_UNSUPPORTED; 472ca9f4942SBharata B Rao 4739a5788c6SPaul Mackerras /* NAK the transition to secure if not enabled */ 4749a5788c6SPaul Mackerras if (!kvm->arch.svm_enabled) 4759a5788c6SPaul Mackerras return H_AUTHORITY; 4769a5788c6SPaul Mackerras 477ca9f4942SBharata B Rao srcu_idx = srcu_read_lock(&kvm->srcu); 4782027a24aSRam Pai 4792027a24aSRam Pai /* register the memslot */ 480ca9f4942SBharata B Rao slots = kvm_memslots(kvm); 481ca9f4942SBharata B Rao kvm_for_each_memslot(memslot, slots) { 482a2ce7200SLaurent Dufour ret = __kvmppc_uvmem_memslot_create(kvm, memslot); 4832027a24aSRam Pai if (ret) 4842027a24aSRam Pai break; 485ca9f4942SBharata B Rao } 4862027a24aSRam Pai 4872027a24aSRam Pai if (ret) { 4882027a24aSRam Pai slots = kvm_memslots(kvm); 4892027a24aSRam Pai kvm_for_each_memslot(m, slots) { 4902027a24aSRam Pai if (m == memslot) 4912027a24aSRam Pai break; 492a2ce7200SLaurent Dufour __kvmppc_uvmem_memslot_delete(kvm, memslot); 493ca9f4942SBharata B Rao } 494ca9f4942SBharata B Rao } 4952027a24aSRam Pai 496ca9f4942SBharata B Rao srcu_read_unlock(&kvm->srcu, srcu_idx); 497ca9f4942SBharata B Rao return ret; 498ca9f4942SBharata B Rao } 499ca9f4942SBharata B Rao 500ca9f4942SBharata B Rao /* 501f1b87ea8SLaurent Dufour * Provision a new page on HV side and copy over the contents 502f1b87ea8SLaurent Dufour * from secure memory using UV_PAGE_OUT uvcall. 503f1b87ea8SLaurent Dufour * Caller must held kvm->arch.uvmem_lock. 504f1b87ea8SLaurent Dufour */ 505f1b87ea8SLaurent Dufour static int __kvmppc_svm_page_out(struct vm_area_struct *vma, 506f1b87ea8SLaurent Dufour unsigned long start, 507f1b87ea8SLaurent Dufour unsigned long end, unsigned long page_shift, 508f1b87ea8SLaurent Dufour struct kvm *kvm, unsigned long gpa) 509ca9f4942SBharata B Rao { 510f1b87ea8SLaurent Dufour unsigned long src_pfn, dst_pfn = 0; 511f1b87ea8SLaurent Dufour struct migrate_vma mig; 512f1b87ea8SLaurent Dufour struct page *dpage, *spage; 513f1b87ea8SLaurent Dufour struct kvmppc_uvmem_page_pvt *pvt; 514f1b87ea8SLaurent Dufour unsigned long pfn; 515f1b87ea8SLaurent Dufour int ret = U_SUCCESS; 516ca9f4942SBharata B Rao 517f1b87ea8SLaurent Dufour memset(&mig, 0, sizeof(mig)); 518f1b87ea8SLaurent Dufour mig.vma = vma; 519f1b87ea8SLaurent Dufour mig.start = start; 520f1b87ea8SLaurent Dufour mig.end = end; 521f1b87ea8SLaurent Dufour mig.src = &src_pfn; 522f1b87ea8SLaurent Dufour mig.dst = &dst_pfn; 5233ff03278SPaolo Bonzini mig.pgmap_owner = &kvmppc_uvmem_pgmap; 5243ff03278SPaolo Bonzini mig.flags = MIGRATE_VMA_SELECT_DEVICE_PRIVATE; 525f1b87ea8SLaurent Dufour 526f1b87ea8SLaurent Dufour /* The requested page is already paged-out, nothing to do */ 527f1b87ea8SLaurent Dufour if (!kvmppc_gfn_is_uvmem_pfn(gpa >> page_shift, kvm, NULL)) 528f1b87ea8SLaurent Dufour return ret; 529f1b87ea8SLaurent Dufour 530f1b87ea8SLaurent Dufour ret = migrate_vma_setup(&mig); 531f1b87ea8SLaurent Dufour if (ret) 532f1b87ea8SLaurent Dufour return -1; 533f1b87ea8SLaurent Dufour 534f1b87ea8SLaurent Dufour spage = migrate_pfn_to_page(*mig.src); 535f1b87ea8SLaurent Dufour if (!spage || !(*mig.src & MIGRATE_PFN_MIGRATE)) 536f1b87ea8SLaurent Dufour goto out_finalize; 537f1b87ea8SLaurent Dufour 538f1b87ea8SLaurent Dufour if (!is_zone_device_page(spage)) 539f1b87ea8SLaurent Dufour goto out_finalize; 540f1b87ea8SLaurent Dufour 541f1b87ea8SLaurent Dufour dpage = alloc_page_vma(GFP_HIGHUSER, vma, start); 542f1b87ea8SLaurent Dufour if (!dpage) { 543f1b87ea8SLaurent Dufour ret = -1; 544f1b87ea8SLaurent Dufour goto out_finalize; 545f1b87ea8SLaurent Dufour } 546f1b87ea8SLaurent Dufour 547f1b87ea8SLaurent Dufour lock_page(dpage); 548f1b87ea8SLaurent Dufour pvt = spage->zone_device_data; 549f1b87ea8SLaurent Dufour pfn = page_to_pfn(dpage); 550f1b87ea8SLaurent Dufour 551f1b87ea8SLaurent Dufour /* 552f1b87ea8SLaurent Dufour * This function is used in two cases: 553f1b87ea8SLaurent Dufour * - When HV touches a secure page, for which we do UV_PAGE_OUT 554f1b87ea8SLaurent Dufour * - When a secure page is converted to shared page, we *get* 555f1b87ea8SLaurent Dufour * the page to essentially unmap the device page. In this 556f1b87ea8SLaurent Dufour * case we skip page-out. 557f1b87ea8SLaurent Dufour */ 558f1b87ea8SLaurent Dufour if (!pvt->skip_page_out) 559f1b87ea8SLaurent Dufour ret = uv_page_out(kvm->arch.lpid, pfn << page_shift, 560f1b87ea8SLaurent Dufour gpa, 0, page_shift); 561f1b87ea8SLaurent Dufour 562f1b87ea8SLaurent Dufour if (ret == U_SUCCESS) 563*ab09243aSAlistair Popple *mig.dst = migrate_pfn(pfn); 564f1b87ea8SLaurent Dufour else { 565f1b87ea8SLaurent Dufour unlock_page(dpage); 566f1b87ea8SLaurent Dufour __free_page(dpage); 567f1b87ea8SLaurent Dufour goto out_finalize; 568f1b87ea8SLaurent Dufour } 569f1b87ea8SLaurent Dufour 570f1b87ea8SLaurent Dufour migrate_vma_pages(&mig); 571f1b87ea8SLaurent Dufour 572f1b87ea8SLaurent Dufour out_finalize: 573f1b87ea8SLaurent Dufour migrate_vma_finalize(&mig); 574f1b87ea8SLaurent Dufour return ret; 575f1b87ea8SLaurent Dufour } 576f1b87ea8SLaurent Dufour 577f1b87ea8SLaurent Dufour static inline int kvmppc_svm_page_out(struct vm_area_struct *vma, 578f1b87ea8SLaurent Dufour unsigned long start, unsigned long end, 579f1b87ea8SLaurent Dufour unsigned long page_shift, 580f1b87ea8SLaurent Dufour struct kvm *kvm, unsigned long gpa) 581f1b87ea8SLaurent Dufour { 582f1b87ea8SLaurent Dufour int ret; 583f1b87ea8SLaurent Dufour 584f1b87ea8SLaurent Dufour mutex_lock(&kvm->arch.uvmem_lock); 585f1b87ea8SLaurent Dufour ret = __kvmppc_svm_page_out(vma, start, end, page_shift, kvm, gpa); 586f1b87ea8SLaurent Dufour mutex_unlock(&kvm->arch.uvmem_lock); 587f1b87ea8SLaurent Dufour 588f1b87ea8SLaurent Dufour return ret; 589ca9f4942SBharata B Rao } 590ca9f4942SBharata B Rao 591ca9f4942SBharata B Rao /* 592c3262257SBharata B Rao * Drop device pages that we maintain for the secure guest 593c3262257SBharata B Rao * 594c3262257SBharata B Rao * We first mark the pages to be skipped from UV_PAGE_OUT when there 595c3262257SBharata B Rao * is HV side fault on these pages. Next we *get* these pages, forcing 596c3262257SBharata B Rao * fault on them, do fault time migration to replace the device PTEs in 597c3262257SBharata B Rao * QEMU page table with normal PTEs from newly allocated pages. 598c3262257SBharata B Rao */ 59981ab595dSLaurent Dufour void kvmppc_uvmem_drop_pages(const struct kvm_memory_slot *slot, 600ce477a7aSSukadev Bhattiprolu struct kvm *kvm, bool skip_page_out) 601c3262257SBharata B Rao { 602c3262257SBharata B Rao int i; 603c3262257SBharata B Rao struct kvmppc_uvmem_page_pvt *pvt; 604c3262257SBharata B Rao struct page *uvmem_page; 60581ab595dSLaurent Dufour struct vm_area_struct *vma = NULL; 60681ab595dSLaurent Dufour unsigned long uvmem_pfn, gfn; 60781ab595dSLaurent Dufour unsigned long addr; 608c3262257SBharata B Rao 60981ab595dSLaurent Dufour mmap_read_lock(kvm->mm); 61081ab595dSLaurent Dufour 61181ab595dSLaurent Dufour addr = slot->userspace_addr; 61281ab595dSLaurent Dufour 61381ab595dSLaurent Dufour gfn = slot->base_gfn; 61481ab595dSLaurent Dufour for (i = slot->npages; i; --i, ++gfn, addr += PAGE_SIZE) { 61581ab595dSLaurent Dufour 61681ab595dSLaurent Dufour /* Fetch the VMA if addr is not in the latest fetched one */ 61781ab595dSLaurent Dufour if (!vma || addr >= vma->vm_end) { 61827a14d28SLiam Howlett vma = vma_lookup(kvm->mm, addr); 61981ab595dSLaurent Dufour if (!vma) { 62081ab595dSLaurent Dufour pr_err("Can't find VMA for gfn:0x%lx\n", gfn); 62181ab595dSLaurent Dufour break; 62281ab595dSLaurent Dufour } 623c3262257SBharata B Rao } 624c3262257SBharata B Rao 62581ab595dSLaurent Dufour mutex_lock(&kvm->arch.uvmem_lock); 62681ab595dSLaurent Dufour 62781ab595dSLaurent Dufour if (kvmppc_gfn_is_uvmem_pfn(gfn, kvm, &uvmem_pfn)) { 628c3262257SBharata B Rao uvmem_page = pfn_to_page(uvmem_pfn); 629c3262257SBharata B Rao pvt = uvmem_page->zone_device_data; 630ce477a7aSSukadev Bhattiprolu pvt->skip_page_out = skip_page_out; 631651a6310SRam Pai pvt->remove_gfn = true; 632c3262257SBharata B Rao 63381ab595dSLaurent Dufour if (__kvmppc_svm_page_out(vma, addr, addr + PAGE_SIZE, 63481ab595dSLaurent Dufour PAGE_SHIFT, kvm, pvt->gpa)) 63581ab595dSLaurent Dufour pr_err("Can't page out gpa:0x%lx addr:0x%lx\n", 63681ab595dSLaurent Dufour pvt->gpa, addr); 63781ab595dSLaurent Dufour } else { 63881ab595dSLaurent Dufour /* Remove the shared flag if any */ 63981ab595dSLaurent Dufour kvmppc_gfn_remove(gfn, kvm); 640c3262257SBharata B Rao } 64181ab595dSLaurent Dufour 64281ab595dSLaurent Dufour mutex_unlock(&kvm->arch.uvmem_lock); 64381ab595dSLaurent Dufour } 64481ab595dSLaurent Dufour 64581ab595dSLaurent Dufour mmap_read_unlock(kvm->mm); 646c3262257SBharata B Rao } 647c3262257SBharata B Rao 6483a43970dSSukadev Bhattiprolu unsigned long kvmppc_h_svm_init_abort(struct kvm *kvm) 6493a43970dSSukadev Bhattiprolu { 6503a43970dSSukadev Bhattiprolu int srcu_idx; 6513a43970dSSukadev Bhattiprolu struct kvm_memory_slot *memslot; 6523a43970dSSukadev Bhattiprolu 6533a43970dSSukadev Bhattiprolu /* 6543a43970dSSukadev Bhattiprolu * Expect to be called only after INIT_START and before INIT_DONE. 6553a43970dSSukadev Bhattiprolu * If INIT_DONE was completed, use normal VM termination sequence. 6563a43970dSSukadev Bhattiprolu */ 6573a43970dSSukadev Bhattiprolu if (!(kvm->arch.secure_guest & KVMPPC_SECURE_INIT_START)) 6583a43970dSSukadev Bhattiprolu return H_UNSUPPORTED; 6593a43970dSSukadev Bhattiprolu 6603a43970dSSukadev Bhattiprolu if (kvm->arch.secure_guest & KVMPPC_SECURE_INIT_DONE) 6613a43970dSSukadev Bhattiprolu return H_STATE; 6623a43970dSSukadev Bhattiprolu 6633a43970dSSukadev Bhattiprolu srcu_idx = srcu_read_lock(&kvm->srcu); 6643a43970dSSukadev Bhattiprolu 6653a43970dSSukadev Bhattiprolu kvm_for_each_memslot(memslot, kvm_memslots(kvm)) 6663a43970dSSukadev Bhattiprolu kvmppc_uvmem_drop_pages(memslot, kvm, false); 6673a43970dSSukadev Bhattiprolu 6683a43970dSSukadev Bhattiprolu srcu_read_unlock(&kvm->srcu, srcu_idx); 6693a43970dSSukadev Bhattiprolu 6703a43970dSSukadev Bhattiprolu kvm->arch.secure_guest = 0; 6713a43970dSSukadev Bhattiprolu uv_svm_terminate(kvm->arch.lpid); 6723a43970dSSukadev Bhattiprolu 6733a43970dSSukadev Bhattiprolu return H_PARAMETER; 6743a43970dSSukadev Bhattiprolu } 6753a43970dSSukadev Bhattiprolu 676c3262257SBharata B Rao /* 677ca9f4942SBharata B Rao * Get a free device PFN from the pool 678ca9f4942SBharata B Rao * 679ca9f4942SBharata B Rao * Called when a normal page is moved to secure memory (UV_PAGE_IN). Device 680ca9f4942SBharata B Rao * PFN will be used to keep track of the secure page on HV side. 681ca9f4942SBharata B Rao * 682ca9f4942SBharata B Rao * Called with kvm->arch.uvmem_lock held 683ca9f4942SBharata B Rao */ 684ca9f4942SBharata B Rao static struct page *kvmppc_uvmem_get_page(unsigned long gpa, struct kvm *kvm) 685ca9f4942SBharata B Rao { 686ca9f4942SBharata B Rao struct page *dpage = NULL; 687ca9f4942SBharata B Rao unsigned long bit, uvmem_pfn; 688ca9f4942SBharata B Rao struct kvmppc_uvmem_page_pvt *pvt; 689ca9f4942SBharata B Rao unsigned long pfn_last, pfn_first; 690ca9f4942SBharata B Rao 691a4574f63SDan Williams pfn_first = kvmppc_uvmem_pgmap.range.start >> PAGE_SHIFT; 692ca9f4942SBharata B Rao pfn_last = pfn_first + 693a4574f63SDan Williams (range_len(&kvmppc_uvmem_pgmap.range) >> PAGE_SHIFT); 694ca9f4942SBharata B Rao 695ca9f4942SBharata B Rao spin_lock(&kvmppc_uvmem_bitmap_lock); 696ca9f4942SBharata B Rao bit = find_first_zero_bit(kvmppc_uvmem_bitmap, 697ca9f4942SBharata B Rao pfn_last - pfn_first); 698ca9f4942SBharata B Rao if (bit >= (pfn_last - pfn_first)) 699ca9f4942SBharata B Rao goto out; 700ca9f4942SBharata B Rao bitmap_set(kvmppc_uvmem_bitmap, bit, 1); 701ca9f4942SBharata B Rao spin_unlock(&kvmppc_uvmem_bitmap_lock); 702ca9f4942SBharata B Rao 703ca9f4942SBharata B Rao pvt = kzalloc(sizeof(*pvt), GFP_KERNEL); 704ca9f4942SBharata B Rao if (!pvt) 705ca9f4942SBharata B Rao goto out_clear; 706ca9f4942SBharata B Rao 707ca9f4942SBharata B Rao uvmem_pfn = bit + pfn_first; 708651a6310SRam Pai kvmppc_gfn_secure_uvmem_pfn(gpa >> PAGE_SHIFT, uvmem_pfn, kvm); 709ca9f4942SBharata B Rao 710ca9f4942SBharata B Rao pvt->gpa = gpa; 711ca9f4942SBharata B Rao pvt->kvm = kvm; 712ca9f4942SBharata B Rao 713ca9f4942SBharata B Rao dpage = pfn_to_page(uvmem_pfn); 714ca9f4942SBharata B Rao dpage->zone_device_data = pvt; 715ca9f4942SBharata B Rao get_page(dpage); 716ca9f4942SBharata B Rao lock_page(dpage); 717ca9f4942SBharata B Rao return dpage; 718ca9f4942SBharata B Rao out_clear: 719ca9f4942SBharata B Rao spin_lock(&kvmppc_uvmem_bitmap_lock); 720ca9f4942SBharata B Rao bitmap_clear(kvmppc_uvmem_bitmap, bit, 1); 721ca9f4942SBharata B Rao out: 722ca9f4942SBharata B Rao spin_unlock(&kvmppc_uvmem_bitmap_lock); 723ca9f4942SBharata B Rao return NULL; 724ca9f4942SBharata B Rao } 725ca9f4942SBharata B Rao 726ca9f4942SBharata B Rao /* 727dfaa973aSRam Pai * Alloc a PFN from private device memory pool. If @pagein is true, 728dfaa973aSRam Pai * copy page from normal memory to secure memory using UV_PAGE_IN uvcall. 729ca9f4942SBharata B Rao */ 730dfaa973aSRam Pai static int kvmppc_svm_page_in(struct vm_area_struct *vma, 731dfaa973aSRam Pai unsigned long start, 732ca9f4942SBharata B Rao unsigned long end, unsigned long gpa, struct kvm *kvm, 733dfaa973aSRam Pai unsigned long page_shift, 734dfaa973aSRam Pai bool pagein) 735ca9f4942SBharata B Rao { 736ca9f4942SBharata B Rao unsigned long src_pfn, dst_pfn = 0; 737ca9f4942SBharata B Rao struct migrate_vma mig; 738ca9f4942SBharata B Rao struct page *spage; 739ca9f4942SBharata B Rao unsigned long pfn; 740ca9f4942SBharata B Rao struct page *dpage; 741ca9f4942SBharata B Rao int ret = 0; 742ca9f4942SBharata B Rao 743ca9f4942SBharata B Rao memset(&mig, 0, sizeof(mig)); 744ca9f4942SBharata B Rao mig.vma = vma; 745ca9f4942SBharata B Rao mig.start = start; 746ca9f4942SBharata B Rao mig.end = end; 747ca9f4942SBharata B Rao mig.src = &src_pfn; 748ca9f4942SBharata B Rao mig.dst = &dst_pfn; 7495143192cSRalph Campbell mig.flags = MIGRATE_VMA_SELECT_SYSTEM; 750ca9f4942SBharata B Rao 751ca9f4942SBharata B Rao ret = migrate_vma_setup(&mig); 752ca9f4942SBharata B Rao if (ret) 753ca9f4942SBharata B Rao return ret; 754ca9f4942SBharata B Rao 755ca9f4942SBharata B Rao if (!(*mig.src & MIGRATE_PFN_MIGRATE)) { 756ca9f4942SBharata B Rao ret = -1; 757ca9f4942SBharata B Rao goto out_finalize; 758ca9f4942SBharata B Rao } 759ca9f4942SBharata B Rao 760ca9f4942SBharata B Rao dpage = kvmppc_uvmem_get_page(gpa, kvm); 761ca9f4942SBharata B Rao if (!dpage) { 762ca9f4942SBharata B Rao ret = -1; 763ca9f4942SBharata B Rao goto out_finalize; 764ca9f4942SBharata B Rao } 765ca9f4942SBharata B Rao 766dfaa973aSRam Pai if (pagein) { 767ca9f4942SBharata B Rao pfn = *mig.src >> MIGRATE_PFN_SHIFT; 768ca9f4942SBharata B Rao spage = migrate_pfn_to_page(*mig.src); 769dfaa973aSRam Pai if (spage) { 770dfaa973aSRam Pai ret = uv_page_in(kvm->arch.lpid, pfn << page_shift, 771dfaa973aSRam Pai gpa, 0, page_shift); 772dfaa973aSRam Pai if (ret) 773dfaa973aSRam Pai goto out_finalize; 774dfaa973aSRam Pai } 775dfaa973aSRam Pai } 776ca9f4942SBharata B Rao 777*ab09243aSAlistair Popple *mig.dst = migrate_pfn(page_to_pfn(dpage)); 778ca9f4942SBharata B Rao migrate_vma_pages(&mig); 779ca9f4942SBharata B Rao out_finalize: 780ca9f4942SBharata B Rao migrate_vma_finalize(&mig); 781ca9f4942SBharata B Rao return ret; 782ca9f4942SBharata B Rao } 783ca9f4942SBharata B Rao 784dfaa973aSRam Pai static int kvmppc_uv_migrate_mem_slot(struct kvm *kvm, 785dfaa973aSRam Pai const struct kvm_memory_slot *memslot) 786dfaa973aSRam Pai { 787dfaa973aSRam Pai unsigned long gfn = memslot->base_gfn; 788dfaa973aSRam Pai struct vm_area_struct *vma; 789dfaa973aSRam Pai unsigned long start, end; 790dfaa973aSRam Pai int ret = 0; 791dfaa973aSRam Pai 792dfaa973aSRam Pai mmap_read_lock(kvm->mm); 793dfaa973aSRam Pai mutex_lock(&kvm->arch.uvmem_lock); 794dfaa973aSRam Pai while (kvmppc_next_nontransitioned_gfn(memslot, kvm, &gfn)) { 795dfaa973aSRam Pai ret = H_STATE; 796dfaa973aSRam Pai start = gfn_to_hva(kvm, gfn); 797dfaa973aSRam Pai if (kvm_is_error_hva(start)) 798dfaa973aSRam Pai break; 799dfaa973aSRam Pai 800dfaa973aSRam Pai end = start + (1UL << PAGE_SHIFT); 801dfaa973aSRam Pai vma = find_vma_intersection(kvm->mm, start, end); 802dfaa973aSRam Pai if (!vma || vma->vm_start > start || vma->vm_end < end) 803dfaa973aSRam Pai break; 804dfaa973aSRam Pai 805dfaa973aSRam Pai ret = kvmppc_svm_page_in(vma, start, end, 806dfaa973aSRam Pai (gfn << PAGE_SHIFT), kvm, PAGE_SHIFT, false); 807dfaa973aSRam Pai if (ret) { 808dfaa973aSRam Pai ret = H_STATE; 809dfaa973aSRam Pai break; 810dfaa973aSRam Pai } 811dfaa973aSRam Pai 812dfaa973aSRam Pai /* relinquish the cpu if needed */ 813dfaa973aSRam Pai cond_resched(); 814dfaa973aSRam Pai } 815dfaa973aSRam Pai mutex_unlock(&kvm->arch.uvmem_lock); 816dfaa973aSRam Pai mmap_read_unlock(kvm->mm); 817dfaa973aSRam Pai return ret; 818dfaa973aSRam Pai } 819dfaa973aSRam Pai 820dfaa973aSRam Pai unsigned long kvmppc_h_svm_init_done(struct kvm *kvm) 821dfaa973aSRam Pai { 822dfaa973aSRam Pai struct kvm_memslots *slots; 823dfaa973aSRam Pai struct kvm_memory_slot *memslot; 824dfaa973aSRam Pai int srcu_idx; 825dfaa973aSRam Pai long ret = H_SUCCESS; 826dfaa973aSRam Pai 827dfaa973aSRam Pai if (!(kvm->arch.secure_guest & KVMPPC_SECURE_INIT_START)) 828dfaa973aSRam Pai return H_UNSUPPORTED; 829dfaa973aSRam Pai 830dfaa973aSRam Pai /* migrate any unmoved normal pfn to device pfns*/ 831dfaa973aSRam Pai srcu_idx = srcu_read_lock(&kvm->srcu); 832dfaa973aSRam Pai slots = kvm_memslots(kvm); 833dfaa973aSRam Pai kvm_for_each_memslot(memslot, slots) { 834dfaa973aSRam Pai ret = kvmppc_uv_migrate_mem_slot(kvm, memslot); 835dfaa973aSRam Pai if (ret) { 836dfaa973aSRam Pai /* 837dfaa973aSRam Pai * The pages will remain transitioned. 838dfaa973aSRam Pai * Its the callers responsibility to 839dfaa973aSRam Pai * terminate the VM, which will undo 840dfaa973aSRam Pai * all state of the VM. Till then 841dfaa973aSRam Pai * this VM is in a erroneous state. 842dfaa973aSRam Pai * Its KVMPPC_SECURE_INIT_DONE will 843dfaa973aSRam Pai * remain unset. 844dfaa973aSRam Pai */ 845dfaa973aSRam Pai ret = H_STATE; 846dfaa973aSRam Pai goto out; 847dfaa973aSRam Pai } 848dfaa973aSRam Pai } 849dfaa973aSRam Pai 850dfaa973aSRam Pai kvm->arch.secure_guest |= KVMPPC_SECURE_INIT_DONE; 851dfaa973aSRam Pai pr_info("LPID %d went secure\n", kvm->arch.lpid); 852dfaa973aSRam Pai 853dfaa973aSRam Pai out: 854dfaa973aSRam Pai srcu_read_unlock(&kvm->srcu, srcu_idx); 855dfaa973aSRam Pai return ret; 856dfaa973aSRam Pai } 857dfaa973aSRam Pai 858ca9f4942SBharata B Rao /* 85960f0a643SBharata B Rao * Shares the page with HV, thus making it a normal page. 86060f0a643SBharata B Rao * 86160f0a643SBharata B Rao * - If the page is already secure, then provision a new page and share 86260f0a643SBharata B Rao * - If the page is a normal page, share the existing page 86360f0a643SBharata B Rao * 86460f0a643SBharata B Rao * In the former case, uses dev_pagemap_ops.migrate_to_ram handler 86560f0a643SBharata B Rao * to unmap the device page from QEMU's page tables. 86660f0a643SBharata B Rao */ 86748908a38SRam Pai static unsigned long kvmppc_share_page(struct kvm *kvm, unsigned long gpa, 86848908a38SRam Pai unsigned long page_shift) 86960f0a643SBharata B Rao { 87060f0a643SBharata B Rao 87160f0a643SBharata B Rao int ret = H_PARAMETER; 87260f0a643SBharata B Rao struct page *uvmem_page; 87360f0a643SBharata B Rao struct kvmppc_uvmem_page_pvt *pvt; 87460f0a643SBharata B Rao unsigned long pfn; 87560f0a643SBharata B Rao unsigned long gfn = gpa >> page_shift; 87660f0a643SBharata B Rao int srcu_idx; 87760f0a643SBharata B Rao unsigned long uvmem_pfn; 87860f0a643SBharata B Rao 87960f0a643SBharata B Rao srcu_idx = srcu_read_lock(&kvm->srcu); 88060f0a643SBharata B Rao mutex_lock(&kvm->arch.uvmem_lock); 88160f0a643SBharata B Rao if (kvmppc_gfn_is_uvmem_pfn(gfn, kvm, &uvmem_pfn)) { 88260f0a643SBharata B Rao uvmem_page = pfn_to_page(uvmem_pfn); 88360f0a643SBharata B Rao pvt = uvmem_page->zone_device_data; 88460f0a643SBharata B Rao pvt->skip_page_out = true; 885651a6310SRam Pai /* 886651a6310SRam Pai * do not drop the GFN. It is a valid GFN 887651a6310SRam Pai * that is transitioned to a shared GFN. 888651a6310SRam Pai */ 889651a6310SRam Pai pvt->remove_gfn = false; 89060f0a643SBharata B Rao } 89160f0a643SBharata B Rao 89260f0a643SBharata B Rao retry: 89360f0a643SBharata B Rao mutex_unlock(&kvm->arch.uvmem_lock); 89460f0a643SBharata B Rao pfn = gfn_to_pfn(kvm, gfn); 89560f0a643SBharata B Rao if (is_error_noslot_pfn(pfn)) 89660f0a643SBharata B Rao goto out; 89760f0a643SBharata B Rao 89860f0a643SBharata B Rao mutex_lock(&kvm->arch.uvmem_lock); 89960f0a643SBharata B Rao if (kvmppc_gfn_is_uvmem_pfn(gfn, kvm, &uvmem_pfn)) { 90060f0a643SBharata B Rao uvmem_page = pfn_to_page(uvmem_pfn); 90160f0a643SBharata B Rao pvt = uvmem_page->zone_device_data; 90260f0a643SBharata B Rao pvt->skip_page_out = true; 903651a6310SRam Pai pvt->remove_gfn = false; /* it continues to be a valid GFN */ 90460f0a643SBharata B Rao kvm_release_pfn_clean(pfn); 90560f0a643SBharata B Rao goto retry; 90660f0a643SBharata B Rao } 90760f0a643SBharata B Rao 908651a6310SRam Pai if (!uv_page_in(kvm->arch.lpid, pfn << page_shift, gpa, 0, 909651a6310SRam Pai page_shift)) { 910651a6310SRam Pai kvmppc_gfn_shared(gfn, kvm); 91160f0a643SBharata B Rao ret = H_SUCCESS; 912651a6310SRam Pai } 91360f0a643SBharata B Rao kvm_release_pfn_clean(pfn); 91460f0a643SBharata B Rao mutex_unlock(&kvm->arch.uvmem_lock); 91560f0a643SBharata B Rao out: 91660f0a643SBharata B Rao srcu_read_unlock(&kvm->srcu, srcu_idx); 91760f0a643SBharata B Rao return ret; 91860f0a643SBharata B Rao } 91960f0a643SBharata B Rao 92060f0a643SBharata B Rao /* 921ca9f4942SBharata B Rao * H_SVM_PAGE_IN: Move page from normal memory to secure memory. 92260f0a643SBharata B Rao * 92360f0a643SBharata B Rao * H_PAGE_IN_SHARED flag makes the page shared which means that the same 92460f0a643SBharata B Rao * memory in is visible from both UV and HV. 925ca9f4942SBharata B Rao */ 92648908a38SRam Pai unsigned long kvmppc_h_svm_page_in(struct kvm *kvm, unsigned long gpa, 92748908a38SRam Pai unsigned long flags, 92848908a38SRam Pai unsigned long page_shift) 929ca9f4942SBharata B Rao { 930ca9f4942SBharata B Rao unsigned long start, end; 931ca9f4942SBharata B Rao struct vm_area_struct *vma; 932ca9f4942SBharata B Rao int srcu_idx; 933ca9f4942SBharata B Rao unsigned long gfn = gpa >> page_shift; 934ca9f4942SBharata B Rao int ret; 935ca9f4942SBharata B Rao 936ca9f4942SBharata B Rao if (!(kvm->arch.secure_guest & KVMPPC_SECURE_INIT_START)) 937ca9f4942SBharata B Rao return H_UNSUPPORTED; 938ca9f4942SBharata B Rao 939ca9f4942SBharata B Rao if (page_shift != PAGE_SHIFT) 940ca9f4942SBharata B Rao return H_P3; 941ca9f4942SBharata B Rao 94260f0a643SBharata B Rao if (flags & ~H_PAGE_IN_SHARED) 943ca9f4942SBharata B Rao return H_P2; 944ca9f4942SBharata B Rao 94560f0a643SBharata B Rao if (flags & H_PAGE_IN_SHARED) 94660f0a643SBharata B Rao return kvmppc_share_page(kvm, gpa, page_shift); 94760f0a643SBharata B Rao 948ca9f4942SBharata B Rao ret = H_PARAMETER; 949ca9f4942SBharata B Rao srcu_idx = srcu_read_lock(&kvm->srcu); 9502027a24aSRam Pai mmap_read_lock(kvm->mm); 951ca9f4942SBharata B Rao 952ca9f4942SBharata B Rao start = gfn_to_hva(kvm, gfn); 953ca9f4942SBharata B Rao if (kvm_is_error_hva(start)) 954ca9f4942SBharata B Rao goto out; 955ca9f4942SBharata B Rao 956ca9f4942SBharata B Rao mutex_lock(&kvm->arch.uvmem_lock); 957ca9f4942SBharata B Rao /* Fail the page-in request of an already paged-in page */ 958ca9f4942SBharata B Rao if (kvmppc_gfn_is_uvmem_pfn(gfn, kvm, NULL)) 959ca9f4942SBharata B Rao goto out_unlock; 960ca9f4942SBharata B Rao 961ca9f4942SBharata B Rao end = start + (1UL << page_shift); 962ca9f4942SBharata B Rao vma = find_vma_intersection(kvm->mm, start, end); 963ca9f4942SBharata B Rao if (!vma || vma->vm_start > start || vma->vm_end < end) 964ca9f4942SBharata B Rao goto out_unlock; 965ca9f4942SBharata B Rao 966dfaa973aSRam Pai if (kvmppc_svm_page_in(vma, start, end, gpa, kvm, page_shift, 967dfaa973aSRam Pai true)) 968dfaa973aSRam Pai goto out_unlock; 969dfaa973aSRam Pai 970ca9f4942SBharata B Rao ret = H_SUCCESS; 971651a6310SRam Pai 972ca9f4942SBharata B Rao out_unlock: 973ca9f4942SBharata B Rao mutex_unlock(&kvm->arch.uvmem_lock); 974ca9f4942SBharata B Rao out: 975d8ed45c5SMichel Lespinasse mmap_read_unlock(kvm->mm); 976ca9f4942SBharata B Rao srcu_read_unlock(&kvm->srcu, srcu_idx); 977ca9f4942SBharata B Rao return ret; 978ca9f4942SBharata B Rao } 979ca9f4942SBharata B Rao 980ca9f4942SBharata B Rao 981ca9f4942SBharata B Rao /* 982ca9f4942SBharata B Rao * Fault handler callback that gets called when HV touches any page that 983ca9f4942SBharata B Rao * has been moved to secure memory, we ask UV to give back the page by 984ca9f4942SBharata B Rao * issuing UV_PAGE_OUT uvcall. 985ca9f4942SBharata B Rao * 986ca9f4942SBharata B Rao * This eventually results in dropping of device PFN and the newly 987ca9f4942SBharata B Rao * provisioned page/PFN gets populated in QEMU page tables. 988ca9f4942SBharata B Rao */ 989ca9f4942SBharata B Rao static vm_fault_t kvmppc_uvmem_migrate_to_ram(struct vm_fault *vmf) 990ca9f4942SBharata B Rao { 991ca9f4942SBharata B Rao struct kvmppc_uvmem_page_pvt *pvt = vmf->page->zone_device_data; 992ca9f4942SBharata B Rao 993ca9f4942SBharata B Rao if (kvmppc_svm_page_out(vmf->vma, vmf->address, 994ca9f4942SBharata B Rao vmf->address + PAGE_SIZE, PAGE_SHIFT, 995ca9f4942SBharata B Rao pvt->kvm, pvt->gpa)) 996ca9f4942SBharata B Rao return VM_FAULT_SIGBUS; 997ca9f4942SBharata B Rao else 998ca9f4942SBharata B Rao return 0; 999ca9f4942SBharata B Rao } 1000ca9f4942SBharata B Rao 1001ca9f4942SBharata B Rao /* 1002ca9f4942SBharata B Rao * Release the device PFN back to the pool 1003ca9f4942SBharata B Rao * 1004651a6310SRam Pai * Gets called when secure GFN tranistions from a secure-PFN 1005651a6310SRam Pai * to a normal PFN during H_SVM_PAGE_OUT. 1006ca9f4942SBharata B Rao * Gets called with kvm->arch.uvmem_lock held. 1007ca9f4942SBharata B Rao */ 1008ca9f4942SBharata B Rao static void kvmppc_uvmem_page_free(struct page *page) 1009ca9f4942SBharata B Rao { 1010ca9f4942SBharata B Rao unsigned long pfn = page_to_pfn(page) - 1011a4574f63SDan Williams (kvmppc_uvmem_pgmap.range.start >> PAGE_SHIFT); 1012ca9f4942SBharata B Rao struct kvmppc_uvmem_page_pvt *pvt; 1013ca9f4942SBharata B Rao 1014ca9f4942SBharata B Rao spin_lock(&kvmppc_uvmem_bitmap_lock); 1015ca9f4942SBharata B Rao bitmap_clear(kvmppc_uvmem_bitmap, pfn, 1); 1016ca9f4942SBharata B Rao spin_unlock(&kvmppc_uvmem_bitmap_lock); 1017ca9f4942SBharata B Rao 1018ca9f4942SBharata B Rao pvt = page->zone_device_data; 1019ca9f4942SBharata B Rao page->zone_device_data = NULL; 1020651a6310SRam Pai if (pvt->remove_gfn) 1021651a6310SRam Pai kvmppc_gfn_remove(pvt->gpa >> PAGE_SHIFT, pvt->kvm); 1022651a6310SRam Pai else 1023651a6310SRam Pai kvmppc_gfn_secure_mem_pfn(pvt->gpa >> PAGE_SHIFT, pvt->kvm); 1024ca9f4942SBharata B Rao kfree(pvt); 1025ca9f4942SBharata B Rao } 1026ca9f4942SBharata B Rao 1027ca9f4942SBharata B Rao static const struct dev_pagemap_ops kvmppc_uvmem_ops = { 1028ca9f4942SBharata B Rao .page_free = kvmppc_uvmem_page_free, 1029ca9f4942SBharata B Rao .migrate_to_ram = kvmppc_uvmem_migrate_to_ram, 1030ca9f4942SBharata B Rao }; 1031ca9f4942SBharata B Rao 1032ca9f4942SBharata B Rao /* 1033ca9f4942SBharata B Rao * H_SVM_PAGE_OUT: Move page from secure memory to normal memory. 1034ca9f4942SBharata B Rao */ 1035ca9f4942SBharata B Rao unsigned long 1036ca9f4942SBharata B Rao kvmppc_h_svm_page_out(struct kvm *kvm, unsigned long gpa, 1037ca9f4942SBharata B Rao unsigned long flags, unsigned long page_shift) 1038ca9f4942SBharata B Rao { 1039ca9f4942SBharata B Rao unsigned long gfn = gpa >> page_shift; 1040ca9f4942SBharata B Rao unsigned long start, end; 1041ca9f4942SBharata B Rao struct vm_area_struct *vma; 1042ca9f4942SBharata B Rao int srcu_idx; 1043ca9f4942SBharata B Rao int ret; 1044ca9f4942SBharata B Rao 1045ca9f4942SBharata B Rao if (!(kvm->arch.secure_guest & KVMPPC_SECURE_INIT_START)) 1046ca9f4942SBharata B Rao return H_UNSUPPORTED; 1047ca9f4942SBharata B Rao 1048ca9f4942SBharata B Rao if (page_shift != PAGE_SHIFT) 1049ca9f4942SBharata B Rao return H_P3; 1050ca9f4942SBharata B Rao 1051ca9f4942SBharata B Rao if (flags) 1052ca9f4942SBharata B Rao return H_P2; 1053ca9f4942SBharata B Rao 1054ca9f4942SBharata B Rao ret = H_PARAMETER; 1055ca9f4942SBharata B Rao srcu_idx = srcu_read_lock(&kvm->srcu); 1056d8ed45c5SMichel Lespinasse mmap_read_lock(kvm->mm); 1057ca9f4942SBharata B Rao start = gfn_to_hva(kvm, gfn); 1058ca9f4942SBharata B Rao if (kvm_is_error_hva(start)) 1059ca9f4942SBharata B Rao goto out; 1060ca9f4942SBharata B Rao 1061ca9f4942SBharata B Rao end = start + (1UL << page_shift); 1062ca9f4942SBharata B Rao vma = find_vma_intersection(kvm->mm, start, end); 1063ca9f4942SBharata B Rao if (!vma || vma->vm_start > start || vma->vm_end < end) 1064ca9f4942SBharata B Rao goto out; 1065ca9f4942SBharata B Rao 1066ca9f4942SBharata B Rao if (!kvmppc_svm_page_out(vma, start, end, page_shift, kvm, gpa)) 1067ca9f4942SBharata B Rao ret = H_SUCCESS; 1068ca9f4942SBharata B Rao out: 1069d8ed45c5SMichel Lespinasse mmap_read_unlock(kvm->mm); 1070ca9f4942SBharata B Rao srcu_read_unlock(&kvm->srcu, srcu_idx); 1071ca9f4942SBharata B Rao return ret; 1072ca9f4942SBharata B Rao } 1073ca9f4942SBharata B Rao 1074008e359cSBharata B Rao int kvmppc_send_page_to_uv(struct kvm *kvm, unsigned long gfn) 1075008e359cSBharata B Rao { 1076008e359cSBharata B Rao unsigned long pfn; 1077008e359cSBharata B Rao int ret = U_SUCCESS; 1078008e359cSBharata B Rao 1079008e359cSBharata B Rao pfn = gfn_to_pfn(kvm, gfn); 1080008e359cSBharata B Rao if (is_error_noslot_pfn(pfn)) 1081008e359cSBharata B Rao return -EFAULT; 1082008e359cSBharata B Rao 1083008e359cSBharata B Rao mutex_lock(&kvm->arch.uvmem_lock); 1084008e359cSBharata B Rao if (kvmppc_gfn_is_uvmem_pfn(gfn, kvm, NULL)) 1085008e359cSBharata B Rao goto out; 1086008e359cSBharata B Rao 1087008e359cSBharata B Rao ret = uv_page_in(kvm->arch.lpid, pfn << PAGE_SHIFT, gfn << PAGE_SHIFT, 1088008e359cSBharata B Rao 0, PAGE_SHIFT); 1089008e359cSBharata B Rao out: 1090008e359cSBharata B Rao kvm_release_pfn_clean(pfn); 1091008e359cSBharata B Rao mutex_unlock(&kvm->arch.uvmem_lock); 1092008e359cSBharata B Rao return (ret == U_SUCCESS) ? RESUME_GUEST : -EFAULT; 1093008e359cSBharata B Rao } 1094008e359cSBharata B Rao 1095a2ce7200SLaurent Dufour int kvmppc_uvmem_memslot_create(struct kvm *kvm, const struct kvm_memory_slot *new) 1096a2ce7200SLaurent Dufour { 1097a2ce7200SLaurent Dufour int ret = __kvmppc_uvmem_memslot_create(kvm, new); 1098a2ce7200SLaurent Dufour 1099a2ce7200SLaurent Dufour if (!ret) 1100a2ce7200SLaurent Dufour ret = kvmppc_uv_migrate_mem_slot(kvm, new); 1101a2ce7200SLaurent Dufour 1102a2ce7200SLaurent Dufour return ret; 1103a2ce7200SLaurent Dufour } 1104a2ce7200SLaurent Dufour 1105a2ce7200SLaurent Dufour void kvmppc_uvmem_memslot_delete(struct kvm *kvm, const struct kvm_memory_slot *old) 1106a2ce7200SLaurent Dufour { 1107a2ce7200SLaurent Dufour __kvmppc_uvmem_memslot_delete(kvm, old); 1108a2ce7200SLaurent Dufour } 1109a2ce7200SLaurent Dufour 1110ca9f4942SBharata B Rao static u64 kvmppc_get_secmem_size(void) 1111ca9f4942SBharata B Rao { 1112ca9f4942SBharata B Rao struct device_node *np; 1113ca9f4942SBharata B Rao int i, len; 1114ca9f4942SBharata B Rao const __be32 *prop; 1115ca9f4942SBharata B Rao u64 size = 0; 1116ca9f4942SBharata B Rao 1117512721d2SLaurent Dufour /* 1118512721d2SLaurent Dufour * First try the new ibm,secure-memory nodes which supersede the 1119512721d2SLaurent Dufour * secure-memory-ranges property. 1120512721d2SLaurent Dufour * If we found some, no need to read the deprecated ones. 1121512721d2SLaurent Dufour */ 1122512721d2SLaurent Dufour for_each_compatible_node(np, NULL, "ibm,secure-memory") { 1123512721d2SLaurent Dufour prop = of_get_property(np, "reg", &len); 1124512721d2SLaurent Dufour if (!prop) 1125512721d2SLaurent Dufour continue; 1126512721d2SLaurent Dufour size += of_read_number(prop + 2, 2); 1127512721d2SLaurent Dufour } 1128512721d2SLaurent Dufour if (size) 1129512721d2SLaurent Dufour return size; 1130512721d2SLaurent Dufour 1131ca9f4942SBharata B Rao np = of_find_compatible_node(NULL, NULL, "ibm,uv-firmware"); 1132ca9f4942SBharata B Rao if (!np) 1133ca9f4942SBharata B Rao goto out; 1134ca9f4942SBharata B Rao 1135ca9f4942SBharata B Rao prop = of_get_property(np, "secure-memory-ranges", &len); 1136ca9f4942SBharata B Rao if (!prop) 1137ca9f4942SBharata B Rao goto out_put; 1138ca9f4942SBharata B Rao 1139ca9f4942SBharata B Rao for (i = 0; i < len / (sizeof(*prop) * 4); i++) 1140ca9f4942SBharata B Rao size += of_read_number(prop + (i * 4) + 2, 2); 1141ca9f4942SBharata B Rao 1142ca9f4942SBharata B Rao out_put: 1143ca9f4942SBharata B Rao of_node_put(np); 1144ca9f4942SBharata B Rao out: 1145ca9f4942SBharata B Rao return size; 1146ca9f4942SBharata B Rao } 1147ca9f4942SBharata B Rao 1148ca9f4942SBharata B Rao int kvmppc_uvmem_init(void) 1149ca9f4942SBharata B Rao { 1150ca9f4942SBharata B Rao int ret = 0; 1151ca9f4942SBharata B Rao unsigned long size; 1152ca9f4942SBharata B Rao struct resource *res; 1153ca9f4942SBharata B Rao void *addr; 1154ca9f4942SBharata B Rao unsigned long pfn_last, pfn_first; 1155ca9f4942SBharata B Rao 1156ca9f4942SBharata B Rao size = kvmppc_get_secmem_size(); 1157ca9f4942SBharata B Rao if (!size) { 1158ca9f4942SBharata B Rao /* 1159ca9f4942SBharata B Rao * Don't fail the initialization of kvm-hv module if 1160ca9f4942SBharata B Rao * the platform doesn't export ibm,uv-firmware node. 1161ca9f4942SBharata B Rao * Let normal guests run on such PEF-disabled platform. 1162ca9f4942SBharata B Rao */ 1163ca9f4942SBharata B Rao pr_info("KVMPPC-UVMEM: No support for secure guests\n"); 1164ca9f4942SBharata B Rao goto out; 1165ca9f4942SBharata B Rao } 1166ca9f4942SBharata B Rao 1167ca9f4942SBharata B Rao res = request_free_mem_region(&iomem_resource, size, "kvmppc_uvmem"); 1168ca9f4942SBharata B Rao if (IS_ERR(res)) { 1169ca9f4942SBharata B Rao ret = PTR_ERR(res); 1170ca9f4942SBharata B Rao goto out; 1171ca9f4942SBharata B Rao } 1172ca9f4942SBharata B Rao 1173ca9f4942SBharata B Rao kvmppc_uvmem_pgmap.type = MEMORY_DEVICE_PRIVATE; 1174a4574f63SDan Williams kvmppc_uvmem_pgmap.range.start = res->start; 1175a4574f63SDan Williams kvmppc_uvmem_pgmap.range.end = res->end; 1176b7b3c01bSDan Williams kvmppc_uvmem_pgmap.nr_range = 1; 1177ca9f4942SBharata B Rao kvmppc_uvmem_pgmap.ops = &kvmppc_uvmem_ops; 1178f894ddd5SChristoph Hellwig /* just one global instance: */ 1179f894ddd5SChristoph Hellwig kvmppc_uvmem_pgmap.owner = &kvmppc_uvmem_pgmap; 1180ca9f4942SBharata B Rao addr = memremap_pages(&kvmppc_uvmem_pgmap, NUMA_NO_NODE); 1181ca9f4942SBharata B Rao if (IS_ERR(addr)) { 1182ca9f4942SBharata B Rao ret = PTR_ERR(addr); 1183ca9f4942SBharata B Rao goto out_free_region; 1184ca9f4942SBharata B Rao } 1185ca9f4942SBharata B Rao 1186ca9f4942SBharata B Rao pfn_first = res->start >> PAGE_SHIFT; 1187ca9f4942SBharata B Rao pfn_last = pfn_first + (resource_size(res) >> PAGE_SHIFT); 1188ca9f4942SBharata B Rao kvmppc_uvmem_bitmap = kcalloc(BITS_TO_LONGS(pfn_last - pfn_first), 1189ca9f4942SBharata B Rao sizeof(unsigned long), GFP_KERNEL); 1190ca9f4942SBharata B Rao if (!kvmppc_uvmem_bitmap) { 1191ca9f4942SBharata B Rao ret = -ENOMEM; 1192ca9f4942SBharata B Rao goto out_unmap; 1193ca9f4942SBharata B Rao } 1194ca9f4942SBharata B Rao 1195ca9f4942SBharata B Rao pr_info("KVMPPC-UVMEM: Secure Memory size 0x%lx\n", size); 1196ca9f4942SBharata B Rao return ret; 1197ca9f4942SBharata B Rao out_unmap: 1198ca9f4942SBharata B Rao memunmap_pages(&kvmppc_uvmem_pgmap); 1199ca9f4942SBharata B Rao out_free_region: 1200ca9f4942SBharata B Rao release_mem_region(res->start, size); 1201ca9f4942SBharata B Rao out: 1202ca9f4942SBharata B Rao return ret; 1203ca9f4942SBharata B Rao } 1204ca9f4942SBharata B Rao 1205ca9f4942SBharata B Rao void kvmppc_uvmem_free(void) 1206ca9f4942SBharata B Rao { 12079bee484bSFabiano Rosas if (!kvmppc_uvmem_bitmap) 12089bee484bSFabiano Rosas return; 12099bee484bSFabiano Rosas 1210ca9f4942SBharata B Rao memunmap_pages(&kvmppc_uvmem_pgmap); 1211a4574f63SDan Williams release_mem_region(kvmppc_uvmem_pgmap.range.start, 1212a4574f63SDan Williams range_len(&kvmppc_uvmem_pgmap.range)); 1213ca9f4942SBharata B Rao kfree(kvmppc_uvmem_bitmap); 1214ca9f4942SBharata B Rao } 1215