pseries: Allow KVM Book3S-HV on PPC970 CPUS

At present, using the hypervisor aware Book3S-HV KVM will only work
with qemu on POWER7 CPUs.  PPC970 CPUs also have hypervisor
capability, but they lack the VRMA feature which makes assigning guest
memory easier.

In order to allow KVM Book3S-HV on PPC970, we need to specially
allocate the first chunk of guest memory (the "Real Mode Area" or
RMA), so that it is physically contiguous.

Sufficiently recent host kernels allow such contiguous RMAs to be
allocated, with a kvm capability advertising whether the feature is
available and/or necessary on this hardware.  This patch enables qemu
to use this support, thus allowing kvm acceleration of pseries qemu
machines on PPC970 hardware.

Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>

---

agraf: fix to use memory api
This commit is contained in:
David Gibson 2011-09-29 21:39:11 +00:00 committed by Alexander Graf
parent e97c363638
commit 354ac20a36
3 changed files with 96 additions and 12 deletions

View file

@ -55,6 +55,7 @@ static int cap_interrupt_level = false;
static int cap_segstate;
static int cap_booke_sregs;
static int cap_ppc_smt;
static int cap_ppc_rma;
/* XXX We have a race condition where we actually have a level triggered
* interrupt, but the infrastructure can't expose that yet, so the guest
@ -79,6 +80,7 @@ int kvm_arch_init(KVMState *s)
cap_segstate = kvm_check_extension(s, KVM_CAP_PPC_SEGSTATE);
cap_booke_sregs = kvm_check_extension(s, KVM_CAP_PPC_BOOKE_SREGS);
cap_ppc_smt = kvm_check_extension(s, KVM_CAP_PPC_SMT);
cap_ppc_rma = kvm_check_extension(s, KVM_CAP_PPC_RMA);
if (!cap_interrupt_level) {
fprintf(stderr, "KVM: Couldn't find level irq capability. Expect the "
@ -758,6 +760,48 @@ int kvmppc_smt_threads(void)
return cap_ppc_smt ? cap_ppc_smt : 1;
}
off_t kvmppc_alloc_rma(const char *name, MemoryRegion *sysmem)
{
void *rma;
off_t size;
int fd;
struct kvm_allocate_rma ret;
MemoryRegion *rma_region;
/* If cap_ppc_rma == 0, contiguous RMA allocation is not supported
* if cap_ppc_rma == 1, contiguous RMA allocation is supported, but
* not necessary on this hardware
* if cap_ppc_rma == 2, contiguous RMA allocation is needed on this hardware
*
* FIXME: We should allow the user to force contiguous RMA
* allocation in the cap_ppc_rma==1 case.
*/
if (cap_ppc_rma < 2) {
return 0;
}
fd = kvm_vm_ioctl(kvm_state, KVM_ALLOCATE_RMA, &ret);
if (fd < 0) {
fprintf(stderr, "KVM: Error on KVM_ALLOCATE_RMA: %s\n",
strerror(errno));
return -1;
}
size = MIN(ret.rma_size, 256ul << 20);
rma = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (rma == MAP_FAILED) {
fprintf(stderr, "KVM: Error mapping RMA: %s\n", strerror(errno));
return -1;
};
rma_region = g_new(MemoryRegion, 1);
memory_region_init_ram_ptr(rma_region, NULL, name, size, rma);
memory_region_add_subregion(sysmem, 0, rma_region);
return size;
}
bool kvm_arch_stop_on_emulation_error(CPUState *env)
{
return true;