mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
dfaa973ae9
commit
a2ce720038
|
@ -23,6 +23,10 @@ int kvmppc_send_page_to_uv(struct kvm *kvm, unsigned long gfn);
|
|||
unsigned long kvmppc_h_svm_init_abort(struct kvm *kvm);
|
||||
void kvmppc_uvmem_drop_pages(const struct kvm_memory_slot *free,
|
||||
struct kvm *kvm, bool skip_page_out);
|
||||
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)
|
||||
{
|
||||
|
@ -82,5 +86,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__ */
|
||||
|
|
|
@ -4523,16 +4523,14 @@ 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);
|
||||
/*
|
||||
* @TODO kvmppc_uvmem_memslot_create() can fail and
|
||||
* return error. Fix this.
|
||||
*/
|
||||
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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue