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:
hangliu1
2025-09-09 14:39:50 -04:00
committed by acrnsi-robot
parent 0cd5567140
commit a72bd5e076
17 changed files with 111 additions and 65 deletions

View File

@@ -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

View File

@@ -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 {

View File

@@ -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>

View File

@@ -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

View File

@@ -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;

View File

@@ -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
View 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;
}

View File

@@ -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;

View File

@@ -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
/** /**

View File

@@ -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;

View File

@@ -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

View File

@@ -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)
{ {

View File

@@ -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

View File

@@ -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)
{ {
/** /**

View File

@@ -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 */

View 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 */

View File

@@ -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>