[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 05/22] pseries: Use Book3S-HV TCE acceleration capab
From: |
Alexander Graf |
Subject: |
[Qemu-devel] [PATCH 05/22] pseries: Use Book3S-HV TCE acceleration capabilities |
Date: |
Sun, 30 Oct 2011 21:22:56 +0100 |
From: David Gibson <address@hidden>
The pseries machine of qemu implements the TCE mechanism used as a
virtual IOMMU for the PAPR defined virtual IO devices. Because the
PAPR spec only defines a small DMA address space, the guest VIO
drivers need to update TCE mappings very frequently - the virtual
network device is particularly bad. This means many slow exits to
qemu to emulate the H_PUT_TCE hypercall.
Sufficiently recent kernels allow this to be mitigated by implementing
H_PUT_TCE in the host kernel. To make use of this, however, qemu
needs to initialize the necessary TCE tables, and map them into itself
so that the VIO device implementations can retrieve the mappings when
they access guest memory (which is treated as a virtual DMA
operation).
This patch adds the necessary calls to use the KVM TCE acceleration.
If the kernel does not support acceleration, or there is some other
error creating the accelerated TCE table, then it will still fall back
to full userspace TCE implementation.
Signed-off-by: David Gibson <address@hidden>
Signed-off-by: Alexander Graf <address@hidden>
---
hw/spapr_vio.c | 8 ++++++-
hw/spapr_vio.h | 1 +
target-ppc/kvm.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++
target-ppc/kvm_ppc.h | 14 +++++++++++++
4 files changed, 76 insertions(+), 1 deletions(-)
diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index 35818e1..1da3032 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -165,7 +165,13 @@ static void rtce_init(VIOsPAPRDevice *dev)
* sizeof(VIOsPAPR_RTCE);
if (size) {
- dev->rtce_table = g_malloc0(size);
+ dev->rtce_table = kvmppc_create_spapr_tce(dev->reg,
+ dev->rtce_window_size,
+ &dev->kvmtce_fd);
+
+ if (!dev->rtce_table) {
+ dev->rtce_table = g_malloc0(size);
+ }
}
}
diff --git a/hw/spapr_vio.h b/hw/spapr_vio.h
index 4fe5f74..a325a5f 100644
--- a/hw/spapr_vio.h
+++ b/hw/spapr_vio.h
@@ -57,6 +57,7 @@ typedef struct VIOsPAPRDevice {
target_ulong signal_state;
uint32_t rtce_window_size;
VIOsPAPR_RTCE *rtce_table;
+ int kvmtce_fd;
VIOsPAPR_CRQ crq;
} VIOsPAPRDevice;
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index fd17d23..06cad41 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -28,6 +28,7 @@
#include "kvm_ppc.h"
#include "cpu.h"
#include "device_tree.h"
+#include "hw/sysbus.h"
#include "hw/spapr.h"
#include "hw/sysbus.h"
@@ -56,6 +57,7 @@ static int cap_segstate;
static int cap_booke_sregs;
static int cap_ppc_smt;
static int cap_ppc_rma;
+static int cap_spapr_tce;
/* 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
@@ -81,6 +83,7 @@ int kvm_arch_init(KVMState *s)
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);
+ cap_spapr_tce = kvm_check_extension(s, KVM_CAP_SPAPR_TCE);
if (!cap_interrupt_level) {
fprintf(stderr, "KVM: Couldn't find level irq capability. Expect the "
@@ -802,6 +805,57 @@ off_t kvmppc_alloc_rma(const char *name, MemoryRegion
*sysmem)
return size;
}
+void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd)
+{
+ struct kvm_create_spapr_tce args = {
+ .liobn = liobn,
+ .window_size = window_size,
+ };
+ long len;
+ int fd;
+ void *table;
+
+ if (!cap_spapr_tce) {
+ return NULL;
+ }
+
+ fd = kvm_vm_ioctl(kvm_state, KVM_CREATE_SPAPR_TCE, &args);
+ if (fd < 0) {
+ return NULL;
+ }
+
+ len = (window_size / SPAPR_VIO_TCE_PAGE_SIZE) * sizeof(VIOsPAPR_RTCE);
+ /* FIXME: round this up to page size */
+
+ table = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
+ if (table == MAP_FAILED) {
+ close(fd);
+ return NULL;
+ }
+
+ *pfd = fd;
+ return table;
+}
+
+int kvmppc_remove_spapr_tce(void *table, int fd, uint32_t window_size)
+{
+ long len;
+
+ if (fd < 0) {
+ return -1;
+ }
+
+ len = (window_size / SPAPR_VIO_TCE_PAGE_SIZE)*sizeof(VIOsPAPR_RTCE);
+ if ((munmap(table, len) < 0) ||
+ (close(fd) < 0)) {
+ fprintf(stderr, "KVM: Unexpected error removing KVM SPAPR TCE "
+ "table: %s", strerror(errno));
+ /* Leak the table */
+ }
+
+ return 0;
+}
+
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 82f32f4..87d1bdd 100644
--- a/target-ppc/kvm_ppc.h
+++ b/target-ppc/kvm_ppc.h
@@ -22,6 +22,8 @@ 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);
+void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd);
+int kvmppc_remove_spapr_tce(void *table, int pfd, uint32_t window_size);
#else
@@ -59,6 +61,18 @@ static inline off_t kvmppc_alloc_rma(const char *name,
MemoryRegion *sysmem)
return 0;
}
+static inline void *kvmppc_create_spapr_tce(uint32_t liobn,
+ uint32_t window_size, int *fd)
+{
+ return NULL;
+}
+
+static inline int kvmppc_remove_spapr_tce(void *table, int pfd,
+ uint32_t window_size)
+{
+ return -1;
+}
+
#endif
#ifndef CONFIG_KVM
--
1.6.0.2
- [Qemu-devel] [PULL 00/22] ppc patch queue 2011-10-30, Alexander Graf, 2011/10/30
- [Qemu-devel] [PATCH 02/22] ppc/e500_pci: Fix an array overflow issue, Alexander Graf, 2011/10/30
- [Qemu-devel] [PATCH 01/22] ppc/e500_pci: Fix code style, Alexander Graf, 2011/10/30
- [Qemu-devel] [PATCH 03/22] pseries: Support SMT systems for KVM Book3S-HV, Alexander Graf, 2011/10/30
- [Qemu-devel] [PATCH 04/22] pseries: Allow KVM Book3S-HV on PPC970 CPUS, Alexander Graf, 2011/10/30
- [Qemu-devel] [PATCH 05/22] pseries: Use Book3S-HV TCE acceleration capabilities,
Alexander Graf <=
- [Qemu-devel] [PATCH 06/22] pseries: Update SLOF firmware image, Alexander Graf, 2011/10/30
- [Qemu-devel] [PATCH 13/22] ppc: Add cpu defs for POWER7 revisions 2.1 and 2.3, Alexander Graf, 2011/10/30
- [Qemu-devel] [PATCH 09/22] pseries: Add device tree properties for VMX/VSX and DFP under kvm, Alexander Graf, 2011/10/30
- [Qemu-devel] [PATCH 15/22] PPC: Bump qemu-system-ppc to 64-bit physical address space, Alexander Graf, 2011/10/30
- [Qemu-devel] [PATCH 07/22] Set an invalid-bits mask for each SPE instructions, Alexander Graf, 2011/10/30
- [Qemu-devel] [PATCH 18/22] PPC: Fail configure when libfdt is not available, Alexander Graf, 2011/10/30
- [Qemu-devel] [PATCH 17/22] ppc: Avoid decrementer related kvm exits, Alexander Graf, 2011/10/30
- [Qemu-devel] [PATCH 11/22] ppc: Remove broken partial PVR matching, Alexander Graf, 2011/10/30
- [Qemu-devel] [PATCH 21/22] KVM: PPC: Override host vmx/vsx/dfp only when information known, Alexander Graf, 2011/10/30
- [Qemu-devel] [PATCH 14/22] pseries: Under kvm use guest cpu = host cpu by default, Alexander Graf, 2011/10/30