diff options
Diffstat (limited to 'system')
| -rw-r--r-- | system/physmem.c | 28 | ||||
| -rw-r--r-- | system/runstate.c | 44 |
2 files changed, 68 insertions, 4 deletions
diff --git a/system/physmem.c b/system/physmem.c index 2fb0c25..e5ff26a 100644 --- a/system/physmem.c +++ b/system/physmem.c @@ -2827,6 +2827,34 @@ found: } /* + * Creates new guest memfd for the ramblocks and closes the + * existing memfd. + */ +int ram_block_rebind(Error **errp) +{ + RAMBlock *block; + + qemu_mutex_lock_ramlist(); + + RAMBLOCK_FOREACH(block) { + if (block->flags & RAM_GUEST_MEMFD) { + if (block->guest_memfd >= 0) { + close(block->guest_memfd); + } + block->guest_memfd = kvm_create_guest_memfd(block->max_length, + 0, errp); + if (block->guest_memfd < 0) { + qemu_mutex_unlock_ramlist(); + return -1; + } + + } + } + qemu_mutex_unlock_ramlist(); + return 0; +} + +/* * Finds the named RAMBlock * * name: The name of RAMBlock to find diff --git a/system/runstate.c b/system/runstate.c index d091a2b..eca722b 100644 --- a/system/runstate.c +++ b/system/runstate.c @@ -42,6 +42,7 @@ #include "qapi/qapi-commands-run-state.h" #include "qapi/qapi-events-run-state.h" #include "qemu/accel.h" +#include "accel/accel-ops.h" #include "qemu/error-report.h" #include "qemu/job.h" #include "qemu/log.h" @@ -57,6 +58,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" @@ -508,6 +510,9 @@ void qemu_system_reset(ShutdownCause reason) { MachineClass *mc; ResetType type; + AccelClass *ac = ACCEL_GET_CLASS(current_accel()); + bool guest_state_rebuilt = false; + int ret; mc = current_machine ? MACHINE_GET_CLASS(current_machine) : NULL; @@ -520,6 +525,29 @@ void qemu_system_reset(ShutdownCause reason) default: type = RESET_TYPE_COLD; } + + if ((reason == SHUTDOWN_CAUSE_GUEST_RESET || + reason == SHUTDOWN_CAUSE_HOST_QMP_SYSTEM_RESET) && + (current_machine->new_accel_vmfd_on_reset || !cpus_are_resettable())) { + if (ac->rebuild_guest) { + ret = ac->rebuild_guest(current_machine); + if (ret < 0) { + error_report("unable to rebuild guest: %s(%d)", + strerror(-ret), ret); + vm_stop(RUN_STATE_INTERNAL_ERROR); + } else { + info_report("virtual machine state has been rebuilt with new " + "guest file handle."); + guest_state_rebuilt = true; + } + } else if (!cpus_are_resettable()) { + error_report("accelerator does not support reset!"); + } else { + error_report("accelerator does not support rebuilding guest state," + " proceeding with normal reset!"); + } + } + if (mc && mc->reset) { mc->reset(current_machine, type); } else { @@ -542,9 +570,16 @@ void qemu_system_reset(ShutdownCause reason) * it does _more_ than cpu_synchronize_all_post_reset(). */ if (cpus_are_resettable()) { - cpu_synchronize_all_post_reset(); - } else { - assert(runstate_check(RUN_STATE_PRELAUNCH)); + if (guest_state_rebuilt) { + /* + * If guest state has been rebuilt, then we + * need to sync full cpu state for non confidential guests post + * reset. + */ + cpu_synchronize_all_post_init(); + } else { + cpu_synchronize_all_post_reset(); + } } vm_set_suspended(false); @@ -697,7 +732,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 { |
