Skip to content

Commit

Permalink
KVM: s390/cmm: Fix prefix handling for diag 10 balloon
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Thomas Huth <[email protected]>
  • Loading branch information
borntraeger committed Sep 10, 2014
1 parent 6b33195 commit f7a960a
Showing 1 changed file with 18 additions and 8 deletions.
26 changes: 18 additions & 8 deletions arch/s390/kvm/diag.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,32 @@ static int diag_release_pages(struct kvm_vcpu *vcpu)
start = vcpu->run->s.regs.gprs[(vcpu->arch.sie_block->ipa & 0xf0) >> 4];
end = vcpu->run->s.regs.gprs[vcpu->arch.sie_block->ipa & 0xf] + 4096;

if (start & ~PAGE_MASK || end & ~PAGE_MASK || start > end
if (start & ~PAGE_MASK || end & ~PAGE_MASK || start >= end
|| start < 2 * PAGE_SIZE)
return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);

VCPU_EVENT(vcpu, 5, "diag release pages %lX %lX", start, end);
vcpu->stat.diagnose_10++;

/* we checked for start > end above */
if (end < prefix || start >= prefix + 2 * PAGE_SIZE) {
/*
* We checked for start >= end above, so lets check for the
* fast path (no prefix swap page involved)
*/
if (end <= prefix || start >= prefix + 2 * PAGE_SIZE) {
gmap_discard(vcpu->arch.gmap, start, end);
} else {
if (start < prefix)
gmap_discard(vcpu->arch.gmap, start, prefix);
if (end >= prefix)
gmap_discard(vcpu->arch.gmap,
prefix + 2 * PAGE_SIZE, end);
/*
* This is slow path. gmap_discard will check for start
* so lets split this into before prefix, prefix, after
* prefix and let gmap_discard make some of these calls
* NOPs.
*/
gmap_discard(vcpu->arch.gmap, start, prefix);
if (start <= prefix)
gmap_discard(vcpu->arch.gmap, 0, 4096);
if (end > prefix + 4096)
gmap_discard(vcpu->arch.gmap, 4096, 8192);
gmap_discard(vcpu->arch.gmap, prefix + 2 * PAGE_SIZE, end);
}
return 0;
}
Expand Down

0 comments on commit f7a960a

Please sign in to comment.