mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-11-22 15:51:09 +00:00
hv: multiarch: abstract pcpu related data from x86
Move phys_cpu_num and pcpu_active_bitmap to common, which could be only accessed by interfaces provided by smp.h. v2->v3: 1. move ALL_CPUS_MASK/AP_MASK to common cpu.h v1->v2: 1. preserve phys_cpu_num in x86 but implement arch_get_num_available_cpus() to provide interface for common code to access. 2. change function name test_xx to check_xx Tracked-On: #8801 Signed-off-by: hangliu1 <hang1.liu@intel.com> Reviewed-by: Wang, Yu1 <yu1.wang@intel.com> Reviewed-by: Liu, Yifan1 <yifan1.liu@intel.com> Acked-by: Wang, Yu1 <yu1.wang@intel.com>
This commit is contained in:
@@ -151,6 +151,7 @@ endif
|
|||||||
COMMON_C_SRCS += common/notify.c
|
COMMON_C_SRCS += common/notify.c
|
||||||
COMMON_C_SRCS += lib/memory.c
|
COMMON_C_SRCS += lib/memory.c
|
||||||
COMMON_C_SRCS += common/percpu.c
|
COMMON_C_SRCS += common/percpu.c
|
||||||
|
COMMON_C_SRCS += common/cpu.c
|
||||||
|
|
||||||
ifeq ($(ARCH),x86)
|
ifeq ($(ARCH),x86)
|
||||||
COMMON_C_SRCS += common/ticks.c
|
COMMON_C_SRCS += common/ticks.c
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
#include <delay.h>
|
#include <delay.h>
|
||||||
#include <thermal.h>
|
#include <thermal.h>
|
||||||
#include <common/notify.h>
|
#include <common/notify.h>
|
||||||
|
#include <cpu.h>
|
||||||
|
|
||||||
#define CPU_UP_TIMEOUT 100U /* millisecond */
|
#define CPU_UP_TIMEOUT 100U /* millisecond */
|
||||||
#define CPU_DOWN_TIMEOUT 100U /* millisecond */
|
#define CPU_DOWN_TIMEOUT 100U /* millisecond */
|
||||||
@@ -47,9 +48,6 @@ static uint16_t phys_cpu_num = 0U;
|
|||||||
static uint64_t pcpu_sync = 0UL;
|
static uint64_t pcpu_sync = 0UL;
|
||||||
static uint64_t startup_paddr = 0UL;
|
static uint64_t startup_paddr = 0UL;
|
||||||
|
|
||||||
/* physical cpu active bitmap, support up to 64 cpus */
|
|
||||||
static volatile uint64_t pcpu_active_bitmap = 0UL;
|
|
||||||
|
|
||||||
static void init_pcpu_xsave(void);
|
static void init_pcpu_xsave(void);
|
||||||
static void init_keylocker(void);
|
static void init_keylocker(void);
|
||||||
static void set_current_pcpu_id(uint16_t pcpu_id);
|
static void set_current_pcpu_id(uint16_t pcpu_id);
|
||||||
@@ -57,6 +55,15 @@ static void print_hv_banner(void);
|
|||||||
static uint16_t get_pcpu_id_from_lapic_id(uint32_t lapic_id);
|
static uint16_t get_pcpu_id_from_lapic_id(uint32_t lapic_id);
|
||||||
static uint64_t start_tick __attribute__((__section__(".bss_noinit")));
|
static uint64_t start_tick __attribute__((__section__(".bss_noinit")));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will be called by function get_pcpu_nums()
|
||||||
|
* in common/cpu.c
|
||||||
|
*/
|
||||||
|
uint16_t arch_get_pcpu_num(void)
|
||||||
|
{
|
||||||
|
return phys_cpu_num;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @pre phys_cpu_num <= MAX_PCPU_NUM
|
* @pre phys_cpu_num <= MAX_PCPU_NUM
|
||||||
*/
|
*/
|
||||||
@@ -92,24 +99,6 @@ static void pcpu_set_current_state(uint16_t pcpu_id, enum pcpu_boot_state state)
|
|||||||
per_cpu(boot_state, pcpu_id) = state;
|
per_cpu(boot_state, pcpu_id) = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @post return <= MAX_PCPU_NUM
|
|
||||||
*/
|
|
||||||
uint16_t get_pcpu_nums(void)
|
|
||||||
{
|
|
||||||
return phys_cpu_num;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_pcpu_active(uint16_t pcpu_id)
|
|
||||||
{
|
|
||||||
return bitmap_test(pcpu_id, &pcpu_active_bitmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t get_active_pcpu_bitmap(void)
|
|
||||||
{
|
|
||||||
return pcpu_active_bitmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void enable_ac_for_splitlock(void)
|
static void enable_ac_for_splitlock(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_SPLIT_LOCK_DETECTION_ENABLED
|
#ifdef CONFIG_SPLIT_LOCK_DETECTION_ENABLED
|
||||||
@@ -217,7 +206,7 @@ void init_pcpu_pre(bool is_bsp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bitmap_set_lock(pcpu_id, &pcpu_active_bitmap);
|
set_pcpu_active(pcpu_id);
|
||||||
|
|
||||||
/* Set state for this CPU to initializing */
|
/* Set state for this CPU to initializing */
|
||||||
pcpu_set_current_state(pcpu_id, PCPU_STATE_INITIALIZING);
|
pcpu_set_current_state(pcpu_id, PCPU_STATE_INITIALIZING);
|
||||||
@@ -342,7 +331,7 @@ static uint16_t get_pcpu_id_from_lapic_id(uint32_t lapic_id)
|
|||||||
uint16_t i;
|
uint16_t i;
|
||||||
uint16_t pcpu_id = INVALID_CPU_ID;
|
uint16_t pcpu_id = INVALID_CPU_ID;
|
||||||
|
|
||||||
for (i = 0U; i < phys_cpu_num; i++) {
|
for (i = 0U; i < get_pcpu_nums(); i++) {
|
||||||
if (per_cpu(arch.lapic_id, i) == lapic_id) {
|
if (per_cpu(arch.lapic_id, i) == lapic_id) {
|
||||||
pcpu_id = i;
|
pcpu_id = i;
|
||||||
break;
|
break;
|
||||||
@@ -413,7 +402,7 @@ bool start_pcpus(uint64_t mask)
|
|||||||
i = ffs64(expected_start_mask);
|
i = ffs64(expected_start_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ((pcpu_active_bitmap & mask) == mask);
|
return check_pcpus_active(mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void make_pcpu_offline(uint16_t pcpu_id)
|
void make_pcpu_offline(uint16_t pcpu_id)
|
||||||
@@ -434,7 +423,7 @@ void wait_pcpus_offline(uint64_t mask)
|
|||||||
uint32_t timeout;
|
uint32_t timeout;
|
||||||
|
|
||||||
timeout = CPU_DOWN_TIMEOUT * 1000U;
|
timeout = CPU_DOWN_TIMEOUT * 1000U;
|
||||||
while (((pcpu_active_bitmap & mask) != 0UL) && (timeout != 0U)) {
|
while (check_pcpus_inactive(mask) && (timeout != 0U)) {
|
||||||
udelay(10U);
|
udelay(10U);
|
||||||
timeout -= 10U;
|
timeout -= 10U;
|
||||||
}
|
}
|
||||||
@@ -445,7 +434,7 @@ void stop_pcpus(void)
|
|||||||
uint16_t pcpu_id;
|
uint16_t pcpu_id;
|
||||||
uint64_t mask = 0UL;
|
uint64_t mask = 0UL;
|
||||||
|
|
||||||
for (pcpu_id = 0U; pcpu_id < phys_cpu_num; pcpu_id++) {
|
for (pcpu_id = 0U; pcpu_id < get_pcpu_nums(); pcpu_id++) {
|
||||||
if (get_pcpu_id() == pcpu_id) { /* avoid offline itself */
|
if (get_pcpu_id() == pcpu_id) { /* avoid offline itself */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -497,7 +486,7 @@ void cpu_dead(void)
|
|||||||
uint16_t pcpu_id = get_pcpu_id();
|
uint16_t pcpu_id = get_pcpu_id();
|
||||||
|
|
||||||
deinit_sched(pcpu_id);
|
deinit_sched(pcpu_id);
|
||||||
if (bitmap_test(pcpu_id, &pcpu_active_bitmap)) {
|
if (is_pcpu_active(pcpu_id)) {
|
||||||
/* clean up native stuff */
|
/* clean up native stuff */
|
||||||
vmx_off();
|
vmx_off();
|
||||||
|
|
||||||
@@ -507,7 +496,7 @@ void cpu_dead(void)
|
|||||||
|
|
||||||
/* Set state to show CPU is dead */
|
/* Set state to show CPU is dead */
|
||||||
pcpu_set_current_state(pcpu_id, PCPU_STATE_DEAD);
|
pcpu_set_current_state(pcpu_id, PCPU_STATE_DEAD);
|
||||||
bitmap_clear_lock(pcpu_id, &pcpu_active_bitmap);
|
clear_pcpu_active(pcpu_id);
|
||||||
|
|
||||||
/* Halt the CPU */
|
/* Halt the CPU */
|
||||||
do {
|
do {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <cpu.h>
|
||||||
#include <irq.h>
|
#include <irq.h>
|
||||||
#include <asm/lib/spinlock.h>
|
#include <asm/lib/spinlock.h>
|
||||||
#include <asm/ioapic.h>
|
#include <asm/ioapic.h>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include <asm/apicreg.h>
|
#include <asm/apicreg.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
#include <delay.h>
|
#include <delay.h>
|
||||||
|
#include <cpu.h>
|
||||||
|
|
||||||
/* intr_lapic_icr_delivery_mode */
|
/* intr_lapic_icr_delivery_mode */
|
||||||
#define INTR_LAPIC_ICR_FIXED 0x0U
|
#define INTR_LAPIC_ICR_FIXED 0x0U
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include <delay.h>
|
#include <delay.h>
|
||||||
#include <asm/board.h>
|
#include <asm/board.h>
|
||||||
#include <asm/cpuid.h>
|
#include <asm/cpuid.h>
|
||||||
|
#include <cpu.h>
|
||||||
|
|
||||||
struct cpu_context cpu_ctx;
|
struct cpu_context cpu_ctx;
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include <asm/mmu.h>
|
#include <asm/mmu.h>
|
||||||
#include <asm/cpu_caps.h>
|
#include <asm/cpu_caps.h>
|
||||||
#include <asm/rtcm.h>
|
#include <asm/rtcm.h>
|
||||||
|
#include <cpu.h>
|
||||||
|
|
||||||
|
|
||||||
static uint64_t ssram_bottom_hpa;
|
static uint64_t ssram_bottom_hpa;
|
||||||
|
|||||||
49
hypervisor/common/cpu.c
Normal file
49
hypervisor/common/cpu.c
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2025 Intel Corporation.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
#include <cpu.h>
|
||||||
|
#include <asm/lib/bits.h>
|
||||||
|
|
||||||
|
|
||||||
|
static volatile uint64_t pcpu_active_bitmap = 0UL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @post return <= MAX_PCPU_NUM
|
||||||
|
*/
|
||||||
|
uint16_t get_pcpu_nums(void)
|
||||||
|
{
|
||||||
|
return arch_get_pcpu_num();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_pcpu_active(uint16_t pcpu_id)
|
||||||
|
{
|
||||||
|
return bitmap_test(pcpu_id, &pcpu_active_bitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_pcpu_active(uint16_t pcpu_id)
|
||||||
|
{
|
||||||
|
bitmap_set_lock(pcpu_id, &pcpu_active_bitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_pcpu_active(uint16_t pcpu_id)
|
||||||
|
{
|
||||||
|
|
||||||
|
bitmap_clear_lock(pcpu_id, &pcpu_active_bitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool check_pcpus_active(uint64_t mask)
|
||||||
|
{
|
||||||
|
return ((pcpu_active_bitmap & mask) == mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool check_pcpus_inactive(uint64_t mask)
|
||||||
|
{
|
||||||
|
return ((pcpu_active_bitmap & mask) != 0UL);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t get_active_pcpu_bitmap(void)
|
||||||
|
{
|
||||||
|
return pcpu_active_bitmap;
|
||||||
|
}
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
#include <common/notify.h>
|
#include <common/notify.h>
|
||||||
#include <debug/logmsg.h>
|
#include <debug/logmsg.h>
|
||||||
#include <asm/cpu.h>
|
#include <asm/cpu.h>
|
||||||
|
#include <cpu.h>
|
||||||
|
|
||||||
static volatile uint64_t smp_call_mask = 0UL;
|
static volatile uint64_t smp_call_mask = 0UL;
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include <npk_log.h>
|
#include <npk_log.h>
|
||||||
#include <asm/guest/vm.h>
|
#include <asm/guest/vm.h>
|
||||||
#include <logmsg.h>
|
#include <logmsg.h>
|
||||||
|
#include <cpu.h>
|
||||||
|
|
||||||
#ifdef PROFILING_ON
|
#ifdef PROFILING_ON
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include <asm/mmu.h>
|
#include <asm/mmu.h>
|
||||||
#include <logmsg.h>
|
#include <logmsg.h>
|
||||||
#include <npk_log.h>
|
#include <npk_log.h>
|
||||||
|
#include <cpu.h>
|
||||||
|
|
||||||
static int32_t npk_log_setup_ref;
|
static int32_t npk_log_setup_ref;
|
||||||
static bool npk_log_enabled;
|
static bool npk_log_enabled;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include <sprintf.h>
|
#include <sprintf.h>
|
||||||
#include <logmsg.h>
|
#include <logmsg.h>
|
||||||
#include <ticks.h>
|
#include <ticks.h>
|
||||||
|
#include <cpu.h>
|
||||||
|
|
||||||
#define DBG_LEVEL_PROFILING 5U
|
#define DBG_LEVEL_PROFILING 5U
|
||||||
#define DBG_LEVEL_ERR_PROFILING 3U
|
#define DBG_LEVEL_ERR_PROFILING 3U
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <asm/cpu.h>
|
#include <asm/cpu.h>
|
||||||
#include <per_cpu.h>
|
#include <per_cpu.h>
|
||||||
|
#include <cpu.h>
|
||||||
|
|
||||||
int32_t sbuf_share_setup(uint16_t pcpu_id, uint32_t sbuf_id, uint64_t *hva)
|
int32_t sbuf_share_setup(uint16_t pcpu_id, uint32_t sbuf_id, uint64_t *hva)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include <shell.h>
|
#include <shell.h>
|
||||||
#include <asm/guest/vmcs.h>
|
#include <asm/guest/vmcs.h>
|
||||||
#include <asm/host_pm.h>
|
#include <asm/host_pm.h>
|
||||||
|
#include <cpu.h>
|
||||||
|
|
||||||
#define TEMP_STR_SIZE 60U
|
#define TEMP_STR_SIZE 60U
|
||||||
#define MAX_STR_SIZE 256U
|
#define MAX_STR_SIZE 256U
|
||||||
|
|||||||
@@ -11,15 +11,6 @@
|
|||||||
#include <types.h>
|
#include <types.h>
|
||||||
#include <lib/util.h>
|
#include <lib/util.h>
|
||||||
|
|
||||||
/* CPU states defined */
|
|
||||||
enum pcpu_boot_state {
|
|
||||||
PCPU_STATE_RESET = 0U,
|
|
||||||
PCPU_STATE_INITIALIZING,
|
|
||||||
PCPU_STATE_RUNNING,
|
|
||||||
PCPU_STATE_HALTED,
|
|
||||||
PCPU_STATE_DEAD,
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline void wait_sync_change(__unused volatile const uint64_t *sync, __unused uint64_t wake_sync)
|
static inline void wait_sync_change(__unused volatile const uint64_t *sync, __unused uint64_t wake_sync)
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@@ -28,15 +19,6 @@ static inline void wait_sync_change(__unused volatile const uint64_t *sync, __un
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool is_pcpu_active(__unused uint16_t pcpu_id)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Dummy implementation.
|
|
||||||
* Official implementations are to be provided in the platform initialization patchset (by Hang).
|
|
||||||
*/
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint16_t get_pcpu_id(void)
|
static inline uint16_t get_pcpu_id(void)
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -201,9 +201,6 @@
|
|||||||
|
|
||||||
#ifndef ASSEMBLER
|
#ifndef ASSEMBLER
|
||||||
|
|
||||||
#define ALL_CPUS_MASK ((1UL << get_pcpu_nums()) - 1UL)
|
|
||||||
#define AP_MASK (ALL_CPUS_MASK & ~(1UL << BSP_CPU_ID))
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Identifiers for architecturally defined registers.
|
* Identifiers for architecturally defined registers.
|
||||||
@@ -311,15 +308,6 @@ struct descriptor_table {
|
|||||||
uint64_t base;
|
uint64_t base;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
/* CPU states defined */
|
|
||||||
enum pcpu_boot_state {
|
|
||||||
PCPU_STATE_RESET = 0U,
|
|
||||||
PCPU_STATE_INITIALIZING,
|
|
||||||
PCPU_STATE_RUNNING,
|
|
||||||
PCPU_STATE_HALTED,
|
|
||||||
PCPU_STATE_DEAD,
|
|
||||||
};
|
|
||||||
|
|
||||||
#define NEED_OFFLINE (1U)
|
#define NEED_OFFLINE (1U)
|
||||||
#define NEED_SHUTDOWN_VM (2U)
|
#define NEED_SHUTDOWN_VM (2U)
|
||||||
void make_pcpu_offline(uint16_t pcpu_id);
|
void make_pcpu_offline(uint16_t pcpu_id);
|
||||||
@@ -808,12 +796,6 @@ static inline void clac(void)
|
|||||||
asm volatile ("clac" : : : "memory");
|
asm volatile ("clac" : : : "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @post return <= MAX_PCPU_NUM
|
|
||||||
*/
|
|
||||||
uint16_t get_pcpu_nums(void);
|
|
||||||
bool is_pcpu_active(uint16_t pcpu_id);
|
|
||||||
uint64_t get_active_pcpu_bitmap(void);
|
|
||||||
#else /* ASSEMBLER defined */
|
#else /* ASSEMBLER defined */
|
||||||
|
|
||||||
#endif /* ASSEMBLER defined */
|
#endif /* ASSEMBLER defined */
|
||||||
|
|||||||
33
hypervisor/include/common/cpu.h
Normal file
33
hypervisor/include/common/cpu.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2025 Intel Corporation.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef COMMON_CPU_H
|
||||||
|
#define COMMON_CPU_H
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
#include <asm/cpu.h>
|
||||||
|
|
||||||
|
/* CPU states defined */
|
||||||
|
enum pcpu_boot_state {
|
||||||
|
PCPU_STATE_RESET = 0U,
|
||||||
|
PCPU_STATE_INITIALIZING,
|
||||||
|
PCPU_STATE_RUNNING,
|
||||||
|
PCPU_STATE_HALTED,
|
||||||
|
PCPU_STATE_DEAD,
|
||||||
|
};
|
||||||
|
uint16_t arch_get_pcpu_num(void);
|
||||||
|
uint16_t get_pcpu_nums(void);
|
||||||
|
bool is_pcpu_active(uint16_t pcpu_id);
|
||||||
|
void set_pcpu_active(uint16_t pcpu_id);
|
||||||
|
void clear_pcpu_active(uint16_t pcpu_id);
|
||||||
|
bool check_pcpus_active(uint64_t mask);
|
||||||
|
bool check_pcpus_inactive(uint64_t mask);
|
||||||
|
uint64_t get_active_pcpu_bitmap(void);
|
||||||
|
|
||||||
|
#define ALL_CPUS_MASK ((1UL << get_pcpu_nums()) - 1UL)
|
||||||
|
#define AP_MASK (ALL_CPUS_MASK & ~(1UL << BSP_CPU_ID))
|
||||||
|
|
||||||
|
#endif /* COMMON_CPU_H */
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
#include <asm/per_cpu.h>
|
#include <asm/per_cpu.h>
|
||||||
#include <asm/security.h>
|
#include <asm/security.h>
|
||||||
#include <notify.h>
|
#include <notify.h>
|
||||||
#include <asm/cpu.h>
|
#include <cpu.h>
|
||||||
#include <board_info.h>
|
#include <board_info.h>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user