From 69fef2e685597e51ce2103e8701e90d210ec0640 Mon Sep 17 00:00:00 2001 From: Yifan Liu Date: Fri, 16 Jul 2021 15:09:00 +0800 Subject: [PATCH] hv: debug: Add hv console callback to VM-exit event In some scenarios (e.g., nested) where lapic-pt is enabled for a vcpu running on a pcpu hosting console timer, the hv console will be inaccessible. This patch adds the console callback to every VM-exit event so that the console can still be somewhat functional under such circumstance. Since this is VM-exit driven, the VM-exit/second can be low in certain cases (e.g., idle or running stress workload). In extreme cases where the guest panics/hangs, there will be no VM-exits at all. In most cases, the shell is laggy but functional (probably enough for debugging purpose). Tracked-On: #6312 Signed-off-by: Yifan Liu --- hypervisor/arch/x86/guest/vmexit.c | 3 +++ hypervisor/debug/console.c | 22 ++++++++++++++++++++++ hypervisor/include/debug/console.h | 2 ++ hypervisor/release/console.c | 1 + 4 files changed, 28 insertions(+) diff --git a/hypervisor/arch/x86/guest/vmexit.c b/hypervisor/arch/x86/guest/vmexit.c index affb0237e..22e588e6f 100644 --- a/hypervisor/arch/x86/guest/vmexit.c +++ b/hypervisor/arch/x86/guest/vmexit.c @@ -22,6 +22,7 @@ #include #include #include +#include /* * According to "SDM APPENDIX C VMX BASIC EXIT REASONS", @@ -292,6 +293,8 @@ int32_t vmexit_handler(struct acrn_vcpu *vcpu) } } + console_vmexit_callback(vcpu); + return ret; } diff --git a/hypervisor/debug/console.c b/hypervisor/debug/console.c index 826f1a2c4..0e5189b69 100644 --- a/hypervisor/debug/console.c +++ b/hypervisor/debug/console.c @@ -172,6 +172,28 @@ void console_setup_timer(void) } } +/* When lapic-pt is enabled for a vcpu working on the pcpu hosting + * console timer (currently BSP), we utilize vm-exits to drive the console. + * + * Note that currently this approach will result in a laggy shell when + * the number of VM-exits/second is low (which is mostly true when lapic-pt is + * enabled). + */ +void console_vmexit_callback(struct acrn_vcpu *vcpu) +{ + static uint64_t prev_tsc = 0; + uint64_t tsc; + + /* console_setup_timer is called on BSP only. */ + if ((pcpuid_from_vcpu(vcpu) == BSP_CPU_ID) && (is_lapic_pt_enabled(vcpu))) { + tsc = cpu_ticks(); + if (tsc - prev_tsc > (TICKS_PER_MS * CONSOLE_KICK_TIMER_TIMEOUT)) { + console_timer_callback(NULL); + prev_tsc = tsc; + } + } +} + void suspend_console(void) { del_timer(&console_timer); diff --git a/hypervisor/include/debug/console.h b/hypervisor/include/debug/console.h index 9819c1a41..768cb854b 100644 --- a/hypervisor/include/debug/console.h +++ b/hypervisor/include/debug/console.h @@ -8,6 +8,7 @@ #define CONSOLE_H #include +#include /** Initializes the console module. * @@ -35,6 +36,7 @@ void console_putc(const char *ch); char console_getc(void); void console_setup_timer(void); +void console_vmexit_callback(struct acrn_vcpu *vcpu); void suspend_console(void); void resume_console(void); diff --git a/hypervisor/release/console.c b/hypervisor/release/console.c index 7866bca06..910fc7c36 100644 --- a/hypervisor/release/console.c +++ b/hypervisor/release/console.c @@ -27,6 +27,7 @@ void suspend_console(void) {} void resume_console(void) {} bool handle_dbg_cmd(__unused const char *cmd, __unused int32_t len) { return false; } +void console_vmexit_callback(__unused struct acrn_vcpu *vcpu) {} void shell_init(void) {} void shell_kick(void) {}