mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2026-05-03 17:37:54 +00:00
hv: riscv add vSBI IPI extension support
Implement the SBI IPI (Inter-Processor Interrupt) extension to enable guest VMs to send software interrupts between virtual CPUs. The implementation handles the SBI_IPI_SEND_IPI function call, which allows a guest to target one or more vCPUs using either: - A mask (bitmap of target harts relative to a base hart ID) - Broadcast mode (when mask_base is UINT64_MAX) The IPI is delivered by asserting the VS-level software interrupt (VSSIP, bit 2) on each target vCPU. Proper validation is performed to ensure hart IDs are within valid range and all masked harts exist. Tracked-On: #8851 Signed-off-by: Haoyu Tang <haoyu.tang@intel.com> Acked-by: Wang Yu1 <yu1.wang@intel.com>
This commit is contained in:
@@ -79,6 +79,7 @@ VP_C_SRCS += arch/riscv/guest/vsbi/vsbi_srst.c
|
||||
VP_C_SRCS += arch/riscv/guest/vsbi/vsbi_acrn.c
|
||||
VP_C_SRCS += arch/riscv/guest/vsbi/vsbi_dbcn.c
|
||||
VP_C_SRCS += arch/riscv/guest/vsbi/vsbi_timer.c
|
||||
VP_C_SRCS += arch/riscv/guest/vsbi/vsbi_ipi.c
|
||||
|
||||
VM_CFG_C_SRCS += $(SCENARIO_CFG_DIR)/vm_configurations.c
|
||||
VM_CFG_C_SRCS += $(BOARD_CFG_DIR)/pci_dev.c
|
||||
|
||||
@@ -77,6 +77,7 @@ extern const struct acrn_vsbi_extension vsbi_ext_srst;
|
||||
extern const struct acrn_vsbi_extension vsbi_ext_timer;
|
||||
extern const struct acrn_vsbi_extension vsbi_ext_acrn;
|
||||
extern const struct acrn_vsbi_extension vsbi_ext_dbcn;
|
||||
extern const struct acrn_vsbi_extension vsbi_ext_ipi;
|
||||
static const struct acrn_vsbi_extension *vsbi_extensions[MAX_NUM_SUPPORTED_VSBI_EXT] = {
|
||||
&vsbi_ext_base,
|
||||
&vsbi_ext_hsm,
|
||||
@@ -84,6 +85,7 @@ static const struct acrn_vsbi_extension *vsbi_extensions[MAX_NUM_SUPPORTED_VSBI_
|
||||
&vsbi_ext_acrn,
|
||||
&vsbi_ext_dbcn,
|
||||
&vsbi_ext_timer,
|
||||
&vsbi_ext_ipi,
|
||||
};
|
||||
|
||||
void init_vsbi(struct acrn_vm *vm)
|
||||
|
||||
69
hypervisor/arch/riscv/guest/vsbi/vsbi_ipi.c
Normal file
69
hypervisor/arch/riscv/guest/vsbi/vsbi_ipi.c
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2025 Intel Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
#include <vcpu.h>
|
||||
#include <vm.h>
|
||||
#include <per_cpu.h>
|
||||
#include <asm/sbi.h>
|
||||
#include <asm/trap.h>
|
||||
#include <asm/guest/vsbi.h>
|
||||
#include <asm/guest/virq.h>
|
||||
#include <logmsg.h>
|
||||
|
||||
static int32_t vcpu_sbi_ipi_ecall_handler(struct acrn_vcpu *vcpu, __unused uint64_t ext_id,
|
||||
uint64_t func_id, uint64_t *args, __unused struct vsbi_ret *out)
|
||||
{
|
||||
int32_t ret = SBI_SUCCESS;
|
||||
uint16_t i;
|
||||
struct acrn_vcpu *tmp_vcpu;
|
||||
uint64_t mask = args[0];
|
||||
uint64_t mask_base = args[1];
|
||||
uint64_t bit_index = 0;
|
||||
int early_exit = 0;
|
||||
int is_broadcast = (mask_base == UINT64_MAX);
|
||||
|
||||
switch (func_id) {
|
||||
case SBI_IPI_FID_SEND_IPI:
|
||||
foreach_vcpu(i, vcpu->vm, tmp_vcpu) {
|
||||
if (!is_broadcast) {
|
||||
if (tmp_vcpu->vcpu_id < mask_base)
|
||||
continue;
|
||||
bit_index = tmp_vcpu->vcpu_id - mask_base;
|
||||
if (bit_index >= 64UL) {
|
||||
early_exit = 1;
|
||||
break;
|
||||
}
|
||||
if (!(mask & (1UL << bit_index)))
|
||||
continue;
|
||||
}
|
||||
|
||||
/* asserts a VS-level software interrupt to target VCPU */
|
||||
ret = vcpu_set_intr(tmp_vcpu, TRAP_CAUSE_IRQ_VS_SOFT);
|
||||
if (ret < 0) {
|
||||
pr_err("vsbi ipi: failed to send ipi to vcpu %hu", tmp_vcpu->vcpu_id);
|
||||
early_exit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_broadcast && early_exit)
|
||||
ret = SBI_ERR_INVALID_PARAM;
|
||||
break;
|
||||
default:
|
||||
ret = SBI_ERR_NOT_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const struct acrn_vsbi_extension vsbi_ext_ipi = {
|
||||
.name = "ipi",
|
||||
.eid_start = SBI_EID_IPI,
|
||||
.eid_end = SBI_EID_IPI,
|
||||
.handler = vcpu_sbi_ipi_ecall_handler,
|
||||
};
|
||||
Reference in New Issue
Block a user