@@ -349,6 +349,73 @@ __attribute__((weak)) cpumap_t vm_translate_to_vcpu_mask(struct vm* vm, cpumap_t
349349
350350void vcpu_run (struct vcpu * vcpu )
351351{
352- cpu ()-> vcpu -> active = true;
353352 vcpu_arch_run (vcpu );
354353}
354+
355+ static void vm_vcpu_reset (struct vm * vm )
356+ {
357+ struct vcpu * vcpu = cpu ()-> vcpu ;
358+
359+ if (vcpu -> vm -> id != vm -> id ) {
360+ ERROR ("Trying to reset vm not hosted in this cpu" );
361+ }
362+
363+ cpu_sync_and_clear_msgs (& vm -> sync );
364+
365+ if (vm -> master == cpu ()-> id ) {
366+ vm_arch_reset (vm );
367+ for (size_t i = 0 ; i < vm -> config -> platform .region_num ; i ++ ) {
368+ struct vm_mem_region * reg = & vm -> config -> platform .regions [i ];
369+ bool img_is_in_rgn = range_in_range (vm -> config -> image .base_addr , vm -> config -> image .size ,
370+ reg -> base , reg -> size );
371+ if (img_is_in_rgn ) {
372+ vm_install_image (vm , reg );
373+ break ;
374+ }
375+ }
376+ }
377+
378+ cpu_sync_barrier (& vcpu -> vm -> sync );
379+
380+ vcpu_arch_reset (vcpu , vm -> config -> entry );
381+
382+ vcpu_arch_run (vcpu );
383+ }
384+
385+ enum VM_EVENTS { VM_RESET };
386+
387+ static void vm_msg_handler (uint32_t event , uint64_t data )
388+ {
389+ UNUSED_ARG (data );
390+
391+ switch (event ) {
392+ case VM_RESET :
393+ vm_vcpu_reset (cpu ()-> vcpu -> vm );
394+ break ;
395+ default :
396+ break ;
397+ }
398+ }
399+
400+ CPU_MSG_HANDLER (vm_msg_handler , VM_IPI_ID )
401+
402+ bool vm_reset (struct vm * vm )
403+ {
404+ bool res ;
405+
406+ if (vm -> config -> image .inplace ) {
407+ res = false;
408+ } else {
409+ struct cpu_msg msg ;
410+ msg .handler = (uint32_t )VM_IPI_ID ;
411+ msg .event = VM_RESET ;
412+
413+ vm_msg_broadcast (vm , & msg );
414+
415+ vm_vcpu_reset (vm );
416+
417+ res = true;
418+ }
419+
420+ return res ;
421+ }
0 commit comments