Message ID | 1595534844-16188-6-git-send-email-linuxram@us.ibm.com (mailing list archive) |
---|---|
State | Not Applicable |
Headers | show |
Series | Migrate non-migrated pages of a SVM. | expand |
Context | Check | Description |
---|---|---|
snowpatch_ozlabs/apply_patch | success | Successfully applied on branch powerpc/merge (d6c13d397d6988ec3e6029cae9e80501364cf9cb) |
snowpatch_ozlabs/checkpatch | warning | total: 0 errors, 0 warnings, 6 checks, 96 lines checked |
snowpatch_ozlabs/needsstable | success | Patch has no Fixes tags |
On Thu, Jul 23, 2020 at 01:07:22PM -0700, Ram Pai wrote: > From: Laurent Dufour <ldufour@linux.ibm.com> > > 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. > > 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> > --- > arch/powerpc/include/asm/kvm_book3s_uvmem.h | 14 ++++++++++++++ > arch/powerpc/kvm/book3s_hv.c | 10 ++-------- > arch/powerpc/kvm/book3s_hv_uvmem.c | 23 +++++++++++++++++++---- > 3 files changed, 35 insertions(+), 12 deletions(-) > > diff --git a/arch/powerpc/include/asm/kvm_book3s_uvmem.h b/arch/powerpc/include/asm/kvm_book3s_uvmem.h > index f229ab5..59c17ca 100644 > --- a/arch/powerpc/include/asm/kvm_book3s_uvmem.h > +++ b/arch/powerpc/include/asm/kvm_book3s_uvmem.h > @@ -25,6 +25,10 @@ void kvmppc_uvmem_drop_pages(const struct kvm_memory_slot *free, > struct kvm *kvm, bool skip_page_out); > int kvmppc_uv_migrate_mem_slot(struct kvm *kvm, > const struct kvm_memory_slot *memslot); > +int kvmppc_uvmem_memslot_create(struct kvm *kvm, > + const struct kvm_memory_slot *new); > +void kvmppc_uvmem_memslot_delete(struct kvm *kvm, > + const struct kvm_memory_slot *old); > #else > static inline int kvmppc_uvmem_init(void) > { > @@ -84,5 +88,15 @@ static inline int kvmppc_send_page_to_uv(struct kvm *kvm, unsigned long gfn) > static inline void > kvmppc_uvmem_drop_pages(const struct kvm_memory_slot *free, > struct kvm *kvm, bool skip_page_out) { } > + > +static inline int kvmppc_uvmem_memslot_create(struct kvm *kvm, > + const struct kvm_memory_slot *new) > +{ > + return H_UNSUPPORTED; > +} > + > +static inline void kvmppc_uvmem_memslot_delete(struct kvm *kvm, > + const struct kvm_memory_slot *old) { } > + > #endif /* CONFIG_PPC_UV */ > #endif /* __ASM_KVM_BOOK3S_UVMEM_H__ */ > diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c > index d331b46..b1485ca 100644 > --- a/arch/powerpc/kvm/book3s_hv.c > +++ b/arch/powerpc/kvm/book3s_hv.c > @@ -4515,16 +4515,10 @@ static void kvmppc_core_commit_memory_region_hv(struct kvm *kvm, > > switch (change) { > case KVM_MR_CREATE: > - if (kvmppc_uvmem_slot_init(kvm, new)) > - return; > - uv_register_mem_slot(kvm->arch.lpid, > - new->base_gfn << PAGE_SHIFT, > - new->npages * PAGE_SIZE, > - 0, new->id); > + kvmppc_uvmem_memslot_create(kvm, new); Only concern is that kvmppc_uvmem_memslot_create() can fail due to multiple reasons but we ignore them and go ahead with memory hotplug. May be this hasn't been observed in reality but if we can note this as a TODO in the comments to dig further and explore the possibility of recovering from here, then Reviewed-by: Bharata B Rao <bharata@linux.ibm.com> Regards, Bharata.
diff --git a/arch/powerpc/include/asm/kvm_book3s_uvmem.h b/arch/powerpc/include/asm/kvm_book3s_uvmem.h index f229ab5..59c17ca 100644 --- a/arch/powerpc/include/asm/kvm_book3s_uvmem.h +++ b/arch/powerpc/include/asm/kvm_book3s_uvmem.h @@ -25,6 +25,10 @@ void kvmppc_uvmem_drop_pages(const struct kvm_memory_slot *free, struct kvm *kvm, bool skip_page_out); int kvmppc_uv_migrate_mem_slot(struct kvm *kvm, const struct kvm_memory_slot *memslot); +int kvmppc_uvmem_memslot_create(struct kvm *kvm, + const struct kvm_memory_slot *new); +void kvmppc_uvmem_memslot_delete(struct kvm *kvm, + const struct kvm_memory_slot *old); #else static inline int kvmppc_uvmem_init(void) { @@ -84,5 +88,15 @@ static inline int kvmppc_send_page_to_uv(struct kvm *kvm, unsigned long gfn) static inline void kvmppc_uvmem_drop_pages(const struct kvm_memory_slot *free, struct kvm *kvm, bool skip_page_out) { } + +static inline int kvmppc_uvmem_memslot_create(struct kvm *kvm, + const struct kvm_memory_slot *new) +{ + return H_UNSUPPORTED; +} + +static inline void kvmppc_uvmem_memslot_delete(struct kvm *kvm, + const struct kvm_memory_slot *old) { } + #endif /* CONFIG_PPC_UV */ #endif /* __ASM_KVM_BOOK3S_UVMEM_H__ */ diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index d331b46..b1485ca 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -4515,16 +4515,10 @@ static void kvmppc_core_commit_memory_region_hv(struct kvm *kvm, switch (change) { case KVM_MR_CREATE: - if (kvmppc_uvmem_slot_init(kvm, new)) - return; - uv_register_mem_slot(kvm->arch.lpid, - new->base_gfn << PAGE_SHIFT, - new->npages * PAGE_SIZE, - 0, new->id); + kvmppc_uvmem_memslot_create(kvm, new); break; case KVM_MR_DELETE: - uv_unregister_mem_slot(kvm->arch.lpid, old->id); - kvmppc_uvmem_slot_free(kvm, old); + kvmppc_uvmem_memslot_delete(kvm, old); break; default: /* TODO: Handle KVM_MR_MOVE */ diff --git a/arch/powerpc/kvm/book3s_hv_uvmem.c b/arch/powerpc/kvm/book3s_hv_uvmem.c index 43b3566..fd9ff6e 100644 --- a/arch/powerpc/kvm/book3s_hv_uvmem.c +++ b/arch/powerpc/kvm/book3s_hv_uvmem.c @@ -418,7 +418,7 @@ static int kvmppc_memslot_page_merge(struct kvm *kvm, return ret; } -static void kvmppc_uvmem_memslot_delete(struct kvm *kvm, +static void __kvmppc_uvmem_memslot_delete(struct kvm *kvm, const struct kvm_memory_slot *memslot) { uv_unregister_mem_slot(kvm->arch.lpid, memslot->id); @@ -426,7 +426,7 @@ static void kvmppc_uvmem_memslot_delete(struct kvm *kvm, kvmppc_memslot_page_merge(kvm, memslot, true); } -static int kvmppc_uvmem_memslot_create(struct kvm *kvm, +static int __kvmppc_uvmem_memslot_create(struct kvm *kvm, const struct kvm_memory_slot *memslot) { int ret = H_PARAMETER; @@ -478,7 +478,7 @@ unsigned long kvmppc_h_svm_init_start(struct kvm *kvm) /* register the memslot */ slots = kvm_memslots(kvm); kvm_for_each_memslot(memslot, slots) { - ret = kvmppc_uvmem_memslot_create(kvm, memslot); + ret = __kvmppc_uvmem_memslot_create(kvm, memslot); if (ret) break; } @@ -488,7 +488,7 @@ unsigned long kvmppc_h_svm_init_start(struct kvm *kvm) kvm_for_each_memslot(m, slots) { if (m == memslot) break; - kvmppc_uvmem_memslot_delete(kvm, memslot); + __kvmppc_uvmem_memslot_delete(kvm, memslot); } } @@ -1057,6 +1057,21 @@ int kvmppc_send_page_to_uv(struct kvm *kvm, unsigned long gfn) return (ret == U_SUCCESS) ? RESUME_GUEST : -EFAULT; } +int kvmppc_uvmem_memslot_create(struct kvm *kvm, const struct kvm_memory_slot *new) +{ + int ret = __kvmppc_uvmem_memslot_create(kvm, new); + + if (!ret) + ret = kvmppc_uv_migrate_mem_slot(kvm, new); + + return ret; +} + +void kvmppc_uvmem_memslot_delete(struct kvm *kvm, const struct kvm_memory_slot *old) +{ + __kvmppc_uvmem_memslot_delete(kvm, old); +} + static u64 kvmppc_get_secmem_size(void) { struct device_node *np;