aboutsummaryrefslogtreecommitdiff
path: root/target-ppc
diff options
context:
space:
mode:
Diffstat (limited to 'target-ppc')
-rw-r--r--target-ppc/kvm.c44
-rw-r--r--target-ppc/kvm_ppc.h8
2 files changed, 52 insertions, 0 deletions
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 6c7ca6fc50..fd17d23d2e 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -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;
diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
index c298411aa8..82f32f449e 100644
--- a/target-ppc/kvm_ppc.h
+++ b/target-ppc/kvm_ppc.h
@@ -9,6 +9,8 @@
#ifndef __KVM_PPC_H__
#define __KVM_PPC_H__
+#include "memory.h"
+
void kvmppc_init(void);
#ifdef CONFIG_KVM
@@ -19,6 +21,7 @@ int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len);
int kvmppc_set_interrupt(CPUState *env, int irq, int level);
void kvmppc_set_papr(CPUState *env);
int kvmppc_smt_threads(void);
+off_t kvmppc_alloc_rma(const char *name, MemoryRegion *sysmem);
#else
@@ -51,6 +54,11 @@ static inline int kvmppc_smt_threads(void)
return 1;
}
+static inline off_t kvmppc_alloc_rma(const char *name, MemoryRegion *sysmem)
+{
+ return 0;
+}
+
#endif
#ifndef CONFIG_KVM