hv: improve smp call to support debugging RTVM

Improve SMP call to support ACRN shell to operate RTVM.
before, the RTVM CPU can't be kicked off by notification IPI,
so some shell commands can't support it, like rdmsr/wrmsr,
memory/registers dump. So INIT will be used for RTVM, which
LAPIC is pass-thru.

Tracked-On: #8207
Signed-off-by: Minggui Cao <minggui.cao@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Minggui Cao 2022-08-22 15:44:12 +08:00 committed by acrnsi-robot
parent bc4c773cf8
commit 6d4ca4b3a1
5 changed files with 38 additions and 12 deletions

View File

@ -388,6 +388,11 @@ int32_t acrn_handle_pending_request(struct acrn_vcpu *vcpu)
if (bitmap_test_and_clear_lock(ACRN_REQUEST_EOI_EXIT_BITMAP_UPDATE, pending_req_bits)) {
vcpu_set_vmcs_eoi_exit(vcpu);
}
if (bitmap_test_and_clear_lock(ACRN_REQUEST_SMP_CALL, pending_req_bits)) {
handle_smp_call();
}
}
}

View File

@ -13,6 +13,7 @@
#include <asm/per_cpu.h>
#include <asm/lapic.h>
#include <asm/guest/vm.h>
#include <asm/guest/virq.h>
static uint32_t notification_irq = IRQ_INVALID;
@ -37,6 +38,11 @@ static void kick_notification(__unused uint32_t irq, __unused void *data)
}
}
void handle_smp_call(void)
{
kick_notification(0, NULL);
}
void smp_call_function(uint64_t mask, smp_call_func_t func, void *data)
{
uint16_t pcpu_id;
@ -47,10 +53,21 @@ void smp_call_function(uint64_t mask, smp_call_func_t func, void *data)
pcpu_id = ffs64(mask);
while (pcpu_id < MAX_PCPU_NUM) {
bitmap_clear_nolock(pcpu_id, &mask);
if (is_pcpu_active(pcpu_id)) {
if (pcpu_id == get_pcpu_id()) {
func(data);
bitmap_clear_nolock(pcpu_id, &smp_call_mask);
} else if (is_pcpu_active(pcpu_id)) {
smp_call = &per_cpu(smp_call_info, pcpu_id);
smp_call->func = func;
smp_call->data = data;
struct acrn_vcpu *vcpu = get_ever_run_vcpu(pcpu_id);
if ((vcpu != NULL) && (is_lapic_pt_enabled(vcpu))) {
vcpu_make_request(vcpu, ACRN_REQUEST_SMP_CALL);
} else {
send_single_ipi(pcpu_id, NOTIFY_VCPU_VECTOR);
}
} else {
/* pcpu is not in active, print error */
pr_err("pcpu_id %d not in active!", pcpu_id);
@ -58,7 +75,6 @@ void smp_call_function(uint64_t mask, smp_call_func_t func, void *data)
}
pcpu_id = ffs64(mask);
}
send_dest_ipi_mask((uint32_t)smp_call_mask, NOTIFY_VCPU_VECTOR);
/* wait for current smp call complete */
wait_sync_change(&smp_call_mask, 0UL);
}

View File

@ -993,12 +993,6 @@ static int32_t shell_vcpu_dumpreg(int32_t argc, char **argv)
goto out;
}
if (is_lapic_pt_enabled(vcpu)) {
shell_puts("Please switch to vlapic mode for vcpu register dump!\r\n");
status = 0;
goto out;
}
pcpu_id = pcpuid_from_vcpu(vcpu);
dump.vcpu = vcpu;
dump.str = shell_log_buf;
@ -1568,9 +1562,13 @@ static int32_t shell_rdmsr(int32_t argc, char **argv)
}
if (ret == 0) {
val = msr_read_pcpu(msr_index, pcpu_id);
snprintf(str, MAX_STR_SIZE, "rdmsr(0x%x):0x%lx\n", msr_index, val);
shell_puts(str);
if (pcpu_id < get_pcpu_nums()) {
val = msr_read_pcpu(msr_index, pcpu_id);
snprintf(str, MAX_STR_SIZE, "rdmsr(0x%x):0x%lx\n", msr_index, val);
shell_puts(str);
} else {
shell_puts("pcpu id is out of range!\n");
}
}
return ret;
@ -1606,7 +1604,11 @@ static int32_t shell_wrmsr(int32_t argc, char **argv)
}
if (ret == 0) {
msr_write_pcpu(msr_index, val, pcpu_id);
if (pcpu_id < get_pcpu_nums()) {
msr_write_pcpu(msr_index, val, pcpu_id);
} else {
shell_puts("pcpu id is out of range!\n");
}
}
return ret;

View File

@ -105,6 +105,8 @@
*/
#define ACRN_REQUEST_SPLIT_LOCK 10U
#define ACRN_REQUEST_SMP_CALL 11U
/**
* @}
*/

View File

@ -17,6 +17,7 @@ struct acrn_vm;
void smp_call_function(uint64_t mask, smp_call_func_t func, void *data);
void setup_notification(void);
void handle_smp_call(void);
void setup_pi_notification(void);
#endif