A confidential guest reset involves closing the old virtual machine KVM file
descriptor and opening a new one. Since its a new KVM fd, PIT needs to be
re-initialized again. This is done with the help of a notifier which is invoked
upon KVM vm file descriptor change during the confidential guest reset process.
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
hw/i386/kvm/i8254.c | 23 +++++++++++++++++++++++
hw/i386/kvm/trace-events | 1 +
2 files changed, 24 insertions(+)
diff --git a/hw/i386/kvm/i8254.c b/hw/i386/kvm/i8254.c
index 255047458a..70e8fd83cd 100644
--- a/hw/i386/kvm/i8254.c
+++ b/hw/i386/kvm/i8254.c
@@ -35,6 +35,7 @@
#include "hw/core/qdev-properties-system.h"
#include "system/kvm.h"
#include "target/i386/kvm/kvm_i386.h"
+#include "trace.h"
#include "qom/object.h"
#define KVM_PIT_REINJECT_BIT 0
@@ -52,6 +53,8 @@ struct KVMPITState {
LostTickPolicy lost_tick_policy;
bool vm_stopped;
int64_t kernel_clock_offset;
+
+ NotifierWithReturn kvmpit_vmfd_change_notifier;
};
struct KVMPITClass {
@@ -203,6 +206,23 @@ static void kvm_pit_put(PITCommonState *pit)
}
}
+static int kvmpit_post_vmfd_change(NotifierWithReturn *notifier,
+ void *data, Error** errp)
+{
+ KVMPITState *s = container_of(notifier, KVMPITState,
+ kvmpit_vmfd_change_notifier);
+
+ /* we are not interested in pre vmfd change notification */
+ if (((VmfdChangeNotifier *)data)->pre) {
+ return 0;
+ }
+
+ do_pit_initialize(s, errp);
+
+ trace_kvmpit_post_vmfd_change();
+ return 0;
+}
+
static void kvm_pit_set_gate(PITCommonState *s, PITChannelState *sc, int val)
{
kvm_pit_get(s);
@@ -292,6 +312,9 @@ static void kvm_pit_realizefn(DeviceState *dev, Error **errp)
qemu_add_vm_change_state_handler(kvm_pit_vm_state_change, s);
+ s->kvmpit_vmfd_change_notifier.notify = kvmpit_post_vmfd_change;
+ kvm_vmfd_add_change_notifier(&s->kvmpit_vmfd_change_notifier);
+
kpc->parent_realize(dev, errp);
}
diff --git a/hw/i386/kvm/trace-events b/hw/i386/kvm/trace-events
index 67bf7f174e..33680ff82b 100644
--- a/hw/i386/kvm/trace-events
+++ b/hw/i386/kvm/trace-events
@@ -20,3 +20,4 @@ xenstore_reset_watches(void) ""
xenstore_watch_event(const char *path, const char *token) "path %s token %s"
xen_primary_console_create(void) ""
xen_primary_console_reset(int port) "port %u"
+kvmpit_post_vmfd_change(void) ""
--
2.42.0