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 <[email protected]> --- include/system/confidential-guest-support.h | 20 ++++++++++++++++++++ system/runstate.c | 6 +++--- target/i386/kvm/tdx.c | 1 + target/i386/sev.c | 1 + 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/include/system/confidential-guest-support.h b/include/system/confidential-guest-support.h index 0cc8b26e64..5dca717308 100644 --- a/include/system/confidential-guest-support.h +++ b/include/system/confidential-guest-support.h @@ -152,6 +152,11 @@ typedef struct ConfidentialGuestSupportClass { */ int (*get_mem_map_entry)(int index, ConfidentialGuestMemoryMapEntry *entry, Error **errp); + + /* + * is it possible to rebuild the guest state? + */ + bool can_rebuild_guest_state; } ConfidentialGuestSupportClass; static inline int confidential_guest_kvm_init(ConfidentialGuestSupport *cgs, @@ -167,6 +172,21 @@ static inline int confidential_guest_kvm_init(ConfidentialGuestSupport *cgs, return 0; } +static inline bool +confidential_guest_can_rebuild_state(ConfidentialGuestSupport *cgs) +{ + ConfidentialGuestSupportClass *klass; + + if (!cgs) { + /* non-confidential guests */ + return true; + } + + klass = CONFIDENTIAL_GUEST_SUPPORT_GET_CLASS(cgs); + return klass->can_rebuild_guest_state; + +} + static inline int confidential_guest_kvm_reset(ConfidentialGuestSupport *cgs, Error **errp) { diff --git a/system/runstate.c b/system/runstate.c index ed2db56480..5d58260ed5 100644 --- a/system/runstate.c +++ b/system/runstate.c @@ -57,6 +57,7 @@ #include "system/reset.h" #include "system/runstate.h" #include "system/runstate-action.h" +#include "system/confidential-guest-support.h" #include "system/system.h" #include "system/tpm.h" #include "trace.h" @@ -543,8 +544,6 @@ void qemu_system_reset(ShutdownCause reason) */ if (cpus_are_resettable()) { cpu_synchronize_all_post_reset(); - } else { - assert(runstate_check(RUN_STATE_PRELAUNCH)); } vm_set_suspended(false); @@ -693,7 +692,8 @@ void qemu_system_reset_request(ShutdownCause reason) if (reboot_action == REBOOT_ACTION_SHUTDOWN && reason != SHUTDOWN_CAUSE_SUBSYSTEM_RESET) { shutdown_requested = reason; - } else if (!cpus_are_resettable()) { + } else if (!cpus_are_resettable() && + !confidential_guest_can_rebuild_state(current_machine->cgs)) { error_report("cpus are not resettable, terminating"); shutdown_requested = reason; } else { diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c index 0161985768..a3e81e1c0c 100644 --- a/target/i386/kvm/tdx.c +++ b/target/i386/kvm/tdx.c @@ -1543,6 +1543,7 @@ static void tdx_guest_class_init(ObjectClass *oc, const void *data) X86ConfidentialGuestClass *x86_klass = X86_CONFIDENTIAL_GUEST_CLASS(oc); klass->kvm_init = tdx_kvm_init; + klass->can_rebuild_guest_state = true; x86_klass->kvm_type = tdx_kvm_type; x86_klass->cpu_instance_init = tdx_cpu_instance_init; x86_klass->adjust_cpuid_features = tdx_adjust_cpuid_features; diff --git a/target/i386/sev.c b/target/i386/sev.c index 1d70f96ec1..176329bd07 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -2760,6 +2760,7 @@ sev_common_instance_init(Object *obj) cgs->set_guest_state = cgs_set_guest_state; cgs->get_mem_map_entry = cgs_get_mem_map_entry; cgs->set_guest_policy = cgs_set_guest_policy; + cgs->can_rebuild_guest_state = true; QTAILQ_INIT(&sev_common->launch_vmsa); } -- 2.42.0
