Skip to content

Commit a2ce720

Browse files
ldu4paulusmack
authored andcommitted
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 <[email protected]> Signed-off-by: Ram Pai <[email protected]> [rearranged the code, and modified the commit log] Signed-off-by: Laurent Dufour <[email protected]> Signed-off-by: Paul Mackerras <[email protected]>
1 parent dfaa973 commit a2ce720

File tree

3 files changed

+39
-12
lines changed

3 files changed

+39
-12
lines changed

arch/powerpc/include/asm/kvm_book3s_uvmem.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ int kvmppc_send_page_to_uv(struct kvm *kvm, unsigned long gfn);
2323
unsigned long kvmppc_h_svm_init_abort(struct kvm *kvm);
2424
void kvmppc_uvmem_drop_pages(const struct kvm_memory_slot *free,
2525
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);
2630
#else
2731
static inline int kvmppc_uvmem_init(void)
2832
{
@@ -82,5 +86,15 @@ static inline int kvmppc_send_page_to_uv(struct kvm *kvm, unsigned long gfn)
8286
static inline void
8387
kvmppc_uvmem_drop_pages(const struct kvm_memory_slot *free,
8488
struct kvm *kvm, bool skip_page_out) { }
89+
90+
static inline int kvmppc_uvmem_memslot_create(struct kvm *kvm,
91+
const struct kvm_memory_slot *new)
92+
{
93+
return H_UNSUPPORTED;
94+
}
95+
96+
static inline void kvmppc_uvmem_memslot_delete(struct kvm *kvm,
97+
const struct kvm_memory_slot *old) { }
98+
8599
#endif /* CONFIG_PPC_UV */
86100
#endif /* __ASM_KVM_BOOK3S_UVMEM_H__ */

arch/powerpc/kvm/book3s_hv.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4523,16 +4523,14 @@ static void kvmppc_core_commit_memory_region_hv(struct kvm *kvm,
45234523

45244524
switch (change) {
45254525
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);
45324531
break;
45334532
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);
45364534
break;
45374535
default:
45384536
/* TODO: Handle KVM_MR_MOVE */

arch/powerpc/kvm/book3s_hv_uvmem.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -418,15 +418,15 @@ static int kvmppc_memslot_page_merge(struct kvm *kvm,
418418
return ret;
419419
}
420420

421-
static void kvmppc_uvmem_memslot_delete(struct kvm *kvm,
421+
static void __kvmppc_uvmem_memslot_delete(struct kvm *kvm,
422422
const struct kvm_memory_slot *memslot)
423423
{
424424
uv_unregister_mem_slot(kvm->arch.lpid, memslot->id);
425425
kvmppc_uvmem_slot_free(kvm, memslot);
426426
kvmppc_memslot_page_merge(kvm, memslot, true);
427427
}
428428

429-
static int kvmppc_uvmem_memslot_create(struct kvm *kvm,
429+
static int __kvmppc_uvmem_memslot_create(struct kvm *kvm,
430430
const struct kvm_memory_slot *memslot)
431431
{
432432
int ret = H_PARAMETER;
@@ -478,7 +478,7 @@ unsigned long kvmppc_h_svm_init_start(struct kvm *kvm)
478478
/* register the memslot */
479479
slots = kvm_memslots(kvm);
480480
kvm_for_each_memslot(memslot, slots) {
481-
ret = kvmppc_uvmem_memslot_create(kvm, memslot);
481+
ret = __kvmppc_uvmem_memslot_create(kvm, memslot);
482482
if (ret)
483483
break;
484484
}
@@ -488,7 +488,7 @@ unsigned long kvmppc_h_svm_init_start(struct kvm *kvm)
488488
kvm_for_each_memslot(m, slots) {
489489
if (m == memslot)
490490
break;
491-
kvmppc_uvmem_memslot_delete(kvm, memslot);
491+
__kvmppc_uvmem_memslot_delete(kvm, memslot);
492492
}
493493
}
494494

@@ -1057,6 +1057,21 @@ int kvmppc_send_page_to_uv(struct kvm *kvm, unsigned long gfn)
10571057
return (ret == U_SUCCESS) ? RESUME_GUEST : -EFAULT;
10581058
}
10591059

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);
1073+
}
1074+
10601075
static u64 kvmppc_get_secmem_size(void)
10611076
{
10621077
struct device_node *np;

0 commit comments

Comments
 (0)