[PATCH 3/4] HV: Implement smp call for lapic_pt VMs using NMI


Kaige Fu
 

There are some functions which rely on smp call, such as vcpu_dumpreg.
This function is very useful when debug guest hang issue as it can provides
the vCPU contexts where the guest hang at.

So, this patch implements smp call for lapic_pt VMs using NMI to make these
functions work.

Signed-off-by: Kaige Fu <kaige.fu@...>
---
hypervisor/arch/x86/guest/virq.c | 6 ++++++
hypervisor/arch/x86/guest/vmexit.c | 6 ++++++
hypervisor/arch/x86/irq.c | 6 ++++++
hypervisor/arch/x86/notify.c | 10 +++++++++-
4 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/hypervisor/arch/x86/guest/virq.c b/hypervisor/arch/x86/guest/virq.c
index 1099d8da..7433af2d 100644
--- a/hypervisor/arch/x86/guest/virq.c
+++ b/hypervisor/arch/x86/guest/virq.c
@@ -213,6 +213,12 @@ int32_t vcpu_queue_exception(struct acrn_vcpu *vcpu, uint32_t vector_arg, uint32
* or not in order to support vNMI.
*/
pr_dbg("This NMI is used as notification signal. So ignore it.");
+
+ /*
+ * NMI is used to kick the target cpu out of VMX non-root mode when lapic
+ * is passthroughed to the guest. And it also serves for smp call.
+ */
+ exec_smp_call();
} else {
vcpu_make_request(vcpu, ACRN_REQUEST_EXCP);
}
diff --git a/hypervisor/arch/x86/guest/vmexit.c b/hypervisor/arch/x86/guest/vmexit.c
index ac73f4ca..8594e742 100644
--- a/hypervisor/arch/x86/guest/vmexit.c
+++ b/hypervisor/arch/x86/guest/vmexit.c
@@ -203,6 +203,12 @@ int32_t vmexit_handler(struct acrn_vcpu *vcpu)
* or not in order to support vNMI.
*/
pr_dbg("This NMI is used as notification signal. So ignore it.");
+
+ /*
+ * NMI is used to kick the target cpu out of VMX non-root mode when lapic
+ * is passthroughed to the guest. And it also serves for smp call.
+ */
+ exec_smp_call();
} else {
vcpu_make_request(vcpu, ACRN_REQUEST_NMI);
vcpu->arch.idt_vectoring_info = 0U;
diff --git a/hypervisor/arch/x86/irq.c b/hypervisor/arch/x86/irq.c
index b0ba0351..927d856c 100644
--- a/hypervisor/arch/x86/irq.c
+++ b/hypervisor/arch/x86/irq.c
@@ -415,6 +415,12 @@ void handle_nmi(__unused struct intr_excp_ctx *ctx)
value32 = exec_vmread32(VMX_PROC_VM_EXEC_CONTROLS);
value32 |= VMX_PROCBASED_CTLS_NMI_WINEXIT;
exec_vmwrite32(VMX_PROC_VM_EXEC_CONTROLS, value32);
+
+ /*
+ * NMI is used to kick the target cpu out of VMX non-root mode when lapic
+ * is passthroughed to the guest. And it also serves for smp call.
+ */
+ exec_smp_call();
}

static void init_irq_descs(void)
diff --git a/hypervisor/arch/x86/notify.c b/hypervisor/arch/x86/notify.c
index d67fdabd..3585667b 100644
--- a/hypervisor/arch/x86/notify.c
+++ b/hypervisor/arch/x86/notify.c
@@ -46,11 +46,19 @@ static void kick_notification(__unused uint32_t irq, __unused void *data)

static void notify_cpus(uint64_t mask)
{
+ struct acrn_vcpu *vcpu;
uint16_t pcpu_id = ffs64(mask);

while (pcpu_id < MAX_PCPU_NUM) {
bitmap_clear_nolock(pcpu_id, &mask);
- send_single_ipi(pcpu_id, VECTOR_NOTIFY_VCPU);
+
+ vcpu = get_running_vcpu(pcpu_id);
+ if ((vcpu != NULL) && is_lapic_pt_enabled(vcpu)) {
+ send_single_nmi(pcpu_id);
+ } else {
+ send_single_ipi(pcpu_id, VECTOR_NOTIFY_VCPU);
+ }
+
pcpu_id = ffs64(mask);
}
}
--
2.20.0

Join acrn-dev@lists.projectacrn.org to automatically receive all group messages.