RISC-V: paravirt: Add skeleton for pv-time support
authorAndrew Jones <ajones@ventanamicro.com>
Wed, 20 Dec 2023 16:00:14 +0000 (17:00 +0100)
committerAnup Patel <anup@brainfault.org>
Sat, 30 Dec 2023 05:55:03 +0000 (11:25 +0530)
Add the files and functions needed to support paravirt time on
RISC-V. Also include the common code needed for the first
application of pv-time, which is steal-time. In the next
patches we'll complete the functions to fully enable steal-time
support.

Acked-by: Palmer Dabbelt <palmer@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Signed-off-by: Anup Patel <anup@brainfault.org>
Documentation/admin-guide/kernel-parameters.txt
arch/riscv/include/asm/paravirt.h [new file with mode: 0644]
arch/riscv/include/asm/paravirt_api_clock.h [new file with mode: 0644]
arch/riscv/kernel/Makefile
arch/riscv/kernel/paravirt.c [new file with mode: 0644]
arch/riscv/kernel/time.c

index 65731b060e3fef98cb97f03695ca8757ee197700..a0d9259e4857211768e3d07959aa1df03326fb55 100644 (file)
                        vulnerability. System may allow data leaks with this
                        option.
 
-       no-steal-acc    [X86,PV_OPS,ARM64,PPC/PSERIES] Disable paravirtualized
-                       steal time accounting. steal time is computed, but
-                       won't influence scheduler behaviour
+       no-steal-acc    [X86,PV_OPS,ARM64,PPC/PSERIES,RISCV] Disable
+                       paravirtualized steal time accounting. steal time is
+                       computed, but won't influence scheduler behaviour
 
        nosync          [HW,M68K] Disables sync negotiation for all devices.
 
diff --git a/arch/riscv/include/asm/paravirt.h b/arch/riscv/include/asm/paravirt.h
new file mode 100644 (file)
index 0000000..c0abde7
--- /dev/null
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_RISCV_PARAVIRT_H
+#define _ASM_RISCV_PARAVIRT_H
+
+#ifdef CONFIG_PARAVIRT
+#include <linux/static_call_types.h>
+
+struct static_key;
+extern struct static_key paravirt_steal_enabled;
+extern struct static_key paravirt_steal_rq_enabled;
+
+u64 dummy_steal_clock(int cpu);
+
+DECLARE_STATIC_CALL(pv_steal_clock, dummy_steal_clock);
+
+static inline u64 paravirt_steal_clock(int cpu)
+{
+       return static_call(pv_steal_clock)(cpu);
+}
+
+int __init pv_time_init(void);
+
+#else
+
+#define pv_time_init() do {} while (0)
+
+#endif /* CONFIG_PARAVIRT */
+#endif /* _ASM_RISCV_PARAVIRT_H */
diff --git a/arch/riscv/include/asm/paravirt_api_clock.h b/arch/riscv/include/asm/paravirt_api_clock.h
new file mode 100644 (file)
index 0000000..65ac7ce
--- /dev/null
@@ -0,0 +1 @@
+#include <asm/paravirt.h>
index fee22a3d1b53462a33bad285d345465a0100e6a9..807c2bde1f83c7ee9cacaa4f6fbf990fa8b2381e 100644 (file)
@@ -85,6 +85,7 @@ obj-$(CONFIG_SMP)             += sbi-ipi.o
 obj-$(CONFIG_SMP) += cpu_ops_sbi.o
 endif
 obj-$(CONFIG_HOTPLUG_CPU)      += cpu-hotplug.o
+obj-$(CONFIG_PARAVIRT)         += paravirt.o
 obj-$(CONFIG_KGDB)             += kgdb.o
 obj-$(CONFIG_KEXEC_CORE)       += kexec_relocate.o crash_save_regs.o machine_kexec.o
 obj-$(CONFIG_KEXEC_FILE)       += elf_kexec.o machine_kexec_file.o
diff --git a/arch/riscv/kernel/paravirt.c b/arch/riscv/kernel/paravirt.c
new file mode 100644 (file)
index 0000000..48d802d
--- /dev/null
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023 Ventana Micro Systems Inc.
+ */
+
+#define pr_fmt(fmt) "riscv-pv: " fmt
+
+#include <linux/cpuhotplug.h>
+#include <linux/init.h>
+#include <linux/jump_label.h>
+#include <linux/printk.h>
+#include <linux/static_call.h>
+#include <linux/types.h>
+
+#include <asm/paravirt.h>
+
+struct static_key paravirt_steal_enabled;
+struct static_key paravirt_steal_rq_enabled;
+
+static u64 native_steal_clock(int cpu)
+{
+       return 0;
+}
+
+DEFINE_STATIC_CALL(pv_steal_clock, native_steal_clock);
+
+static bool steal_acc = true;
+static int __init parse_no_stealacc(char *arg)
+{
+       steal_acc = false;
+       return 0;
+}
+
+early_param("no-steal-acc", parse_no_stealacc);
+
+static bool __init has_pv_steal_clock(void)
+{
+       return false;
+}
+
+static int pv_time_cpu_online(unsigned int cpu)
+{
+       return 0;
+}
+
+static int pv_time_cpu_down_prepare(unsigned int cpu)
+{
+       return 0;
+}
+
+static u64 pv_time_steal_clock(int cpu)
+{
+       return 0;
+}
+
+int __init pv_time_init(void)
+{
+       int ret;
+
+       if (!has_pv_steal_clock())
+               return 0;
+
+       ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
+                               "riscv/pv_time:online",
+                               pv_time_cpu_online,
+                               pv_time_cpu_down_prepare);
+       if (ret < 0)
+               return ret;
+
+       static_call_update(pv_steal_clock, pv_time_steal_clock);
+
+       static_key_slow_inc(&paravirt_steal_enabled);
+       if (steal_acc)
+               static_key_slow_inc(&paravirt_steal_rq_enabled);
+
+       pr_info("Computing paravirt steal-time\n");
+
+       return 0;
+}
index 23641e82a9df2a244727d9e5b674f8c546299ea2..ba3477197789769f846941f2d2a07fe887885d1b 100644 (file)
@@ -12,6 +12,7 @@
 #include <asm/sbi.h>
 #include <asm/processor.h>
 #include <asm/timex.h>
+#include <asm/paravirt.h>
 
 unsigned long riscv_timebase __ro_after_init;
 EXPORT_SYMBOL_GPL(riscv_timebase);
@@ -45,4 +46,6 @@ void __init time_init(void)
        timer_probe();
 
        tick_setup_hrtimer_broadcast();
+
+       pv_time_init();
 }