aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorChristian Borntraeger <borntraeger@de.ibm.com>2014-09-03 15:23:13 -0400
committerChristian Borntraeger <borntraeger@de.ibm.com>2014-09-10 06:19:42 -0400
commitf7a960affc6e5a33e8c7fcef065affc4f0461041 (patch)
tree4ffa230638dd30ef0f82201b3c3a6945bc4f35fd /arch/s390
parent6b331952f1bc2df61c98954e25578629c439e417 (diff)
KVM: s390/cmm: Fix prefix handling for diag 10 balloon
The old handling of prefix pages was broken in the diag10 ballooner. We now rely on gmap_discard to check for start > end and do a slow path if the prefix swap pages are affected: 1. discard the pages from start to prefix 2. discard the absolute 0 pages 3. discard the pages after prefix swap to end Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/kvm/diag.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c
index b374b6cb7785..9254afff250c 100644
--- a/arch/s390/kvm/diag.c
+++ b/arch/s390/kvm/diag.c
@@ -28,22 +28,32 @@ static int diag_release_pages(struct kvm_vcpu *vcpu)
28 start = vcpu->run->s.regs.gprs[(vcpu->arch.sie_block->ipa & 0xf0) >> 4]; 28 start = vcpu->run->s.regs.gprs[(vcpu->arch.sie_block->ipa & 0xf0) >> 4];
29 end = vcpu->run->s.regs.gprs[vcpu->arch.sie_block->ipa & 0xf] + 4096; 29 end = vcpu->run->s.regs.gprs[vcpu->arch.sie_block->ipa & 0xf] + 4096;
30 30
31 if (start & ~PAGE_MASK || end & ~PAGE_MASK || start > end 31 if (start & ~PAGE_MASK || end & ~PAGE_MASK || start >= end
32 || start < 2 * PAGE_SIZE) 32 || start < 2 * PAGE_SIZE)
33 return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); 33 return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
34 34
35 VCPU_EVENT(vcpu, 5, "diag release pages %lX %lX", start, end); 35 VCPU_EVENT(vcpu, 5, "diag release pages %lX %lX", start, end);
36 vcpu->stat.diagnose_10++; 36 vcpu->stat.diagnose_10++;
37 37
38 /* we checked for start > end above */ 38 /*
39 if (end < prefix || start >= prefix + 2 * PAGE_SIZE) { 39 * We checked for start >= end above, so lets check for the
40 * fast path (no prefix swap page involved)
41 */
42 if (end <= prefix || start >= prefix + 2 * PAGE_SIZE) {
40 gmap_discard(vcpu->arch.gmap, start, end); 43 gmap_discard(vcpu->arch.gmap, start, end);
41 } else { 44 } else {
42 if (start < prefix) 45 /*
43 gmap_discard(vcpu->arch.gmap, start, prefix); 46 * This is slow path. gmap_discard will check for start
44 if (end >= prefix) 47 * so lets split this into before prefix, prefix, after
45 gmap_discard(vcpu->arch.gmap, 48 * prefix and let gmap_discard make some of these calls
46 prefix + 2 * PAGE_SIZE, end); 49 * NOPs.
50 */
51 gmap_discard(vcpu->arch.gmap, start, prefix);
52 if (start <= prefix)
53 gmap_discard(vcpu->arch.gmap, 0, 4096);
54 if (end > prefix + 4096)
55 gmap_discard(vcpu->arch.gmap, 4096, 8192);
56 gmap_discard(vcpu->arch.gmap, prefix + 2 * PAGE_SIZE, end);
47 } 57 }
48 return 0; 58 return 0;
49} 59}