mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-07-30 23:16:40 +00:00
hv:add dump_guest_mem
add shell command to support dump dump guest memory e.g. dump_guest_mem vm_id, gva, length Tracked-On: #4144 Signed-off-by: Mingqiang Chi <mingqiang.chi@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
215bb6ca6c
commit
bd0dbd274d
@ -39,6 +39,7 @@ static int32_t shell_list_vm(__unused int32_t argc, __unused char **argv);
|
||||
static int32_t shell_list_vcpu(__unused int32_t argc, __unused char **argv);
|
||||
static int32_t shell_vcpu_dumpreg(int32_t argc, char **argv);
|
||||
static int32_t shell_dump_host_mem(int32_t argc, char **argv);
|
||||
static int32_t shell_dump_guest_mem(int32_t argc, char **argv);
|
||||
static int32_t shell_to_vm_console(int32_t argc, char **argv);
|
||||
static int32_t shell_show_cpu_int(__unused int32_t argc, __unused char **argv);
|
||||
static int32_t shell_show_ptdev_info(__unused int32_t argc, __unused char **argv);
|
||||
@ -87,6 +88,12 @@ static struct shell_cmd shell_cmds[] = {
|
||||
.help_str = SHELL_CMD_DUMP_HOST_MEM_HELP,
|
||||
.fcn = shell_dump_host_mem,
|
||||
},
|
||||
{
|
||||
.str = SHELL_CMD_DUMP_GUEST_MEM,
|
||||
.cmd_param = SHELL_CMD_DUMP_GUEST_MEM_PARAM,
|
||||
.help_str = SHELL_CMD_DUMP_GUEST_MEM_HELP,
|
||||
.fcn = shell_dump_guest_mem,
|
||||
},
|
||||
{
|
||||
.str = SHELL_CMD_VM_CONSOLE,
|
||||
.cmd_param = SHELL_CMD_VM_CONSOLE_PARAM,
|
||||
@ -854,6 +861,73 @@ static int32_t shell_dump_host_mem(int32_t argc, char **argv)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void dump_guest_mem(void *data)
|
||||
{
|
||||
uint64_t i, fault_addr;
|
||||
uint32_t err_code = 0;
|
||||
uint64_t loop_cnt;
|
||||
uint64_t buf[4];
|
||||
char temp_str[MAX_STR_SIZE];
|
||||
struct guest_mem_dump *dump = (struct guest_mem_dump *)data;
|
||||
uint64_t length = dump->len;
|
||||
uint64_t gva = dump->gva;
|
||||
struct acrn_vcpu *vcpu = dump->vcpu;
|
||||
|
||||
/* Change the length to a multiple of 32 if the length is not */
|
||||
loop_cnt = ((length & 0x1fUL) == 0UL) ? ((length >> 5UL)) : ((length >> 5UL) + 1UL);
|
||||
|
||||
for (i = 0UL; i < loop_cnt; i++) {
|
||||
|
||||
if (copy_from_gva(vcpu, buf, gva, 32U, &err_code, &fault_addr) != 0) {
|
||||
printf("copy_from_gva error! err_code=0x%x fault_addr=0x%llx\r\n", err_code, fault_addr);
|
||||
break;
|
||||
}
|
||||
snprintf(temp_str, MAX_STR_SIZE, "GVA(0x%llx): 0x%016lx 0x%016lx 0x%016lx 0x%016lx\r\n",
|
||||
gva, buf[0], buf[1], buf[2], buf[3]);
|
||||
shell_puts(temp_str);
|
||||
gva += 32UL;
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t shell_dump_guest_mem(int32_t argc, char **argv)
|
||||
{
|
||||
uint16_t vm_id, pcpu_id;
|
||||
int32_t ret;
|
||||
uint64_t gva;
|
||||
uint64_t length;
|
||||
uint64_t mask = 0UL;
|
||||
struct acrn_vm *vm;
|
||||
struct acrn_vcpu *vcpu = NULL;
|
||||
struct guest_mem_dump dump;
|
||||
|
||||
/* User input invalidation */
|
||||
if (argc != 4) {
|
||||
ret = -EINVAL;
|
||||
} else {
|
||||
vm_id = sanitize_vmid((uint16_t)strtol_deci(argv[1]));
|
||||
gva = strtoul_hex(argv[2]);
|
||||
length = (uint64_t)strtol_deci(argv[3]);
|
||||
|
||||
vm = get_vm_from_vmid(vm_id);
|
||||
vcpu = vcpu_from_vid(vm, BOOT_CPU_ID);
|
||||
|
||||
dump.vcpu = vcpu;
|
||||
dump.gva = gva;
|
||||
dump.len = length;
|
||||
|
||||
pcpu_id = pcpuid_from_vcpu(vcpu);
|
||||
if (pcpu_id == get_pcpu_id()) {
|
||||
dump_guest_mem(&dump);
|
||||
} else {
|
||||
bitmap_set_nolock(pcpu_id, &mask);
|
||||
smp_call_function(mask, dump_guest_mem, &dump);
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t shell_to_vm_console(int32_t argc, char **argv)
|
||||
{
|
||||
char temp_str[TEMP_STR_SIZE];
|
||||
|
@ -60,6 +60,10 @@ struct shell {
|
||||
#define SHELL_CMD_DUMP_HOST_MEM_PARAM "<addr, length>"
|
||||
#define SHELL_CMD_DUMP_HOST_MEM_HELP "Dump host memory, starting at a given address(Hex), and for a given length (Dec in bytes)"
|
||||
|
||||
#define SHELL_CMD_DUMP_GUEST_MEM "dump_guest_mem"
|
||||
#define SHELL_CMD_DUMP_GUEST_MEM_PARAM "<vm_id, addr, length>"
|
||||
#define SHELL_CMD_DUMP_GUEST_MEM_HELP "Dump guest memory, vm id(Dec), starting at a given address(Hex), and for a given length (Dec in bytes)"
|
||||
|
||||
#define SHELL_CMD_VM_CONSOLE "vm_console"
|
||||
#define SHELL_CMD_VM_CONSOLE_PARAM "<vm id>"
|
||||
#define SHELL_CMD_VM_CONSOLE_HELP "Switch to the VM's console. Use [Ctrl+Spacebar] to return to the ACRN shell "\
|
||||
|
@ -263,6 +263,12 @@ struct vcpu_dump {
|
||||
uint32_t str_max;
|
||||
};
|
||||
|
||||
struct guest_mem_dump {
|
||||
struct acrn_vcpu *vcpu;
|
||||
uint64_t gva;
|
||||
uint64_t len;
|
||||
};
|
||||
|
||||
static inline bool is_vcpu_bsp(const struct acrn_vcpu *vcpu)
|
||||
{
|
||||
return (vcpu->vcpu_id == BOOT_CPU_ID);
|
||||
|
Loading…
Reference in New Issue
Block a user