]>
Commit | Line | Data |
---|---|---|
fb43722c SL |
1 | From 9b42ad76df55bc578ce4845e931d809ad4098b38 Mon Sep 17 00:00:00 2001 |
2 | From: Christian Borntraeger <borntraeger@de.ibm.com> | |
3 | Date: Fri, 24 May 2019 16:06:23 +0200 | |
4 | Subject: KVM: s390: fix memory slot handling for KVM_SET_USER_MEMORY_REGION | |
5 | ||
6 | [ Upstream commit 19ec166c3f39fe1d3789888a74cc95544ac266d4 ] | |
7 | ||
8 | kselftests exposed a problem in the s390 handling for memory slots. | |
9 | Right now we only do proper memory slot handling for creation of new | |
10 | memory slots. Neither MOVE, nor DELETION are handled properly. Let us | |
11 | implement those. | |
12 | ||
13 | Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> | |
14 | Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> | |
15 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
16 | --- | |
17 | arch/s390/kvm/kvm-s390.c | 35 +++++++++++++++++++++-------------- | |
18 | 1 file changed, 21 insertions(+), 14 deletions(-) | |
19 | ||
20 | diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c | |
21 | index c4180ecfbb2a..ee35f1112db9 100644 | |
22 | --- a/arch/s390/kvm/kvm-s390.c | |
23 | +++ b/arch/s390/kvm/kvm-s390.c | |
24 | @@ -4413,21 +4413,28 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, | |
25 | const struct kvm_memory_slot *new, | |
26 | enum kvm_mr_change change) | |
27 | { | |
28 | - int rc; | |
29 | - | |
30 | - /* If the basics of the memslot do not change, we do not want | |
31 | - * to update the gmap. Every update causes several unnecessary | |
32 | - * segment translation exceptions. This is usually handled just | |
33 | - * fine by the normal fault handler + gmap, but it will also | |
34 | - * cause faults on the prefix page of running guest CPUs. | |
35 | - */ | |
36 | - if (old->userspace_addr == mem->userspace_addr && | |
37 | - old->base_gfn * PAGE_SIZE == mem->guest_phys_addr && | |
38 | - old->npages * PAGE_SIZE == mem->memory_size) | |
39 | - return; | |
40 | + int rc = 0; | |
41 | ||
42 | - rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr, | |
43 | - mem->guest_phys_addr, mem->memory_size); | |
44 | + switch (change) { | |
45 | + case KVM_MR_DELETE: | |
46 | + rc = gmap_unmap_segment(kvm->arch.gmap, old->base_gfn * PAGE_SIZE, | |
47 | + old->npages * PAGE_SIZE); | |
48 | + break; | |
49 | + case KVM_MR_MOVE: | |
50 | + rc = gmap_unmap_segment(kvm->arch.gmap, old->base_gfn * PAGE_SIZE, | |
51 | + old->npages * PAGE_SIZE); | |
52 | + if (rc) | |
53 | + break; | |
54 | + /* FALLTHROUGH */ | |
55 | + case KVM_MR_CREATE: | |
56 | + rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr, | |
57 | + mem->guest_phys_addr, mem->memory_size); | |
58 | + break; | |
59 | + case KVM_MR_FLAGS_ONLY: | |
60 | + break; | |
61 | + default: | |
62 | + WARN(1, "Unknown KVM MR CHANGE: %d\n", change); | |
63 | + } | |
64 | if (rc) | |
65 | pr_warn("failed to commit memory region\n"); | |
66 | return; | |
67 | -- | |
68 | 2.20.1 | |
69 |