@@ -39,6 +39,7 @@ static int32_t shell_list_vm(__unused int32_t argc, __unused char **argv);
39
39
static int32_t shell_list_vcpu (__unused int32_t argc , __unused char * * argv );
40
40
static int32_t shell_vcpu_dumpreg (int32_t argc , char * * argv );
41
41
static int32_t shell_dump_host_mem (int32_t argc , char * * argv );
42
+ static int32_t shell_dump_guest_mem (int32_t argc , char * * argv );
42
43
static int32_t shell_to_vm_console (int32_t argc , char * * argv );
43
44
static int32_t shell_show_cpu_int (__unused int32_t argc , __unused char * * argv );
44
45
static int32_t shell_show_ptdev_info (__unused int32_t argc , __unused char * * argv );
@@ -87,6 +88,12 @@ static struct shell_cmd shell_cmds[] = {
87
88
.help_str = SHELL_CMD_DUMP_HOST_MEM_HELP ,
88
89
.fcn = shell_dump_host_mem ,
89
90
},
91
+ {
92
+ .str = SHELL_CMD_DUMP_GUEST_MEM ,
93
+ .cmd_param = SHELL_CMD_DUMP_GUEST_MEM_PARAM ,
94
+ .help_str = SHELL_CMD_DUMP_GUEST_MEM_HELP ,
95
+ .fcn = shell_dump_guest_mem ,
96
+ },
90
97
{
91
98
.str = SHELL_CMD_VM_CONSOLE ,
92
99
.cmd_param = SHELL_CMD_VM_CONSOLE_PARAM ,
@@ -854,6 +861,73 @@ static int32_t shell_dump_host_mem(int32_t argc, char **argv)
854
861
return ret ;
855
862
}
856
863
864
+ static void dump_guest_mem (void * data )
865
+ {
866
+ uint64_t i , fault_addr ;
867
+ uint32_t err_code = 0 ;
868
+ uint64_t loop_cnt ;
869
+ uint64_t buf [4 ];
870
+ char temp_str [MAX_STR_SIZE ];
871
+ struct guest_mem_dump * dump = (struct guest_mem_dump * )data ;
872
+ uint64_t length = dump -> len ;
873
+ uint64_t gva = dump -> gva ;
874
+ struct acrn_vcpu * vcpu = dump -> vcpu ;
875
+
876
+ /* Change the length to a multiple of 32 if the length is not */
877
+ loop_cnt = ((length & 0x1fUL ) == 0UL ) ? ((length >> 5UL )) : ((length >> 5UL ) + 1UL );
878
+
879
+ for (i = 0UL ; i < loop_cnt ; i ++ ) {
880
+
881
+ if (copy_from_gva (vcpu , buf , gva , 32U , & err_code , & fault_addr ) != 0 ) {
882
+ printf ("copy_from_gva error! err_code=0x%x fault_addr=0x%llx\r\n" , err_code , fault_addr );
883
+ break ;
884
+ }
885
+ snprintf (temp_str , MAX_STR_SIZE , "GVA(0x%llx): 0x%016lx 0x%016lx 0x%016lx 0x%016lx\r\n" ,
886
+ gva , buf [0 ], buf [1 ], buf [2 ], buf [3 ]);
887
+ shell_puts (temp_str );
888
+ gva += 32UL ;
889
+ }
890
+ }
891
+
892
+ static int32_t shell_dump_guest_mem (int32_t argc , char * * argv )
893
+ {
894
+ uint16_t vm_id , pcpu_id ;
895
+ int32_t ret ;
896
+ uint64_t gva ;
897
+ uint64_t length ;
898
+ uint64_t mask = 0UL ;
899
+ struct acrn_vm * vm ;
900
+ struct acrn_vcpu * vcpu = NULL ;
901
+ struct guest_mem_dump dump ;
902
+
903
+ /* User input invalidation */
904
+ if (argc != 4 ) {
905
+ ret = - EINVAL ;
906
+ } else {
907
+ vm_id = sanitize_vmid ((uint16_t )strtol_deci (argv [1 ]));
908
+ gva = strtoul_hex (argv [2 ]);
909
+ length = (uint64_t )strtol_deci (argv [3 ]);
910
+
911
+ vm = get_vm_from_vmid (vm_id );
912
+ vcpu = vcpu_from_vid (vm , BOOT_CPU_ID );
913
+
914
+ dump .vcpu = vcpu ;
915
+ dump .gva = gva ;
916
+ dump .len = length ;
917
+
918
+ pcpu_id = pcpuid_from_vcpu (vcpu );
919
+ if (pcpu_id == get_pcpu_id ()) {
920
+ dump_guest_mem (& dump );
921
+ } else {
922
+ bitmap_set_nolock (pcpu_id , & mask );
923
+ smp_call_function (mask , dump_guest_mem , & dump );
924
+ }
925
+ ret = 0 ;
926
+ }
927
+
928
+ return ret ;
929
+ }
930
+
857
931
static int32_t shell_to_vm_console (int32_t argc , char * * argv )
858
932
{
859
933
char temp_str [TEMP_STR_SIZE ];
0 commit comments