[PATCH V10 15/19] RISC-V: paravirt: pvqspinlock: Add SBI implementation

guoren
2023-08-02T16:51:50Z

Implement pv_kick with SBI implementation, and add SBI_EXT_PVLOCK
extension detection.

Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/include/asm/sbi.h | 6 ++++++
arch/riscv/kernel/paravirt.c | 7 ++++++-
2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index b7ced34b79a3..26b4ec039f32 100644
--- a/arch/riscv/include/asm/sbi.h
+++ b/arch/riscv/include/asm/sbi.h
@@ -31,6 +31,7 @@ enum sbi_ext_id {
SBI_EXT_SRST = 0x53525354,
SBI_EXT_PMU = 0x504D55,
SBI_EXT_STA = 0x535441,
+ SBI_EXT_PVLOCK = 0xAB0401,

/* Experimentals extensions must lie within this range */
SBI_EXT_EXPERIMENTAL_START = 0x08000000,
@@ -244,6 +245,11 @@ enum sbi_pmu_ctr_type {
/* Flags defined for counter stop function */
#define SBI_PMU_STOP_FLAG_RESET (1 << 0)

+/* SBI PVLOCK (kick cpu out of wfi) */
+enum sbi_ext_pvlock_fid {
+ SBI_EXT_PVLOCK_KICK_CPU = 0,
+};
+
/* SBI STA (steal-time accounting) extension */
enum sbi_ext_sta_fid {
SBI_EXT_STA_STEAL_TIME_SET_SHMEM = 0,
diff --git a/arch/riscv/kernel/paravirt.c b/arch/riscv/kernel/paravirt.c
index b55c3d3c0c17..564d64f11e4f 100644
--- a/arch/riscv/kernel/paravirt.c
+++ b/arch/riscv/kernel/paravirt.c
@@ -136,6 +136,8 @@ int __init pv_time_init(void)

void pv_kick(int cpu)
{
+ sbi_ecall(SBI_EXT_PVLOCK, SBI_EXT_PVLOCK_KICK_CPU,
+ cpuid_to_hartid_map(cpu), 0, 0, 0, 0, 0);
return;
}

@@ -150,7 +152,7 @@ void pv_wait(u8 *ptr, u8 val)
if (READ_ONCE(*ptr) != val)
goto out;

- /* wait_for_interrupt(); */
+ wait_for_interrupt();
out:
local_irq_restore(flags);
}
@@ -186,6 +188,9 @@ void __init pv_qspinlock_init(void)
if(sbi_get_firmware_id() != SBI_EXT_BASE_IMPL_ID_KVM)
return;

+ if (!sbi_probe_extension(SBI_EXT_PVLOCK))
+ return;
+
pr_info("PV qspinlocks enabled\n");
__pv_init_lock_hash();