mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-10 12:32:45 +00:00
hv: debug: add debug command inj_guest_exp
inj_guest_exp can be used to inject a virtual exception to a specified vcpu of a vm. The command format is as follows: inj_guest_exp <vm id, vcpu id, exception_num> Tracked-On: #6468 Signed-off-by: Jian Jun Chen <jian.jun.chen@intel.com>
This commit is contained in:
parent
8ae4c90747
commit
857890e788
@ -21,6 +21,7 @@
|
||||
#include <version.h>
|
||||
#include <shell.h>
|
||||
#include <asm/guest/vmcs.h>
|
||||
#include <asm/guest/virq.h>
|
||||
#include <asm/host_pm.h>
|
||||
#include <asm/tsc.h>
|
||||
|
||||
@ -53,6 +54,7 @@ static int32_t shell_cpuid(int32_t argc, char **argv);
|
||||
static int32_t shell_reboot(int32_t argc, char **argv);
|
||||
static int32_t shell_rdmsr(int32_t argc, char **argv);
|
||||
static int32_t shell_wrmsr(int32_t argc, char **argv);
|
||||
static int32_t shell_vcpu_inject_exception(int32_t argc, char **argv);
|
||||
static int32_t shell_show_vmexit_profile(__unused int argc, __unused char **argv);
|
||||
|
||||
static struct shell_cmd shell_cmds[] = {
|
||||
@ -98,6 +100,12 @@ static struct shell_cmd shell_cmds[] = {
|
||||
.help_str = SHELL_CMD_DUMP_GUEST_MEM_HELP,
|
||||
.fcn = shell_dump_guest_mem,
|
||||
},
|
||||
{
|
||||
.str = SHELL_CMD_INJ_GUEST_EXP,
|
||||
.cmd_param = SHELL_CMD_INJ_GUEST_EXP_PARAM,
|
||||
.help_str = SHELL_CMD_INJ_GUEST_EXP_HELP,
|
||||
.fcn = shell_vcpu_inject_exception,
|
||||
},
|
||||
{
|
||||
.str = SHELL_CMD_VM_CONSOLE,
|
||||
.cmd_param = SHELL_CMD_VM_CONSOLE_PARAM,
|
||||
@ -1455,6 +1463,84 @@ static int32_t shell_wrmsr(int32_t argc, char **argv)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void inject_vcpu_exception(void *data)
|
||||
{
|
||||
struct vcpu_inject_exception *inject = data;
|
||||
struct acrn_vcpu *vcpu = inject->vcpu;
|
||||
uint32_t exception = inject->exception;
|
||||
|
||||
(void)vcpu_queue_exception(vcpu, exception, 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int32_t shell_vcpu_inject_exception(int32_t argc, char **argv)
|
||||
{
|
||||
char temp_str[MAX_STR_SIZE];
|
||||
int32_t status = 0;
|
||||
uint16_t vm_id;
|
||||
uint16_t vcpu_id, pcpu_id;
|
||||
uint32_t exception;
|
||||
struct acrn_vm *vm;
|
||||
struct acrn_vcpu *vcpu;
|
||||
uint64_t mask = 0UL;
|
||||
struct vcpu_inject_exception inject;
|
||||
|
||||
/* User input invalidation */
|
||||
if (argc != 4) {
|
||||
shell_puts("Please enter cmd with <vm_id, vcpu_id, exception_num>\r\n");
|
||||
status = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
status = strtol_deci(argv[1]);
|
||||
if (status < 0) {
|
||||
goto out;
|
||||
}
|
||||
vm_id = sanitize_vmid((uint16_t)status);
|
||||
vcpu_id = (uint16_t)strtol_deci(argv[2]);
|
||||
exception = (uint32_t)strtol_deci(argv[3]);
|
||||
|
||||
vm = get_vm_from_vmid(vm_id);
|
||||
if (is_poweroff_vm(vm)) {
|
||||
shell_puts("No vm found in the input <vm_id, vcpu_id>\r\n");
|
||||
status = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (vcpu_id >= vm->hw.created_vcpus) {
|
||||
shell_puts("vcpu id is out of range\r\n");
|
||||
status = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
vcpu = vcpu_from_vid(vm, vcpu_id);
|
||||
if (vcpu->state == VCPU_OFFLINE) {
|
||||
shell_puts("vcpu is offline\r\n");
|
||||
status = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (exception > 31U) {
|
||||
shell_puts("invalid exception number\r\n");
|
||||
status = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
pcpu_id = pcpuid_from_vcpu(vcpu);
|
||||
inject.vcpu = vcpu;
|
||||
inject.exception = exception;
|
||||
bitmap_set_nolock(pcpu_id, &mask);
|
||||
smp_call_function(mask, inject_vcpu_exception, &inject);
|
||||
snprintf(temp_str, MAX_STR_SIZE, "Exception %02x is injected to vm(0x%d): vcpu(0x%d)\r\n",
|
||||
exception, vm->vm_id, vcpu->vcpu_id);
|
||||
shell_puts(temp_str);
|
||||
status = 0;
|
||||
|
||||
out:
|
||||
return status;
|
||||
}
|
||||
|
||||
static void get_vmexit_profile_per_pcpu(char *str_arg, size_t str_max)
|
||||
{
|
||||
char *str = str_arg;
|
||||
|
@ -107,6 +107,10 @@ struct shell {
|
||||
#define SHELL_CMD_WRMSR_HELP "Write value (in hexadecimal) to the MSR at msr_index (in hexadecimal) for CPU"\
|
||||
" ID pcpu_id"
|
||||
|
||||
#define SHELL_CMD_INJ_GUEST_EXP "inj_guest_exp"
|
||||
#define SHELL_CMD_INJ_GUEST_EXP_PARAM "<vm id, vcpu id, exception_num>"
|
||||
#define SHELL_CMD_INJ_GUEST_EXP_HELP "Inject an exception to a specific vCPU"
|
||||
|
||||
#define SHELL_CMD_VMEXIT "vmexit"
|
||||
#define SHELL_CMD_VMEXIT_PARAM NULL
|
||||
#define SHELL_CMD_VMEXIT_HELP "show vmexit profiling, use: vmexit [clear | enable | disable] enabled by default"
|
||||
|
@ -329,6 +329,11 @@ struct guest_mem_dump {
|
||||
uint64_t len;
|
||||
};
|
||||
|
||||
struct vcpu_inject_exception {
|
||||
struct acrn_vcpu *vcpu;
|
||||
uint32_t exception;
|
||||
};
|
||||
|
||||
static inline bool is_vcpu_bsp(const struct acrn_vcpu *vcpu)
|
||||
{
|
||||
return (vcpu->vcpu_id == BSP_CPU_ID);
|
||||
|
Loading…
Reference in New Issue
Block a user