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>
---
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 d091a2bddd..13f32bed8c 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);
@@ -697,7 +696,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 acdcb9c4e6..66e38ca32e 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