76daa3
From 81165ace09e10cf550ebdf2b88241a8b0d405196 Mon Sep 17 00:00:00 2001
76daa3
From: Auger Eric <eric.auger@redhat.com>
76daa3
Date: Fri, 16 Jun 2017 15:17:55 +0200
76daa3
Subject: [PATCH 4/5] hw/intc/arm_gicv3_kvm: Implement pending table save
76daa3
76daa3
RH-Author: Auger Eric <eric.auger@redhat.com>
76daa3
Message-id: <1497626276-18221-5-git-send-email-eric.auger@redhat.com>
76daa3
Patchwork-id: 75637
76daa3
O-Subject: [Pegas-1.0 qemu-kvm PATCH v2 4/5] hw/intc/arm_gicv3_kvm: Implement pending table save
76daa3
Bugzilla: 1462061
76daa3
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
76daa3
RH-Acked-by: Peter Xu <peterx@redhat.com>
76daa3
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
76daa3
76daa3
This patch adds the flush of the LPI pending bits into the
76daa3
redistributor pending tables. This happens on VM stop.
76daa3
76daa3
There is no explicit restore as the tables are implicitly sync'ed
76daa3
on ITS table restore and on LPI enable at redistributor level.
76daa3
76daa3
Signed-off-by: Eric Auger <eric.auger@redhat.com>
76daa3
Message-id: 1497023553-18411-4-git-send-email-eric.auger@redhat.com
76daa3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
76daa3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
76daa3
(cherry picked from commit d5aa0c229ab5d46c1a4ff497553671cd46486749)
76daa3
Signed-off-by: Eric Auger <eric.auger@redhat.com>
76daa3
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
76daa3
---
76daa3
 hw/intc/arm_gicv3_kvm.c | 34 ++++++++++++++++++++++++++++++++++
76daa3
 1 file changed, 34 insertions(+)
76daa3
76daa3
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
76daa3
index 824475f..2df4870 100644
76daa3
--- a/hw/intc/arm_gicv3_kvm.c
76daa3
+++ b/hw/intc/arm_gicv3_kvm.c
76daa3
@@ -25,6 +25,7 @@
76daa3
 #include "hw/sysbus.h"
76daa3
 #include "qemu/error-report.h"
76daa3
 #include "sysemu/kvm.h"
76daa3
+#include "sysemu/sysemu.h"
76daa3
 #include "kvm_arm.h"
76daa3
 #include "gicv3_internal.h"
76daa3
 #include "vgic_common.h"
76daa3
@@ -680,6 +681,35 @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
76daa3
     REGINFO_SENTINEL
76daa3
 };
76daa3
 
76daa3
+/**
76daa3
+ * vm_change_state_handler - VM change state callback aiming at flushing
76daa3
+ * RDIST pending tables into guest RAM
76daa3
+ *
76daa3
+ * The tables get flushed to guest RAM whenever the VM gets stopped.
76daa3
+ */
76daa3
+static void vm_change_state_handler(void *opaque, int running,
76daa3
+                                    RunState state)
76daa3
+{
76daa3
+    GICv3State *s = (GICv3State *)opaque;
76daa3
+    Error *err = NULL;
76daa3
+    int ret;
76daa3
+
76daa3
+    if (running) {
76daa3
+        return;
76daa3
+    }
76daa3
+
76daa3
+    ret = kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
76daa3
+                           KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES,
76daa3
+                           NULL, true, &err;;
76daa3
+    if (err) {
76daa3
+        error_report_err(err);
76daa3
+    }
76daa3
+    if (ret < 0 && ret != -EFAULT) {
76daa3
+        abort();
76daa3
+    }
76daa3
+}
76daa3
+
76daa3
+
76daa3
 static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
76daa3
 {
76daa3
     GICv3State *s = KVM_ARM_GICV3(dev);
76daa3
@@ -751,6 +781,10 @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
76daa3
             return;
76daa3
         }
76daa3
     }
76daa3
+    if (kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
76daa3
+                              KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES)) {
76daa3
+        qemu_add_vm_change_state_handler(vm_change_state_handler, s);
76daa3
+    }
76daa3
 }
76daa3
 
76daa3
 static void kvm_arm_gicv3_class_init(ObjectClass *klass, void *data)
76daa3
-- 
76daa3
1.8.3.1
76daa3