hw/hyperv/vmbus: add support for confidential guest reset

On confidential guests when the KVM virtual machine file descriptor changes as
a part of the reset process, event file descriptors needs to be reassociated
with the new KVM VM file descriptor. This is achieved with the help of a
callback handler that gets called when KVM VM file descriptor changes during
the confidential guest reset process.

This patch is tested on non-confidential platform only.

Acked-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com>
Signed-off-by: Ani Sinha <anisinha@redhat.com>
Link: https://lore.kernel.org/r/20260225035000.385950-28-anisinha@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Ani Sinha
2026-02-25 09:19:32 +05:30
committed by Paolo Bonzini
parent c4cf32fc63
commit b6fde55342
2 changed files with 38 additions and 0 deletions

View File

@@ -16,6 +16,7 @@ vmbus_gpadl_torndown(uint32_t gpadl_id) "gpadl #%d"
vmbus_open_channel(uint32_t chan_id, uint32_t gpadl_id, uint32_t target_vp) "channel #%d gpadl #%d target vp %d"
vmbus_channel_open(uint32_t chan_id, uint32_t status) "channel #%d status %d"
vmbus_close_channel(uint32_t chan_id) "channel #%d"
vmbus_handle_vmfd_change(void) ""
# hv-balloon
hv_balloon_state_change(const char *tostr) "-> %s"

View File

@@ -20,6 +20,7 @@
#include "hw/hyperv/vmbus-bridge.h"
#include "hw/core/sysbus.h"
#include "exec/cpu-common.h"
#include "system/kvm.h"
#include "exec/target_page.h"
#include "trace.h"
@@ -248,6 +249,12 @@ struct VMBus {
* interrupt page
*/
EventNotifier notifier;
/*
* Notifier to inform when vmfd is changed as a part of confidential guest
* reset mechanism.
*/
NotifierWithReturn vmbus_vmfd_change_notifier;
};
static bool gpadl_full(VMBusGpadl *gpadl)
@@ -2347,6 +2354,33 @@ static void vmbus_dev_unrealize(DeviceState *dev)
free_channels(vdev);
}
/*
* If the KVM fd changes because of VM reset in confidential guests,
* reassociate event fd with the new KVM fd.
*/
static int vmbus_handle_vmfd_change(NotifierWithReturn *notifier,
void *data, Error** errp)
{
VMBus *vmbus = container_of(notifier, VMBus,
vmbus_vmfd_change_notifier);
int ret = 0;
/* we are not interested in pre vmfd change notification */
if (((VmfdChangeNotifier *)data)->pre) {
return 0;
}
ret = hyperv_set_event_flag_handler(VMBUS_EVENT_CONNECTION_ID,
&vmbus->notifier);
/* if we are only using userland event handler, it may already exist */
if (ret != 0 && ret != -EEXIST) {
error_setg(errp, "hyperv set event handler failed with %d", ret);
}
trace_vmbus_handle_vmfd_change();
return ret;
}
static const Property vmbus_dev_props[] = {
DEFINE_PROP_UUID("instanceid", VMBusDevice, instanceid),
};
@@ -2429,6 +2463,9 @@ static void vmbus_realize(BusState *bus, Error **errp)
goto clear_event_notifier;
}
vmbus->vmbus_vmfd_change_notifier.notify = vmbus_handle_vmfd_change;
kvm_vmfd_add_change_notifier(&vmbus->vmbus_vmfd_change_notifier);
return;
clear_event_notifier: