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:
@@ -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"
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user