hv: bugfix for debug commands with smp_call

With cpu-sharing enabled, there are more than 1 vcpu on 1 pcpu, so the
smp_call handler should switch the vmcs to the target vcpu's vmcs. Then
get the info.

dump_vcpu_reg and dump_guest_mem should run on certain vmcs, otherwise,
there will be #GP error.

Renaming:
vcpu_dumpreg -> dump_vcpu_reg
switch_vmcs -> load_vmcs

Tracked-On: #4178
Signed-off-by: Conghui Chen <conghui.chen@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Conghui Chen 2019-12-02 11:57:12 +00:00 committed by wenlingz
parent 47139bd78c
commit d48da2af3a
4 changed files with 24 additions and 16 deletions

View File

@ -768,7 +768,7 @@ static void context_switch_in(struct thread_object *next)
struct acrn_vcpu *vcpu = list_entry(next, struct acrn_vcpu, thread_obj);
struct ext_context *ectx = &(vcpu->arch.contexts[vcpu->arch.cur_context].ext_ctx);
switch_vmcs(vcpu);
load_vmcs(vcpu);
msr_write(MSR_IA32_STAR, ectx->ia32_star);
msr_write(MSR_IA32_LSTAR, ectx->ia32_lstar);

View File

@ -540,7 +540,7 @@ void init_vmcs(struct acrn_vcpu *vcpu)
/**
* @pre vcpu != NULL
*/
void switch_vmcs(const struct acrn_vcpu *vcpu)
void load_vmcs(const struct acrn_vcpu *vcpu)
{
uint64_t vmcs_pa;
void **vmcs_ptr = &get_cpu_var(vmcs_run);

View File

@ -20,6 +20,7 @@
#include <logmsg.h>
#include <version.h>
#include <shell.h>
#include <vmcs.h>
#define TEMP_STR_SIZE 60U
#define MAX_STR_SIZE 256U
@ -686,7 +687,7 @@ static int32_t shell_list_vcpu(__unused int32_t argc, __unused char **argv)
#define DUMPREG_SP_SIZE 32
/* the input 'data' must != NULL and indicate a vcpu structure pointer */
static void vcpu_dumpreg(void *data)
static void dump_vcpu_reg(void *data)
{
int32_t status;
uint64_t i, fault_addr, tmp[DUMPREG_SP_SIZE];
@ -695,6 +696,11 @@ static void vcpu_dumpreg(void *data)
struct acrn_vcpu *vcpu = dump->vcpu;
char *str = dump->str;
size_t len, size = dump->str_max;
uint16_t pcpu_id = get_pcpu_id();
struct acrn_vcpu *curr = get_running_vcpu(pcpu_id);
/* switch vmcs */
load_vmcs(vcpu);
len = snprintf(str, size,
"= VM ID %d ==== CPU ID %hu========================\r\n"
@ -764,6 +770,9 @@ static void vcpu_dumpreg(void *data)
str += len;
}
}
if (curr != NULL) {
load_vmcs(curr);
}
return;
overflow:
@ -818,12 +827,8 @@ static int32_t shell_vcpu_dumpreg(int32_t argc, char **argv)
dump.vcpu = vcpu;
dump.str = shell_log_buf;
dump.str_max = SHELL_LOG_BUF_SIZE;
if (pcpu_id == get_pcpu_id()) {
vcpu_dumpreg(&dump);
} else {
bitmap_set_nolock(pcpu_id, &mask);
smp_call_function(mask, vcpu_dumpreg, &dump);
}
bitmap_set_nolock(pcpu_id, &mask);
smp_call_function(mask, dump_vcpu_reg, &dump);
shell_puts(shell_log_buf);
status = 0;
@ -872,6 +877,10 @@ static void dump_guest_mem(void *data)
uint64_t length = dump->len;
uint64_t gva = dump->gva;
struct acrn_vcpu *vcpu = dump->vcpu;
uint16_t pcpu_id = get_pcpu_id();
struct acrn_vcpu *curr = get_running_vcpu(pcpu_id);
load_vmcs(vcpu);
/* Change the length to a multiple of 32 if the length is not */
loop_cnt = ((length & 0x1fUL) == 0UL) ? ((length >> 5UL)) : ((length >> 5UL) + 1UL);
@ -887,6 +896,9 @@ static void dump_guest_mem(void *data)
shell_puts(temp_str);
gva += 32UL;
}
if (curr != NULL) {
load_vmcs(curr);
}
}
static int32_t shell_dump_guest_mem(int32_t argc, char **argv)
@ -916,12 +928,8 @@ static int32_t shell_dump_guest_mem(int32_t argc, char **argv)
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);
}
bitmap_set_nolock(pcpu_id, &mask);
smp_call_function(mask, dump_guest_mem, &dump);
ret = 0;
}

View File

@ -41,7 +41,7 @@ static inline uint64_t apic_access_offset(uint64_t qual)
return (qual & APIC_ACCESS_OFFSET);
}
void init_vmcs(struct acrn_vcpu *vcpu);
void switch_vmcs(const struct acrn_vcpu *vcpu);
void load_vmcs(const struct acrn_vcpu *vcpu);
void switch_apicv_mode_x2apic(struct acrn_vcpu *vcpu);
#endif /* ASSEMBLER */