aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Borntraeger <borntraeger@de.ibm.com>2019-05-24 10:06:23 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2019-05-24 15:27:14 -0400
commit19ec166c3f39fe1d3789888a74cc95544ac266d4 (patch)
treee2605e8deec6c7f90081d063ab4491ba1202dc1f
parent2924b52117b2812e9633d5ea337333299166d373 (diff)
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>
-rw-r--r--arch/s390/kvm/kvm-s390.c35
1 files changed, 21 insertions, 14 deletions
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index ac6163c334d6..e5e8eb29e68e 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -4524,21 +4524,28 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
4524 const struct kvm_memory_slot *new, 4524 const struct kvm_memory_slot *new,
4525 enum kvm_mr_change change) 4525 enum kvm_mr_change change)
4526{ 4526{
4527 int rc; 4527 int rc = 0;
4528
4529 /* If the basics of the memslot do not change, we do not want
4530 * to update the gmap. Every update causes several unnecessary
4531 * segment translation exceptions. This is usually handled just
4532 * fine by the normal fault handler + gmap, but it will also
4533 * cause faults on the prefix page of running guest CPUs.
4534 */
4535 if (old->userspace_addr == mem->userspace_addr &&
4536 old->base_gfn * PAGE_SIZE == mem->guest_phys_addr &&
4537 old->npages * PAGE_SIZE == mem->memory_size)
4538 return;
4539 4528
4540 rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr, 4529 switch (change) {
4541 mem->guest_phys_addr, mem->memory_size); 4530 case KVM_MR_DELETE:
4531 rc = gmap_unmap_segment(kvm->arch.gmap, old->base_gfn * PAGE_SIZE,
4532 old->npages * PAGE_SIZE);
4533 break;
4534 case KVM_MR_MOVE:
4535 rc = gmap_unmap_segment(kvm->arch.gmap, old->base_gfn * PAGE_SIZE,
4536 old->npages * PAGE_SIZE);
4537 if (rc)
4538 break;
4539 /* FALLTHROUGH */
4540 case KVM_MR_CREATE:
4541 rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr,
4542 mem->guest_phys_addr, mem->memory_size);
4543 break;
4544 case KVM_MR_FLAGS_ONLY:
4545 break;
4546 default:
4547 WARN(1, "Unknown KVM MR CHANGE: %d\n", change);
4548 }
4542 if (rc) 4549 if (rc)
4543 pr_warn("failed to commit memory region\n"); 4550 pr_warn("failed to commit memory region\n");
4544 return; 4551 return;