On confidential guests KVM virtual machine file descriptor changes as a
part of the guest reset process. Xen capabilities needs to be re-initialized in
KVM against the new file descriptor.
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
target/i386/kvm/xen-emu.c | 38 +++++++++++++++++++++++++++++++++++++-
1 file changed, 37 insertions(+), 1 deletion(-)
diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c
index 52de019834..29364a9279 100644
--- a/target/i386/kvm/xen-emu.c
+++ b/target/i386/kvm/xen-emu.c
@@ -44,9 +44,12 @@
#include "xen-compat.h"
+NotifierWithReturn xen_vmfd_change_notifier;
+static uint32_t xen_msr;
static void xen_vcpu_singleshot_timer_event(void *opaque);
static void xen_vcpu_periodic_timer_event(void *opaque);
static int vcpuop_stop_singleshot_timer(CPUState *cs);
+static int do_initialize_xen_caps(KVMState *s, uint32_t hypercall_msr);
#ifdef TARGET_X86_64
#define hypercall_compat32(longmode) (!(longmode))
@@ -54,6 +57,23 @@ static int vcpuop_stop_singleshot_timer(CPUState *cs);
#define hypercall_compat32(longmode) (false)
#endif
+static int xen_handle_vmfd_change(NotifierWithReturn *n,
+ void *data, Error** errp)
+{
+ int ret;
+
+ /* we are not interested in pre vmfd change notification */
+ if (((VmfdChangeNotifier *)data)->pre) {
+ return 0;
+ }
+
+ ret = do_initialize_xen_caps(kvm_state, xen_msr);
+ if (ret < 0) {
+ return ret;
+ }
+ return 0;
+}
+
static bool kvm_gva_to_gpa(CPUState *cs, uint64_t gva, uint64_t *gpa,
size_t *len, bool is_write)
{
@@ -111,7 +131,7 @@ static inline int kvm_copy_to_gva(CPUState *cs, uint64_t gva, void *buf,
return kvm_gva_rw(cs, gva, buf, sz, true);
}
-int kvm_xen_init(KVMState *s, uint32_t hypercall_msr)
+static int do_initialize_xen_caps(KVMState *s, uint32_t hypercall_msr)
{
const int required_caps = KVM_XEN_HVM_CONFIG_HYPERCALL_MSR |
KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL | KVM_XEN_HVM_CONFIG_SHARED_INFO;
@@ -143,6 +163,19 @@ int kvm_xen_init(KVMState *s, uint32_t hypercall_msr)
strerror(-ret));
return ret;
}
+ return xen_caps;
+}
+
+int kvm_xen_init(KVMState *s, uint32_t hypercall_msr)
+{
+ int xen_caps;
+
+ xen_caps = do_initialize_xen_caps(s, hypercall_msr);
+ if (xen_caps < 0) {
+ return xen_caps;
+ }
+
+ xen_msr = hypercall_msr;
/* If called a second time, don't repeat the rest of the setup. */
if (s->xen_caps) {
@@ -185,6 +218,9 @@ int kvm_xen_init(KVMState *s, uint32_t hypercall_msr)
xen_primary_console_reset();
xen_xenstore_reset();
+ xen_vmfd_change_notifier.notify = xen_handle_vmfd_change;
+ kvm_vmfd_add_change_notifier(&xen_vmfd_change_notifier);
+
return 0;
}
--
2.42.0