@samitouri / QOSamiQemu / commits / 05caf2690e

i386/tdx: finalize TDX guest state upon reset

When the confidential virtual machine KVM file descriptor changes due to the guest reset, some TDX specific setup steps needs to be done again. This includes finalizing the initial guest launch state again. This change re-executes some parts of the TDX setup during the device reset phaze using a resettable interface. This finalizes the guest launch state again and locks it in. Machine done notifier which was previously used is no longer needed as the same code is now executed as a part of VM reset. Signed-off-by: Ani Sinha <anisinha@redhat.com> Link: https://lore.kernel.org/r/20260225035000.385950-18-anisinha@redhat.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Ani Sinha committed Feb 25, 2026 at 09:19 UTC 05caf2690e5a29a25928c6717c4204ea3c0bfee3
3 files changed +37 -5
target/i386/kvm/tdx.c
+33 -5
@@ -19,6 +19,7 @@
19 #include "crypto/hash.h"
20 #include "system/kvm_int.h"
21 #include "system/runstate.h"
22 +#include "system/reset.h"
23 #include "system/system.h"
24 #include "system/ramblock.h"
25 #include "system/address-spaces.h"
@@ -38,6 +39,7 @@
39 #include "kvm_i386.h"
40 #include "tdx.h"
41 #include "tdx-quote-generator.h"
42 +#include "trace.h"
43
44 #include "standard-headers/asm-x86/kvm_para.h"
45
@@ -389,9 +391,19 @@ static void tdx_finalize_vm(Notifier *notifier, void *unused)
391 CONFIDENTIAL_GUEST_SUPPORT(tdx_guest)->ready = true;
392 }
393
392 -static Notifier tdx_machine_done_notify = {
393 - .notify = tdx_finalize_vm,
394 -};
394 +static void tdx_handle_reset(Object *obj, ResetType type)
395 +{
396 + if (!runstate_is_running() && !phase_check(PHASE_MACHINE_READY)) {
397 + return;
398 + }
399 +
400 + if (!kvm_enable_hypercall(BIT_ULL(KVM_HC_MAP_GPA_RANGE))) {
401 + error_setg(&error_fatal, "KVM_HC_MAP_GPA_RANGE not enabled for guest");
402 + }
403 +
404 + tdx_finalize_vm(NULL, NULL);
405 + trace_tdx_handle_reset();
406 +}
407
408 /*
409 * Some CPUID bits change from fixed1 to configurable bits when TDX module
@@ -738,8 +750,6 @@ static int tdx_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
750 */
751 kvm_readonly_mem_allowed = false;
752
741 - qemu_add_machine_init_done_notifier(&tdx_machine_done_notify);
742 -
753 tdx_guest = tdx;
754 return 0;
755 }
@@ -1505,6 +1515,7 @@ OBJECT_DEFINE_TYPE_WITH_INTERFACES(TdxGuest,
1515 TDX_GUEST,
1516 X86_CONFIDENTIAL_GUEST,
1517 { TYPE_USER_CREATABLE },
1518 + { TYPE_RESETTABLE_INTERFACE },
1519 { NULL })
1520
1521 static void tdx_guest_init(Object *obj)
@@ -1538,16 +1549,24 @@ static void tdx_guest_init(Object *obj)
1549
1550 tdx->event_notify_vector = -1;
1551 tdx->event_notify_apicid = -1;
1552 + qemu_register_resettable(obj);
1553 }
1554
1555 static void tdx_guest_finalize(Object *obj)
1556 {
1557 }
1558
1559 +static ResettableState *tdx_reset_state(Object *obj)
1560 +{
1561 + TdxGuest *tdx = TDX_GUEST(obj);
1562 + return &tdx->reset_state;
1563 +}
1564 +
1565 static void tdx_guest_class_init(ObjectClass *oc, const void *data)
1566 {
1567 ConfidentialGuestSupportClass *klass = CONFIDENTIAL_GUEST_SUPPORT_CLASS(oc);
1568 X86ConfidentialGuestClass *x86_klass = X86_CONFIDENTIAL_GUEST_CLASS(oc);
1569 + ResettableClass *rc = RESETTABLE_CLASS(oc);
1570
1571 klass->kvm_init = tdx_kvm_init;
1572 klass->can_rebuild_guest_state = true;
@@ -1555,4 +1574,13 @@ static void tdx_guest_class_init(ObjectClass *oc, const void *data)
1574 x86_klass->cpu_instance_init = tdx_cpu_instance_init;
1575 x86_klass->adjust_cpuid_features = tdx_adjust_cpuid_features;
1576 x86_klass->check_features = tdx_check_features;
1577 +
1578 + /*
1579 + * the exit phase makes sure sev handles reset after all legacy resets
1580 + * have taken place (in the hold phase) and IGVM has also properly
1581 + * set up the boot state.
1582 + */
1583 + rc->phases.exit = tdx_handle_reset;
1584 + rc->get_state = tdx_reset_state;
1585 +
1586 }
target/i386/kvm/tdx.h
+1
@@ -70,6 +70,7 @@ typedef struct TdxGuest {
70
71 uint32_t event_notify_vector;
72 uint32_t event_notify_apicid;
73 + ResettableState reset_state;
74 } TdxGuest;
75
76 #ifdef CONFIG_TDX
target/i386/kvm/trace-events
+3
@@ -14,3 +14,6 @@ kvm_xen_soft_reset(void) ""
14 kvm_xen_set_shared_info(uint64_t gfn) "shared info at gfn 0x%" PRIx64
15 kvm_xen_set_vcpu_attr(int cpu, int type, uint64_t gpa) "vcpu attr cpu %d type %d gpa 0x%" PRIx64
16 kvm_xen_set_vcpu_callback(int cpu, int vector) "callback vcpu %d vector %d"
17 +
18 +# tdx.c
19 +tdx_handle_reset(void) ""