mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-04-30 12:44:07 +00:00
MISRAC has requirement about implict conversion: actual to formal param. This patch is used to fix part of these violations. 1.Add a new structure seg_desc_vmcs to hold the VMCS field address of segment selector to clean up seg_desc structure. 2.Add the definition of maximum MSI entry and the relevant judgement. 3.The violations in shell.c, logmsg.c will be fixed in other series of patches with modification of function snprintf(), vsnprintf() and other related usages. v1->v2: *Move the definition of struct seg_desc_vmcs from instr_emul.h to instr_emul.c. *Modify the formal parameter type in function definition from uint8_t to char instead of using cast. *Drop the const declaration for char data in formal parameter. v2->v3: *update the data missing conversion. *change type of internal parameter len to avoid casting in npklog.c. *change the conversion from signed char to unsigned int in uart16550_getc() to solve sign-extension. Tracked-On: #861 Signed-off-by: Junjun Shan <junjun.shan@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
98 lines
2.4 KiB
C
98 lines
2.4 KiB
C
/*
|
|
* Copyright (C) 2018 Intel Corporation. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include <hypervisor.h>
|
|
|
|
static uint32_t notification_irq = IRQ_INVALID;
|
|
|
|
static uint64_t smp_call_mask = 0UL;
|
|
|
|
/* run in interrupt context */
|
|
static void kick_notification(__unused uint32_t irq, __unused void *data)
|
|
{
|
|
/* Notification vector is used to kick taget cpu out of non-root mode.
|
|
* And it also serves for smp call.
|
|
*/
|
|
uint16_t pcpu_id = get_cpu_id();
|
|
|
|
if (bitmap_test(pcpu_id, &smp_call_mask)) {
|
|
struct smp_call_info_data *smp_call =
|
|
&per_cpu(smp_call_info, pcpu_id);
|
|
|
|
if (smp_call->func != NULL)
|
|
smp_call->func(smp_call->data);
|
|
bitmap_clear_nolock(pcpu_id, &smp_call_mask);
|
|
}
|
|
}
|
|
|
|
void smp_call_function(uint64_t mask, smp_call_func_t func, void *data)
|
|
{
|
|
uint16_t pcpu_id;
|
|
struct smp_call_info_data *smp_call;
|
|
|
|
/* wait for previous smp call complete, which may run on other cpus */
|
|
while (atomic_cmpxchg64(&smp_call_mask, 0UL, mask & INVALID_BIT_INDEX)
|
|
!= 0UL);
|
|
pcpu_id = ffs64(mask);
|
|
while (pcpu_id != INVALID_BIT_INDEX) {
|
|
bitmap_clear_nolock(pcpu_id, &mask);
|
|
if (bitmap_test(pcpu_id, &pcpu_active_bitmap)) {
|
|
smp_call = &per_cpu(smp_call_info, pcpu_id);
|
|
smp_call->func = func;
|
|
smp_call->data = data;
|
|
} else {
|
|
/* pcpu is not in active, print error */
|
|
pr_err("pcpu_id %d not in active!", pcpu_id);
|
|
bitmap_clear_nolock(pcpu_id, &smp_call_mask);
|
|
}
|
|
pcpu_id = ffs64(mask);
|
|
}
|
|
send_dest_ipi((uint32_t)smp_call_mask, VECTOR_NOTIFY_VCPU,
|
|
INTR_LAPIC_ICR_LOGICAL);
|
|
/* wait for current smp call complete */
|
|
wait_sync_change(&smp_call_mask, 0UL);
|
|
}
|
|
|
|
static int request_notification_irq(irq_action_t func, void *data)
|
|
{
|
|
int32_t retval;
|
|
|
|
if (notification_irq != IRQ_INVALID) {
|
|
pr_info("%s, Notification vector already allocated on this CPU",
|
|
__func__);
|
|
return -EBUSY;
|
|
}
|
|
|
|
/* all cpu register the same notification vector */
|
|
retval = request_irq(NOTIFY_IRQ, func, data, IRQF_NONE);
|
|
if (retval < 0) {
|
|
pr_err("Failed to add notify isr");
|
|
return -ENODEV;
|
|
}
|
|
|
|
notification_irq = (uint32_t)retval;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void setup_notification(void)
|
|
{
|
|
uint16_t cpu = get_cpu_id();
|
|
|
|
if (cpu > 0U) {
|
|
return;
|
|
}
|
|
|
|
/* support IPI notification, VM0 will register all CPU */
|
|
if (request_notification_irq(kick_notification, NULL) < 0) {
|
|
pr_err("Failed to setup notification");
|
|
return;
|
|
}
|
|
|
|
dev_dbg(ACRN_DBG_PTIRQ, "NOTIFY: irq[%d] setup vector %x",
|
|
notification_irq, irq_to_vector(notification_irq));
|
|
}
|