Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

KVM: PPC: Book3S HV: Migrate hot plugged memory

When a memory slot is hot plugged to a SVM, PFNs associated with the
GFNs in that slot must be migrated to the secure-PFNs, aka device-PFNs.

Call kvmppc_uv_migrate_mem_slot() to accomplish this.
Disable page-merge for all pages in the memory slot.

Reviewed-by: Bharata B Rao <bharata@linux.ibm.com>
Signed-off-by: Ram Pai <linuxram@us.ibm.com>
[rearranged the code, and modified the commit log]
Signed-off-by: Laurent Dufour <ldufour@linux.ibm.com>
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>

authored by

Laurent Dufour and committed by
Paul Mackerras
a2ce7200 dfaa973a

+39 -12
+14
arch/powerpc/include/asm/kvm_book3s_uvmem.h
··· 23 23 unsigned long kvmppc_h_svm_init_abort(struct kvm *kvm); 24 24 void kvmppc_uvmem_drop_pages(const struct kvm_memory_slot *free, 25 25 struct kvm *kvm, bool skip_page_out); 26 + int kvmppc_uvmem_memslot_create(struct kvm *kvm, 27 + const struct kvm_memory_slot *new); 28 + void kvmppc_uvmem_memslot_delete(struct kvm *kvm, 29 + const struct kvm_memory_slot *old); 26 30 #else 27 31 static inline int kvmppc_uvmem_init(void) 28 32 { ··· 86 82 static inline void 87 83 kvmppc_uvmem_drop_pages(const struct kvm_memory_slot *free, 88 84 struct kvm *kvm, bool skip_page_out) { } 85 + 86 + static inline int kvmppc_uvmem_memslot_create(struct kvm *kvm, 87 + const struct kvm_memory_slot *new) 88 + { 89 + return H_UNSUPPORTED; 90 + } 91 + 92 + static inline void kvmppc_uvmem_memslot_delete(struct kvm *kvm, 93 + const struct kvm_memory_slot *old) { } 94 + 89 95 #endif /* CONFIG_PPC_UV */ 90 96 #endif /* __ASM_KVM_BOOK3S_UVMEM_H__ */
+6 -8
arch/powerpc/kvm/book3s_hv.c
··· 4523 4523 4524 4524 switch (change) { 4525 4525 case KVM_MR_CREATE: 4526 - if (kvmppc_uvmem_slot_init(kvm, new)) 4527 - return; 4528 - uv_register_mem_slot(kvm->arch.lpid, 4529 - new->base_gfn << PAGE_SHIFT, 4530 - new->npages * PAGE_SIZE, 4531 - 0, new->id); 4526 + /* 4527 + * @TODO kvmppc_uvmem_memslot_create() can fail and 4528 + * return error. Fix this. 4529 + */ 4530 + kvmppc_uvmem_memslot_create(kvm, new); 4532 4531 break; 4533 4532 case KVM_MR_DELETE: 4534 - uv_unregister_mem_slot(kvm->arch.lpid, old->id); 4535 - kvmppc_uvmem_slot_free(kvm, old); 4533 + kvmppc_uvmem_memslot_delete(kvm, old); 4536 4534 break; 4537 4535 default: 4538 4536 /* TODO: Handle KVM_MR_MOVE */
+19 -4
arch/powerpc/kvm/book3s_hv_uvmem.c
··· 418 418 return ret; 419 419 } 420 420 421 - static void kvmppc_uvmem_memslot_delete(struct kvm *kvm, 421 + static void __kvmppc_uvmem_memslot_delete(struct kvm *kvm, 422 422 const struct kvm_memory_slot *memslot) 423 423 { 424 424 uv_unregister_mem_slot(kvm->arch.lpid, memslot->id); ··· 426 426 kvmppc_memslot_page_merge(kvm, memslot, true); 427 427 } 428 428 429 - static int kvmppc_uvmem_memslot_create(struct kvm *kvm, 429 + static int __kvmppc_uvmem_memslot_create(struct kvm *kvm, 430 430 const struct kvm_memory_slot *memslot) 431 431 { 432 432 int ret = H_PARAMETER; ··· 478 478 /* register the memslot */ 479 479 slots = kvm_memslots(kvm); 480 480 kvm_for_each_memslot(memslot, slots) { 481 - ret = kvmppc_uvmem_memslot_create(kvm, memslot); 481 + ret = __kvmppc_uvmem_memslot_create(kvm, memslot); 482 482 if (ret) 483 483 break; 484 484 } ··· 488 488 kvm_for_each_memslot(m, slots) { 489 489 if (m == memslot) 490 490 break; 491 - kvmppc_uvmem_memslot_delete(kvm, memslot); 491 + __kvmppc_uvmem_memslot_delete(kvm, memslot); 492 492 } 493 493 } 494 494 ··· 1055 1055 kvm_release_pfn_clean(pfn); 1056 1056 mutex_unlock(&kvm->arch.uvmem_lock); 1057 1057 return (ret == U_SUCCESS) ? RESUME_GUEST : -EFAULT; 1058 + } 1059 + 1060 + int kvmppc_uvmem_memslot_create(struct kvm *kvm, const struct kvm_memory_slot *new) 1061 + { 1062 + int ret = __kvmppc_uvmem_memslot_create(kvm, new); 1063 + 1064 + if (!ret) 1065 + ret = kvmppc_uv_migrate_mem_slot(kvm, new); 1066 + 1067 + return ret; 1068 + } 1069 + 1070 + void kvmppc_uvmem_memslot_delete(struct kvm *kvm, const struct kvm_memory_slot *old) 1071 + { 1072 + __kvmppc_uvmem_memslot_delete(kvm, old); 1058 1073 } 1059 1074 1060 1075 static u64 kvmppc_get_secmem_size(void)