kvm/xen-emu: re-initialize capabilities during confidential guest reset
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> Link: https://lore.kernel.org/r/20260225035000.385950-29-anisinha@redhat.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Ani Sinha committed
Feb 25, 2026 at 09:19 UTC
5e14320daccf54efad4b8fdbc9e5ab82b6e3d44e
1 file changed
+37
-1
target/i386/kvm/xen-emu.c
+37
-1
@@ -44,9 +44,12 @@
44
45
#include "xen-compat.h"
46
47
+NotifierWithReturn xen_vmfd_change_notifier;
48
+static uint32_t xen_msr;
49
static void xen_vcpu_singleshot_timer_event(void *opaque);
50
static void xen_vcpu_periodic_timer_event(void *opaque);
51
static int vcpuop_stop_singleshot_timer(CPUState *cs);
52
+static int do_initialize_xen_caps(KVMState *s, uint32_t hypercall_msr);
53
54
#ifdef TARGET_X86_64
55
#define hypercall_compat32(longmode) (!(longmode))
@@ -54,6 +57,23 @@ static int vcpuop_stop_singleshot_timer(CPUState *cs);
57
#define hypercall_compat32(longmode) (false)
58
#endif
59
60
+static int xen_handle_vmfd_change(NotifierWithReturn *n,
61
+ void *data, Error** errp)
62
+{
63
+ int ret;
64
+
65
+ /* we are not interested in pre vmfd change notification */
66
+ if (((VmfdChangeNotifier *)data)->pre) {
67
+ return 0;
68
+ }
69
+
70
+ ret = do_initialize_xen_caps(kvm_state, xen_msr);
71
+ if (ret < 0) {
72
+ return ret;
73
+ }
74
+ return 0;
75
+}
76
+
77
static bool kvm_gva_to_gpa(CPUState *cs, uint64_t gva, uint64_t *gpa,
78
size_t *len, bool is_write)
79
{
@@ -111,7 +131,7 @@ static inline int kvm_copy_to_gva(CPUState *cs, uint64_t gva, void *buf,
131
return kvm_gva_rw(cs, gva, buf, sz, true);
132
}
133
114
-int kvm_xen_init(KVMState *s, uint32_t hypercall_msr)
134
+static int do_initialize_xen_caps(KVMState *s, uint32_t hypercall_msr)
135
{
136
const int required_caps = KVM_XEN_HVM_CONFIG_HYPERCALL_MSR |
137
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)
163
strerror(-ret));
164
return ret;
165
}
166
+ return xen_caps;
167
+}
168
+
169
+int kvm_xen_init(KVMState *s, uint32_t hypercall_msr)
170
+{
171
+ int xen_caps;
172
+
173
+ xen_caps = do_initialize_xen_caps(s, hypercall_msr);
174
+ if (xen_caps < 0) {
175
+ return xen_caps;
176
+ }
177
+
178
+ xen_msr = hypercall_msr;
179
180
/* If called a second time, don't repeat the rest of the setup. */
181
if (s->xen_caps) {
@@ -185,6 +218,9 @@ int kvm_xen_init(KVMState *s, uint32_t hypercall_msr)
218
xen_primary_console_reset();
219
xen_xenstore_reset();
220
221
+ xen_vmfd_change_notifier.notify = xen_handle_vmfd_change;
222
+ kvm_vmfd_add_change_notifier(&xen_vmfd_change_notifier);
223
+
224
return 0;
225
}
226