mirror of https://gitee.com/openkylin/linux.git
KVM: s390: fix memory slot handling for KVM_SET_USER_MEMORY_REGION
kselftests exposed a problem in the s390 handling for memory slots. Right now we only do proper memory slot handling for creation of new memory slots. Neither MOVE, nor DELETION are handled properly. Let us implement those. Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
2924b52117
commit
19ec166c3f
|
@ -4524,21 +4524,28 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
|
||||||
const struct kvm_memory_slot *new,
|
const struct kvm_memory_slot *new,
|
||||||
enum kvm_mr_change change)
|
enum kvm_mr_change change)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc = 0;
|
||||||
|
|
||||||
/* If the basics of the memslot do not change, we do not want
|
switch (change) {
|
||||||
* to update the gmap. Every update causes several unnecessary
|
case KVM_MR_DELETE:
|
||||||
* segment translation exceptions. This is usually handled just
|
rc = gmap_unmap_segment(kvm->arch.gmap, old->base_gfn * PAGE_SIZE,
|
||||||
* fine by the normal fault handler + gmap, but it will also
|
old->npages * PAGE_SIZE);
|
||||||
* cause faults on the prefix page of running guest CPUs.
|
break;
|
||||||
*/
|
case KVM_MR_MOVE:
|
||||||
if (old->userspace_addr == mem->userspace_addr &&
|
rc = gmap_unmap_segment(kvm->arch.gmap, old->base_gfn * PAGE_SIZE,
|
||||||
old->base_gfn * PAGE_SIZE == mem->guest_phys_addr &&
|
old->npages * PAGE_SIZE);
|
||||||
old->npages * PAGE_SIZE == mem->memory_size)
|
if (rc)
|
||||||
return;
|
break;
|
||||||
|
/* FALLTHROUGH */
|
||||||
rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr,
|
case KVM_MR_CREATE:
|
||||||
mem->guest_phys_addr, mem->memory_size);
|
rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr,
|
||||||
|
mem->guest_phys_addr, mem->memory_size);
|
||||||
|
break;
|
||||||
|
case KVM_MR_FLAGS_ONLY:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
WARN(1, "Unknown KVM MR CHANGE: %d\n", change);
|
||||||
|
}
|
||||||
if (rc)
|
if (rc)
|
||||||
pr_warn("failed to commit memory region\n");
|
pr_warn("failed to commit memory region\n");
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue