mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 01:49:46 +00:00
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:
committed by
Paul Mackerras
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);
|
unsigned long kvmppc_h_svm_init_abort(struct kvm *kvm);
|
||||||
void kvmppc_uvmem_drop_pages(const struct kvm_memory_slot *free,
|
void kvmppc_uvmem_drop_pages(const struct kvm_memory_slot *free,
|
||||||
struct kvm *kvm, bool skip_page_out);
|
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
|
#else
|
||||||
static inline int kvmppc_uvmem_init(void)
|
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
|
static inline void
|
||||||
kvmppc_uvmem_drop_pages(const struct kvm_memory_slot *free,
|
kvmppc_uvmem_drop_pages(const struct kvm_memory_slot *free,
|
||||||
struct kvm *kvm, bool skip_page_out) { }
|
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 /* CONFIG_PPC_UV */
|
||||||
#endif /* __ASM_KVM_BOOK3S_UVMEM_H__ */
|
#endif /* __ASM_KVM_BOOK3S_UVMEM_H__ */
|
||||||
|
|||||||
@@ -4523,16 +4523,14 @@ static void kvmppc_core_commit_memory_region_hv(struct kvm *kvm,
|
|||||||
|
|
||||||
switch (change) {
|
switch (change) {
|
||||||
case KVM_MR_CREATE:
|
case KVM_MR_CREATE:
|
||||||
if (kvmppc_uvmem_slot_init(kvm, new))
|
/*
|
||||||
return;
|
* @TODO kvmppc_uvmem_memslot_create() can fail and
|
||||||
uv_register_mem_slot(kvm->arch.lpid,
|
* return error. Fix this.
|
||||||
new->base_gfn << PAGE_SHIFT,
|
*/
|
||||||
new->npages * PAGE_SIZE,
|
kvmppc_uvmem_memslot_create(kvm, new);
|
||||||
0, new->id);
|
|
||||||
break;
|
break;
|
||||||
case KVM_MR_DELETE:
|
case KVM_MR_DELETE:
|
||||||
uv_unregister_mem_slot(kvm->arch.lpid, old->id);
|
kvmppc_uvmem_memslot_delete(kvm, old);
|
||||||
kvmppc_uvmem_slot_free(kvm, old);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* TODO: Handle KVM_MR_MOVE */
|
/* TODO: Handle KVM_MR_MOVE */
|
||||||
|
|||||||
@@ -418,7 +418,7 @@ static int kvmppc_memslot_page_merge(struct kvm *kvm,
|
|||||||
return ret;
|
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)
|
const struct kvm_memory_slot *memslot)
|
||||||
{
|
{
|
||||||
uv_unregister_mem_slot(kvm->arch.lpid, memslot->id);
|
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);
|
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)
|
const struct kvm_memory_slot *memslot)
|
||||||
{
|
{
|
||||||
int ret = H_PARAMETER;
|
int ret = H_PARAMETER;
|
||||||
@@ -478,7 +478,7 @@ unsigned long kvmppc_h_svm_init_start(struct kvm *kvm)
|
|||||||
/* register the memslot */
|
/* register the memslot */
|
||||||
slots = kvm_memslots(kvm);
|
slots = kvm_memslots(kvm);
|
||||||
kvm_for_each_memslot(memslot, slots) {
|
kvm_for_each_memslot(memslot, slots) {
|
||||||
ret = kvmppc_uvmem_memslot_create(kvm, memslot);
|
ret = __kvmppc_uvmem_memslot_create(kvm, memslot);
|
||||||
if (ret)
|
if (ret)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -488,7 +488,7 @@ unsigned long kvmppc_h_svm_init_start(struct kvm *kvm)
|
|||||||
kvm_for_each_memslot(m, slots) {
|
kvm_for_each_memslot(m, slots) {
|
||||||
if (m == memslot)
|
if (m == memslot)
|
||||||
break;
|
break;
|
||||||
kvmppc_uvmem_memslot_delete(kvm, memslot);
|
__kvmppc_uvmem_memslot_delete(kvm, memslot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1057,6 +1057,21 @@ out:
|
|||||||
return (ret == U_SUCCESS) ? RESUME_GUEST : -EFAULT;
|
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)
|
static u64 kvmppc_get_secmem_size(void)
|
||||||
{
|
{
|
||||||
struct device_node *np;
|
struct device_node *np;
|
||||||
|
|||||||
Reference in New Issue
Block a user