s390/kvm: support collaborative memory management

This patch enables Collaborative Memory Management (CMM) for kvm
on s390. CMM allows the guest to inform the host about page usage
(see arch/s390/mm/cmm.c). The host uses this information to avoid
swapping in unused pages in the page fault handler. Further, a CPU
provided list of unused invalid pages is processed to reclaim swap
space of not yet accessed unused pages.

[ Martin Schwidefsky: patch reordering and cleanup ]

Signed-off-by: Konstantin Weitz <konstantin.weitz@gmail.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
Konstantin Weitz
2013-04-17 17:36:29 +02:00
committed by Martin Schwidefsky
parent 45961722f8
commit b31288fa83
6 changed files with 175 additions and 1 deletions

View File

@@ -636,8 +636,49 @@ static int handle_pfmf(struct kvm_vcpu *vcpu)
return 0;
}
static int handle_essa(struct kvm_vcpu *vcpu)
{
/* entries expected to be 1FF */
int entries = (vcpu->arch.sie_block->cbrlo & ~PAGE_MASK) >> 3;
unsigned long *cbrlo, cbrle;
struct gmap *gmap;
int i;
VCPU_EVENT(vcpu, 5, "cmma release %d pages", entries);
gmap = vcpu->arch.gmap;
vcpu->stat.instruction_essa++;
if (!kvm_enabled_cmma() || !vcpu->arch.sie_block->cbrlo)
return kvm_s390_inject_program_int(vcpu, PGM_OPERATION);
if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
if (((vcpu->arch.sie_block->ipb & 0xf0000000) >> 28) > 6)
return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
/* Rewind PSW to repeat the ESSA instruction */
vcpu->arch.sie_block->gpsw.addr =
__rewind_psw(vcpu->arch.sie_block->gpsw, 4);
vcpu->arch.sie_block->cbrlo &= PAGE_MASK; /* reset nceo */
cbrlo = phys_to_virt(vcpu->arch.sie_block->cbrlo);
down_read(&gmap->mm->mmap_sem);
for (i = 0; i < entries; ++i) {
cbrle = cbrlo[i];
if (unlikely(cbrle & ~PAGE_MASK || cbrle < 2 * PAGE_SIZE))
/* invalid entry */
break;
/* try to free backing */
__gmap_zap(cbrle, gmap);
}
up_read(&gmap->mm->mmap_sem);
if (i < entries)
return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
return 0;
}
static const intercept_handler_t b9_handlers[256] = {
[0x8d] = handle_epsw,
[0xab] = handle_essa,
[0xaf] = handle_pfmf,
};