[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-ppc] [PATCH 3/3] spapr vfio: supporting realmode iommu acceleratio
From: |
Alexey Kardashevskiy |
Subject: |
[Qemu-ppc] [PATCH 3/3] spapr vfio: supporting realmode iommu acceleration |
Date: |
Tue, 19 Feb 2013 18:43:37 +1100 |
Normally TCE request coming from the guest are routed to QEMU
by the host kernel. Since this way slows DMA operations, the host
kernel may support a real mode acceleration.
In order to use it, the host kernel supports new KVM_CAP_SPAPR_TCE_IOMMU
capability and KVM_CREATE_SPAPR_TCE_IOMMU ioctl which lets QEMU tell
the host what LIOBN is used for an IOMMU group.
Signed-off-by: Alexey Kardashevskiy <address@hidden>
---
linux-headers/asm-powerpc/kvm.h | 8 ++++++++
linux-headers/linux/kvm.h | 2 ++
target-ppc/kvm.c | 24 ++++++++++++++++++++++++
target-ppc/kvm_ppc.h | 1 +
4 files changed, 35 insertions(+)
diff --git a/linux-headers/asm-powerpc/kvm.h b/linux-headers/asm-powerpc/kvm.h
index 3c1bfb3..d53c8f2 100644
--- a/linux-headers/asm-powerpc/kvm.h
+++ b/linux-headers/asm-powerpc/kvm.h
@@ -291,6 +291,14 @@ struct kvm_create_spapr_tce {
__u32 window_size;
};
+/* for KVM_CAP_SPAPR_TCE_IOMMU */
+struct kvm_create_spapr_tce_iommu {
+ __u64 liobn;
+ __u32 iommu_id;
+#define SPAPR_TCE_PUT_TCE_VIRTMODE_ONLY 1 /* for debug purposes */
+ __u32 flags;
+};
+
/* for KVM_ALLOCATE_RMA */
struct kvm_allocate_rma {
__u64 rma_size;
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index 8aff3b0..a665fc7 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -634,6 +634,7 @@ struct kvm_ppc_smmu_info {
#define KVM_CAP_SPAPR_XICS 85
#define KVM_CAP_PPC_HTAB_FD 86
#define KVM_CAP_PPC_MULTITCE 87
+#define KVM_CAP_SPAPR_TCE_IOMMU 88
#ifdef KVM_CAP_IRQ_ROUTING
@@ -883,6 +884,7 @@ struct kvm_s390_ucas_mapping {
#endif
#define KVM_IRQCHIP_GET_SOURCES _IOW(KVMIO, 0xad, struct
kvm_irq_sources)
#define KVM_IRQCHIP_SET_SOURCES _IOW(KVMIO, 0xae, struct
kvm_irq_sources)
+#define KVM_CREATE_SPAPR_TCE_IOMMU _IOW(KVMIO, 0xaf, struct
kvm_create_spapr_tce_iommu)
/*
* ioctls for vcpu fds
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 11c2689..3cfa770 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -60,6 +60,7 @@ static int cap_booke_sregs;
static int cap_ppc_smt;
static int cap_ppc_rma;
static int cap_spapr_tce;
+static int cap_spapr_tce_iommu;
static int cap_one_reg;
static int cap_htab_fd;
@@ -90,6 +91,7 @@ int kvm_arch_init(KVMState *s)
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);
+ cap_spapr_tce_iommu = kvm_check_extension(s, KVM_CAP_SPAPR_TCE_IOMMU);
/* This capability is misnamed - it was introduced with the
* KVM_SET_ONE_REG ioctl(), which at the time only supported the
* HIOR. We don't want a different capability for every register
@@ -1478,6 +1480,28 @@ int kvmppc_remove_spapr_tce(void *table, int fd,
uint32_t window_size)
return 0;
}
+int kvmppc_create_spapr_tce_iommu(uint32_t liobn, uint32_t iommu_id)
+{
+ int ret = 0;
+ struct kvm_create_spapr_tce_iommu args = {
+ .liobn = liobn,
+ .iommu_id = iommu_id,
+ /* .flags = SPAPR_TCE_PUT_TCE_VIRTMODE_ONLY */
+ };
+
+ if (!cap_spapr_tce_iommu) {
+ fprintf(stderr, "KVM VFIO: TCE IOMMU capability is not present, DMA
may be slow\n");
+ return -1;
+ }
+
+ ret = kvm_vm_ioctl(kvm_state, KVM_CREATE_SPAPR_TCE_IOMMU, &args);
+ if (ret < 0)
+ fprintf(stderr, "KVM VFIO: Failed to create TCE table for liobn 0x%x,
ret = %d, DMA may be slow\n",
+ liobn, ret);
+
+ return ret;
+}
+
int kvmppc_reset_htab(int shift_hint)
{
uint32_t shift = shift_hint;
diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
index 63a438a..225a173 100644
--- a/target-ppc/kvm_ppc.h
+++ b/target-ppc/kvm_ppc.h
@@ -29,6 +29,7 @@ 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);
+int kvmppc_create_spapr_tce_iommu(uint32_t liobn, uint32_t iommu_id);
int kvmppc_reset_htab(int shift_hint);
uint64_t kvmppc_rma_size(uint64_t current_size, unsigned int hash_shift);
#endif /* !CONFIG_USER_ONLY */
--
1.7.10.4