summaryrefslogtreecommitdiffstats
path: root/qemu/hw/ppc/spapr_iommu.c
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/hw/ppc/spapr_iommu.c')
-rw-r--r--qemu/hw/ppc/spapr_iommu.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/qemu/hw/ppc/spapr_iommu.c b/qemu/hw/ppc/spapr_iommu.c
index f61504e0c..7dd458846 100644
--- a/qemu/hw/ppc/spapr_iommu.c
+++ b/qemu/hw/ppc/spapr_iommu.c
@@ -16,6 +16,7 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include "hw/hw.h"
#include "sysemu/kvm.h"
#include "hw/qdev.h"
@@ -146,7 +147,7 @@ static int spapr_tce_table_realize(DeviceState *dev)
tcet->table = kvmppc_create_spapr_tce(tcet->liobn,
window_size,
&tcet->fd,
- tcet->vfio_accel);
+ tcet->need_vfio);
}
if (!tcet->table) {
@@ -168,11 +169,43 @@ static int spapr_tce_table_realize(DeviceState *dev)
return 0;
}
+void spapr_tce_set_need_vfio(sPAPRTCETable *tcet, bool need_vfio)
+{
+ size_t table_size = tcet->nb_table * sizeof(uint64_t);
+ void *newtable;
+
+ if (need_vfio == tcet->need_vfio) {
+ /* Nothing to do */
+ return;
+ }
+
+ if (!need_vfio) {
+ /* FIXME: We don't support transition back to KVM accelerated
+ * TCEs yet */
+ return;
+ }
+
+ tcet->need_vfio = true;
+
+ if (tcet->fd < 0) {
+ /* Table is already in userspace, nothing to be do */
+ return;
+ }
+
+ newtable = g_malloc(table_size);
+ memcpy(newtable, tcet->table, table_size);
+
+ kvmppc_remove_spapr_tce(tcet->table, tcet->fd, tcet->nb_table);
+
+ tcet->fd = -1;
+ tcet->table = newtable;
+}
+
sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn,
uint64_t bus_offset,
uint32_t page_shift,
uint32_t nb_table,
- bool vfio_accel)
+ bool need_vfio)
{
sPAPRTCETable *tcet;
char tmp[64];
@@ -192,7 +225,7 @@ sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn,
tcet->bus_offset = bus_offset;
tcet->page_shift = page_shift;
tcet->nb_table = nb_table;
- tcet->vfio_accel = vfio_accel;
+ tcet->need_vfio = need_vfio;
snprintf(tmp, sizeof(tmp), "tce-table-%x", liobn);
object_property_add_child(OBJECT(owner), tmp, OBJECT(tcet), NULL);