Blame SOURCES/kvm-target-ppc-kvm-make-use-of-KVM_CREATE_SPAPR_TCE_64.patch

76daa3
From 2882a6b553093b8018f0a14175cf8d7a5fcdb633 Mon Sep 17 00:00:00 2001
76daa3
From: David Gibson <dgibson@redhat.com>
76daa3
Date: Thu, 27 Apr 2017 01:16:30 +0200
76daa3
Subject: [PATCH 16/23] target-ppc: kvm: make use of KVM_CREATE_SPAPR_TCE_64
76daa3
76daa3
RH-Author: David Gibson <dgibson@redhat.com>
76daa3
Message-id: <20170427011630.389-1-dgibson@redhat.com>
76daa3
Patchwork-id: 74912
76daa3
O-Subject: [RHEL-7.4 qemu-kvm-rhev PATCH] target-ppc: kvm: make use of KVM_CREATE_SPAPR_TCE_64
76daa3
Bugzilla: 1440619
76daa3
RH-Acked-by: Thomas Huth <thuth@redhat.com>
76daa3
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
76daa3
RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
76daa3
76daa3
From: Alexey Kardashevskiy <aik@ozlabs.ru>
76daa3
76daa3
KVM_CAP_SPAPR_TCE capability allows creating TCE tables in KVM which
76daa3
allows having in-kernel acceleration for H_PUT_TCE_xxx hypercalls.
76daa3
However it only supports 32bit DMA windows at zero bus offset.
76daa3
76daa3
There is a new KVM_CAP_SPAPR_TCE_64 capability which supports 64bit
76daa3
window size, variable page size and bus offset.
76daa3
76daa3
This makes use of the new capability. The kernel headers are already
76daa3
updated as the kernel support went in to v4.6.
76daa3
76daa3
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
76daa3
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
76daa3
(cherry picked from commit d6ee2a7c85088d587fb0e0376fba1fa20d59c9f3)
76daa3
76daa3
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1440619
76daa3
Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=13095246
76daa3
76daa3
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
76daa3
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
76daa3
---
76daa3
 hw/ppc/spapr_iommu.c |  8 +++++---
76daa3
 target/ppc/kvm.c     | 48 +++++++++++++++++++++++++++++++++++++-----------
76daa3
 target/ppc/kvm_ppc.h | 12 +++++++-----
76daa3
 3 files changed, 49 insertions(+), 19 deletions(-)
76daa3
76daa3
diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
76daa3
index ae30bbe..29c80bb 100644
76daa3
--- a/hw/ppc/spapr_iommu.c
76daa3
+++ b/hw/ppc/spapr_iommu.c
76daa3
@@ -79,15 +79,16 @@ static IOMMUAccessFlags spapr_tce_iommu_access_flags(uint64_t tce)
76daa3
 
76daa3
 static uint64_t *spapr_tce_alloc_table(uint32_t liobn,
76daa3
                                        uint32_t page_shift,
76daa3
+                                       uint64_t bus_offset,
76daa3
                                        uint32_t nb_table,
76daa3
                                        int *fd,
76daa3
                                        bool need_vfio)
76daa3
 {
76daa3
     uint64_t *table = NULL;
76daa3
-    uint64_t window_size = (uint64_t)nb_table << page_shift;
76daa3
 
76daa3
-    if (kvm_enabled() && !(window_size >> 32)) {
76daa3
-        table = kvmppc_create_spapr_tce(liobn, window_size, fd, need_vfio);
76daa3
+    if (kvm_enabled()) {
76daa3
+        table = kvmppc_create_spapr_tce(liobn, page_shift, bus_offset, nb_table,
76daa3
+                                        fd, need_vfio);
76daa3
     }
76daa3
 
76daa3
     if (!table) {
76daa3
@@ -342,6 +343,7 @@ void spapr_tce_table_enable(sPAPRTCETable *tcet,
76daa3
     tcet->nb_table = nb_table;
76daa3
     tcet->table = spapr_tce_alloc_table(tcet->liobn,
76daa3
                                         tcet->page_shift,
76daa3
+                                        tcet->bus_offset,
76daa3
                                         tcet->nb_table,
76daa3
                                         &tcet->fd,
76daa3
                                         tcet->need_vfio);
76daa3
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
76daa3
index 9f1f132..031d31f 100644
76daa3
--- a/target/ppc/kvm.c
76daa3
+++ b/target/ppc/kvm.c
76daa3
@@ -73,6 +73,7 @@ static int cap_booke_sregs;
76daa3
 static int cap_ppc_smt;
76daa3
 static int cap_ppc_rma;
76daa3
 static int cap_spapr_tce;
76daa3
+static int cap_spapr_tce_64;
76daa3
 static int cap_spapr_multitce;
76daa3
 static int cap_spapr_vfio;
76daa3
 static int cap_hior;
76daa3
@@ -125,6 +126,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
76daa3
     cap_ppc_smt = kvm_check_extension(s, KVM_CAP_PPC_SMT);
76daa3
     cap_ppc_rma = kvm_check_extension(s, KVM_CAP_PPC_RMA);
76daa3
     cap_spapr_tce = kvm_check_extension(s, KVM_CAP_SPAPR_TCE);
76daa3
+    cap_spapr_tce_64 = kvm_check_extension(s, KVM_CAP_SPAPR_TCE_64);
76daa3
     cap_spapr_multitce = kvm_check_extension(s, KVM_CAP_SPAPR_MULTITCE);
76daa3
     cap_spapr_vfio = false;
76daa3
     cap_one_reg = kvm_check_extension(s, KVM_CAP_ONE_REG);
76daa3
@@ -2132,13 +2134,10 @@ bool kvmppc_spapr_use_multitce(void)
76daa3
     return cap_spapr_multitce;
76daa3
 }
76daa3
 
76daa3
-void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd,
76daa3
-                              bool need_vfio)
76daa3
+void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t page_shift,
76daa3
+                              uint64_t bus_offset, uint32_t nb_table,
76daa3
+                              int *pfd, bool need_vfio)
76daa3
 {
76daa3
-    struct kvm_create_spapr_tce args = {
76daa3
-        .liobn = liobn,
76daa3
-        .window_size = window_size,
76daa3
-    };
76daa3
     long len;
76daa3
     int fd;
76daa3
     void *table;
76daa3
@@ -2151,14 +2150,41 @@ void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd,
76daa3
         return NULL;
76daa3
     }
76daa3
 
76daa3
-    fd = kvm_vm_ioctl(kvm_state, KVM_CREATE_SPAPR_TCE, &args);
76daa3
-    if (fd < 0) {
76daa3
-        fprintf(stderr, "KVM: Failed to create TCE table for liobn 0x%x\n",
76daa3
-                liobn);
76daa3
+    if (cap_spapr_tce_64) {
76daa3
+        struct kvm_create_spapr_tce_64 args = {
76daa3
+            .liobn = liobn,
76daa3
+            .page_shift = page_shift,
76daa3
+            .offset = bus_offset >> page_shift,
76daa3
+            .size = nb_table,
76daa3
+            .flags = 0
76daa3
+        };
76daa3
+        fd = kvm_vm_ioctl(kvm_state, KVM_CREATE_SPAPR_TCE_64, &args);
76daa3
+        if (fd < 0) {
76daa3
+            fprintf(stderr,
76daa3
+                    "KVM: Failed to create TCE64 table for liobn 0x%x\n",
76daa3
+                    liobn);
76daa3
+            return NULL;
76daa3
+        }
76daa3
+    } else if (cap_spapr_tce) {
76daa3
+        uint64_t window_size = (uint64_t) nb_table << page_shift;
76daa3
+        struct kvm_create_spapr_tce args = {
76daa3
+            .liobn = liobn,
76daa3
+            .window_size = window_size,
76daa3
+        };
76daa3
+        if ((window_size != args.window_size) || bus_offset) {
76daa3
+            return NULL;
76daa3
+        }
76daa3
+        fd = kvm_vm_ioctl(kvm_state, KVM_CREATE_SPAPR_TCE, &args);
76daa3
+        if (fd < 0) {
76daa3
+            fprintf(stderr, "KVM: Failed to create TCE table for liobn 0x%x\n",
76daa3
+                    liobn);
76daa3
+            return NULL;
76daa3
+        }
76daa3
+    } else {
76daa3
         return NULL;
76daa3
     }
76daa3
 
76daa3
-    len = (window_size / SPAPR_TCE_PAGE_SIZE) * sizeof(uint64_t);
76daa3
+    len = nb_table * sizeof(uint64_t);
76daa3
     /* FIXME: round this up to page size */
76daa3
 
76daa3
     table = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
76daa3
diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
76daa3
index 8e9f42d..08ecf75 100644
76daa3
--- a/target/ppc/kvm_ppc.h
76daa3
+++ b/target/ppc/kvm_ppc.h
76daa3
@@ -36,8 +36,9 @@ int kvmppc_booke_watchdog_enable(PowerPCCPU *cpu);
76daa3
 #ifndef CONFIG_USER_ONLY
76daa3
 off_t kvmppc_alloc_rma(void **rma);
76daa3
 bool kvmppc_spapr_use_multitce(void);
76daa3
-void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd,
76daa3
-                              bool need_vfio);
76daa3
+void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t page_shift,
76daa3
+                              uint64_t bus_offset, uint32_t nb_table,
76daa3
+                              int *pfd, bool need_vfio);
76daa3
 int kvmppc_remove_spapr_tce(void *table, int pfd, uint32_t window_size);
76daa3
 int kvmppc_reset_htab(int shift_hint);
76daa3
 uint64_t kvmppc_rma_size(uint64_t current_size, unsigned int hash_shift);
76daa3
@@ -167,9 +168,10 @@ static inline bool kvmppc_spapr_use_multitce(void)
76daa3
     return false;
76daa3
 }
76daa3
 
76daa3
-static inline void *kvmppc_create_spapr_tce(uint32_t liobn,
76daa3
-                                            uint32_t window_size, int *fd,
76daa3
-                                            bool need_vfio)
76daa3
+static inline void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t page_shift,
76daa3
+                                            uint64_t bus_offset,
76daa3
+                                            uint32_t nb_table,
76daa3
+                                            int *pfd, bool need_vfio)
76daa3
 {
76daa3
     return NULL;
76daa3
 }
76daa3
-- 
76daa3
1.8.3.1
76daa3