@samitouri / QOSamiQemu / commits / 2391125f13

accel/kvm: add confidential class member to indicate guest rebuild capability

As a part of the confidential guest reset process, the existing encrypted guest state must be made mutable since it would be discarded after reset. A new encrypted and locked guest state must be established after the reset. To this end, a new boolean member per confidential guest support class (eg, tdx or sev-snp) is added that will indicate whether its possible to rebuild guest state: bool can_rebuild_guest_state; This is true if rebuilding guest state is possible, false otherwise. A KVM based confidential guest reset is only possible when the existing state is locked but its possible to rebuild guest state. Otherwise, the guest is not resettable. Signed-off-by: Ani Sinha <anisinha@redhat.com> Link: https://lore.kernel.org/r/20260225035000.385950-3-anisinha@redhat.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Ani Sinha committed Feb 25, 2026 at 09:19 UTC 2391125f13526e9f389bee0abf4af39e566b6cc8
4 files changed +25 -3
include/system/confidential-guest-support.h
+20
@@ -152,6 +152,11 @@ typedef struct ConfidentialGuestSupportClass {
152 */
153 int (*get_mem_map_entry)(int index, ConfidentialGuestMemoryMapEntry *entry,
154 Error **errp);
155 +
156 + /*
157 + * is it possible to rebuild the guest state?
158 + */
159 + bool can_rebuild_guest_state;
160 } ConfidentialGuestSupportClass;
161
162 static inline int confidential_guest_kvm_init(ConfidentialGuestSupport *cgs,
@@ -167,6 +172,21 @@ static inline int confidential_guest_kvm_init(ConfidentialGuestSupport *cgs,
172 return 0;
173 }
174
175 +static inline bool
176 +confidential_guest_can_rebuild_state(ConfidentialGuestSupport *cgs)
177 +{
178 + ConfidentialGuestSupportClass *klass;
179 +
180 + if (!cgs) {
181 + /* non-confidential guests */
182 + return true;
183 + }
184 +
185 + klass = CONFIDENTIAL_GUEST_SUPPORT_GET_CLASS(cgs);
186 + return klass->can_rebuild_guest_state;
187 +
188 +}
189 +
190 static inline int confidential_guest_kvm_reset(ConfidentialGuestSupport *cgs,
191 Error **errp)
192 {
system/runstate.c
+3 -3
@@ -57,6 +57,7 @@
57 #include "system/reset.h"
58 #include "system/runstate.h"
59 #include "system/runstate-action.h"
60 +#include "system/confidential-guest-support.h"
61 #include "system/system.h"
62 #include "system/tpm.h"
63 #include "trace.h"
@@ -543,8 +544,6 @@ void qemu_system_reset(ShutdownCause reason)
544 */
545 if (cpus_are_resettable()) {
546 cpu_synchronize_all_post_reset();
546 - } else {
547 - assert(runstate_check(RUN_STATE_PRELAUNCH));
547 }
548
549 vm_set_suspended(false);
@@ -697,7 +696,8 @@ void qemu_system_reset_request(ShutdownCause reason)
696 if (reboot_action == REBOOT_ACTION_SHUTDOWN &&
697 reason != SHUTDOWN_CAUSE_SUBSYSTEM_RESET) {
698 shutdown_requested = reason;
700 - } else if (!cpus_are_resettable()) {
699 + } else if (!cpus_are_resettable() &&
700 + !confidential_guest_can_rebuild_state(current_machine->cgs)) {
701 error_report("cpus are not resettable, terminating");
702 shutdown_requested = reason;
703 } else {
target/i386/kvm/tdx.c
+1
@@ -1543,6 +1543,7 @@ static void tdx_guest_class_init(ObjectClass *oc, const void *data)
1543 X86ConfidentialGuestClass *x86_klass = X86_CONFIDENTIAL_GUEST_CLASS(oc);
1544
1545 klass->kvm_init = tdx_kvm_init;
1546 + klass->can_rebuild_guest_state = true;
1547 x86_klass->kvm_type = tdx_kvm_type;
1548 x86_klass->cpu_instance_init = tdx_cpu_instance_init;
1549 x86_klass->adjust_cpuid_features = tdx_adjust_cpuid_features;
target/i386/sev.c
+1
@@ -2760,6 +2760,7 @@ sev_common_instance_init(Object *obj)
2760 cgs->set_guest_state = cgs_set_guest_state;
2761 cgs->get_mem_map_entry = cgs_get_mem_map_entry;
2762 cgs->set_guest_policy = cgs_set_guest_policy;
2763 + cgs->can_rebuild_guest_state = true;
2764
2765 QTAILQ_INIT(&sev_common->launch_vmsa);
2766 }