* [PATCH v1 00/14] RISC-V: Add steal-time support
@ 2023-12-05 18:11 Andrew Jones
2023-12-05 18:11 ` [PATCH v1 01/14] RISC-V: paravirt: Add skeleton for pv-time support Andrew Jones
` (13 more replies)
0 siblings, 14 replies; 19+ messages in thread
From: Andrew Jones @ 2023-12-05 18:11 UTC (permalink / raw)
To: kvm-riscv, linux-riscv, virtualization
Cc: anup, atishp, pbonzini, paul.walmsley, palmer, aou, jgross,
srivatsa, guoren
One frequently touted benefit of virtualization is the ability to
consolidate machines, increasing resource utilization. It may even be
desirable to overcommit, at the risk of one or more VCPUs having to wait.
Hypervisors which have interfaces for guests to retrieve the amount of
time each VCPU had to wait give observers within the guests ways to
account for less progress than would otherwise be expected. The SBI STA
extension[1] provides a standard interface for guest VCPUs to retrieve
the amount of time "stolen".
This series has three parts:
1) Patches 01-04 - Add paravirt support to RISC-V and implement
steal-time accounting support using the SBI STA
extension.
2) Patches 05-10 - Implement SBI STA in KVM so KVM guests, such as
Linux guests which enable the paravirt steal-time
support, can be enlightened about stolen time.
3) Patches 11-14 - Add RISC-V support to the KVM selftests steal_time
test and the SBI extension regs in the get-reg-list
test.
These patches are based on the make SBI uapi consistent with the ISA
uapi KVM series, which is based on Anup's riscv_kvm_more_exts_v1 branch.
Based-on: 20231130183537.55203-8-ajones@ventanamicro.com
[1] https://github.com/riscv-non-isa/riscv-sbi-doc/blob/master/src/ext-steal-time.adoc
This patches are also available here
https://github.com/jones-drew/linux/commits/kvm/steal-time-v1
Changes since RFC:
- Rebased on v6.7-rc3 (plus the patches mentioned above)
- Added defines for the -1's [Conor]
- Added a comment to the steal read sequence [Conor]
- Only do the steal read sequence for 32-bit and added READ_ONCE's
- Check for SBI v2.0 implementation
- Rename set_steal_time_shmem to steal_time_set_shmem
- Add get-reg-list support and test with get-reg-list kselftest
- A few other minor improvements
- Picked up one r-b from Conor
Thanks,
drew
Andrew Jones (14):
RISC-V: paravirt: Add skeleton for pv-time support
RISC-V: Add SBI STA extension definitions
RISC-V: paravirt: Implement steal-time support
RISC-V: paravirt: Add kconfigs
RISC-V: KVM: Add SBI STA extension skeleton
RISC-V: KVM: Add steal-update vcpu request
RISC-V: KVM: Add SBI STA info to vcpu_arch
RISC-V: KVM: Add support for SBI extension registers
RISC-V: KVM: Add support for SBI STA registers
RISC-V: KVM: Implement SBI STA extension
RISC-V: KVM: selftests: Move sbi_ecall to processor.c
RISC-V: KVM: selftests: Add guest_sbi_probe_extension
RISC-V: KVM: selftests: Add steal_time test support
RISC-V: KVM: selftests: Add get-reg-list test for STA registers
.../admin-guide/kernel-parameters.txt | 6 +-
arch/riscv/Kconfig | 19 ++
arch/riscv/include/asm/kvm_host.h | 9 +
arch/riscv/include/asm/kvm_vcpu_sbi.h | 6 +
arch/riscv/include/asm/paravirt.h | 28 +++
arch/riscv/include/asm/paravirt_api_clock.h | 1 +
arch/riscv/include/asm/sbi.h | 17 ++
arch/riscv/include/uapi/asm/kvm.h | 13 ++
arch/riscv/kernel/Makefile | 1 +
arch/riscv/kernel/paravirt.c | 138 ++++++++++++
arch/riscv/kernel/time.c | 3 +
arch/riscv/kvm/Kconfig | 1 +
arch/riscv/kvm/Makefile | 1 +
arch/riscv/kvm/vcpu.c | 7 +
arch/riscv/kvm/vcpu_onereg.c | 105 +++++++++
arch/riscv/kvm/vcpu_sbi.c | 4 +
arch/riscv/kvm/vcpu_sbi_sta.c | 202 ++++++++++++++++++
tools/testing/selftests/kvm/Makefile | 5 +-
.../selftests/kvm/include/riscv/processor.h | 22 ++
.../selftests/kvm/lib/riscv/processor.c | 45 ++++
tools/testing/selftests/kvm/lib/riscv/ucall.c | 26 ---
.../selftests/kvm/riscv/get-reg-list.c | 43 ++++
tools/testing/selftests/kvm/steal_time.c | 99 +++++++++
23 files changed, 770 insertions(+), 31 deletions(-)
create mode 100644 arch/riscv/include/asm/paravirt.h
create mode 100644 arch/riscv/include/asm/paravirt_api_clock.h
create mode 100644 arch/riscv/kernel/paravirt.c
create mode 100644 arch/riscv/kvm/vcpu_sbi_sta.c
--
2.43.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v1 01/14] RISC-V: paravirt: Add skeleton for pv-time support
2023-12-05 18:11 [PATCH v1 00/14] RISC-V: Add steal-time support Andrew Jones
@ 2023-12-05 18:11 ` Andrew Jones
2023-12-05 18:11 ` [PATCH v1 02/14] RISC-V: Add SBI STA extension definitions Andrew Jones
` (12 subsequent siblings)
13 siblings, 0 replies; 19+ messages in thread
From: Andrew Jones @ 2023-12-05 18:11 UTC (permalink / raw)
To: kvm-riscv, linux-riscv, virtualization
Cc: anup, atishp, pbonzini, paul.walmsley, palmer, aou, jgross,
srivatsa, guoren
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.
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
---
.../admin-guide/kernel-parameters.txt | 6 +-
arch/riscv/include/asm/paravirt.h | 28 +++++++
arch/riscv/include/asm/paravirt_api_clock.h | 1 +
arch/riscv/kernel/Makefile | 1 +
arch/riscv/kernel/paravirt.c | 77 +++++++++++++++++++
arch/riscv/kernel/time.c | 3 +
6 files changed, 113 insertions(+), 3 deletions(-)
create mode 100644 arch/riscv/include/asm/paravirt.h
create mode 100644 arch/riscv/include/asm/paravirt_api_clock.h
create mode 100644 arch/riscv/kernel/paravirt.c
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 65731b060e3f..a0d9259e4857 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -3985,9 +3985,9 @@
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
index 000000000000..c0abde70fc2c
--- /dev/null
+++ b/arch/riscv/include/asm/paravirt.h
@@ -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
index 000000000000..65ac7cee0dad
--- /dev/null
+++ b/arch/riscv/include/asm/paravirt_api_clock.h
@@ -0,0 +1 @@
+#include <asm/paravirt.h>
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index fee22a3d1b53..807c2bde1f83 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -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
index 000000000000..141dbcc36fa2
--- /dev/null
+++ b/arch/riscv/kernel/paravirt.c
@@ -0,0 +1,77 @@
+// 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>
+
+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(¶virt_steal_enabled);
+ if (steal_acc)
+ static_key_slow_inc(¶virt_steal_rq_enabled);
+
+ pr_info("using paravirt steal-time\n");
+
+ return 0;
+}
diff --git a/arch/riscv/kernel/time.c b/arch/riscv/kernel/time.c
index 23641e82a9df..ba3477197789 100644
--- a/arch/riscv/kernel/time.c
+++ b/arch/riscv/kernel/time.c
@@ -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();
}
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v1 02/14] RISC-V: Add SBI STA extension definitions
2023-12-05 18:11 [PATCH v1 00/14] RISC-V: Add steal-time support Andrew Jones
2023-12-05 18:11 ` [PATCH v1 01/14] RISC-V: paravirt: Add skeleton for pv-time support Andrew Jones
@ 2023-12-05 18:11 ` Andrew Jones
2023-12-05 18:11 ` [PATCH v1 03/14] RISC-V: paravirt: Implement steal-time support Andrew Jones
` (11 subsequent siblings)
13 siblings, 0 replies; 19+ messages in thread
From: Andrew Jones @ 2023-12-05 18:11 UTC (permalink / raw)
To: kvm-riscv, linux-riscv, virtualization
Cc: anup, atishp, pbonzini, paul.walmsley, palmer, aou, jgross,
srivatsa, guoren, Conor Dooley
The SBI STA extension enables steal-time accounting. Add the
definitions it specifies.
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
---
arch/riscv/include/asm/sbi.h | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index 9eef25308d53..d88d4e8f517e 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_DBCN = 0x4442434E,
+ SBI_EXT_STA = 0x535441,
/* Experimentals extensions must lie within this range */
SBI_EXT_EXPERIMENTAL_START = 0x08000000,
@@ -243,6 +244,22 @@ enum sbi_ext_dbcn_fid {
SBI_EXT_DBCN_CONSOLE_WRITE_BYTE = 2,
};
+/* SBI STA (steal-time accounting) extension */
+enum sbi_ext_sta_fid {
+ SBI_EXT_STA_STEAL_TIME_SET_SHMEM = 0,
+};
+
+struct sbi_sta_struct {
+ __le32 sequence;
+ __le32 flags;
+ __le64 steal;
+ u8 preempted;
+ u8 pad[47];
+} __packed;
+
+#define SBI_STA_SHMEM_DISABLE -1
+
+/* SBI spec version fields */
#define SBI_SPEC_VERSION_DEFAULT 0x1
#define SBI_SPEC_VERSION_MAJOR_SHIFT 24
#define SBI_SPEC_VERSION_MAJOR_MASK 0x7f
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v1 03/14] RISC-V: paravirt: Implement steal-time support
2023-12-05 18:11 [PATCH v1 00/14] RISC-V: Add steal-time support Andrew Jones
2023-12-05 18:11 ` [PATCH v1 01/14] RISC-V: paravirt: Add skeleton for pv-time support Andrew Jones
2023-12-05 18:11 ` [PATCH v1 02/14] RISC-V: Add SBI STA extension definitions Andrew Jones
@ 2023-12-05 18:11 ` Andrew Jones
2023-12-07 14:06 ` Conor Dooley
2023-12-05 18:11 ` [PATCH v1 04/14] RISC-V: paravirt: Add kconfigs Andrew Jones
` (10 subsequent siblings)
13 siblings, 1 reply; 19+ messages in thread
From: Andrew Jones @ 2023-12-05 18:11 UTC (permalink / raw)
To: kvm-riscv, linux-riscv, virtualization
Cc: anup, atishp, pbonzini, paul.walmsley, palmer, aou, jgross,
srivatsa, guoren
When the SBI STA extension exists we can use it to implement
paravirt steal-time support. Fill in the empty pv-time functions
with an SBI STA implementation.
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
---
arch/riscv/kernel/paravirt.c | 67 ++++++++++++++++++++++++++++++++++--
1 file changed, 64 insertions(+), 3 deletions(-)
diff --git a/arch/riscv/kernel/paravirt.c b/arch/riscv/kernel/paravirt.c
index 141dbcc36fa2..b509bcc7292a 100644
--- a/arch/riscv/kernel/paravirt.c
+++ b/arch/riscv/kernel/paravirt.c
@@ -6,12 +6,21 @@
#define pr_fmt(fmt) "riscv-pv: " fmt
#include <linux/cpuhotplug.h>
+#include <linux/compiler.h>
+#include <linux/errno.h>
#include <linux/init.h>
#include <linux/jump_label.h>
+#include <linux/kconfig.h>
+#include <linux/kernel.h>
+#include <linux/percpu-defs.h>
#include <linux/printk.h>
#include <linux/static_call.h>
#include <linux/types.h>
+#include <asm/barrier.h>
+#include <asm/page.h>
+#include <asm/sbi.h>
+
struct static_key paravirt_steal_enabled;
struct static_key paravirt_steal_rq_enabled;
@@ -31,24 +40,76 @@ static int __init parse_no_stealacc(char *arg)
early_param("no-steal-acc", parse_no_stealacc);
+DEFINE_PER_CPU(struct sbi_sta_struct, steal_time) __aligned(64);
+
static bool __init has_pv_steal_clock(void)
{
+ if (sbi_spec_version >= sbi_mk_version(2, 0) &&
+ sbi_probe_extension(SBI_EXT_STA) > 0) {
+ pr_info("SBI STA extension detected\n");
+ return true;
+ }
+
return false;
}
-static int pv_time_cpu_online(unsigned int cpu)
+static int sbi_sta_steal_time_set_shmem(unsigned long lo, unsigned long hi,
+ unsigned long flags)
{
+ struct sbiret ret;
+
+ ret = sbi_ecall(SBI_EXT_STA, SBI_EXT_STA_STEAL_TIME_SET_SHMEM,
+ lo, hi, flags, 0, 0, 0);
+ if (ret.error) {
+ if (lo == SBI_STA_SHMEM_DISABLE && hi == SBI_STA_SHMEM_DISABLE)
+ pr_warn("Failed to disable steal-time shmem");
+ else
+ pr_warn("Failed to set steal-time shmem");
+ return -ENOMEM;
+ }
+
return 0;
}
+static int pv_time_cpu_online(unsigned int cpu)
+{
+ struct sbi_sta_struct *st = this_cpu_ptr(&steal_time);
+ phys_addr_t pa = __pa(st);
+ unsigned long lo = (unsigned long)pa;
+ unsigned long hi = IS_ENABLED(CONFIG_32BIT) ? upper_32_bits((u64)pa) : 0;
+
+ return sbi_sta_steal_time_set_shmem(lo, hi, 0);
+}
+
static int pv_time_cpu_down_prepare(unsigned int cpu)
{
- return 0;
+ return sbi_sta_steal_time_set_shmem(SBI_STA_SHMEM_DISABLE,
+ SBI_STA_SHMEM_DISABLE, 0);
}
static u64 pv_time_steal_clock(int cpu)
{
- return 0;
+ struct sbi_sta_struct *st = per_cpu_ptr(&steal_time, cpu);
+ u32 sequence;
+ u64 steal;
+
+ if (IS_ENABLED(CONFIG_32BIT)) {
+ /*
+ * Check the sequence field before and after reading the steal
+ * field. Repeat the read if it is different or odd.
+ */
+ do {
+ sequence = READ_ONCE(st->sequence);
+ virt_rmb();
+ steal = READ_ONCE(st->steal);
+ virt_rmb();
+ } while ((le32_to_cpu(sequence) & 1) ||
+ sequence != READ_ONCE(st->sequence));
+ } else {
+ steal = READ_ONCE(st->steal);
+ }
+
+ return le64_to_cpu(steal);
}
int __init pv_time_init(void)
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v1 04/14] RISC-V: paravirt: Add kconfigs
2023-12-05 18:11 [PATCH v1 00/14] RISC-V: Add steal-time support Andrew Jones
` (2 preceding siblings ...)
2023-12-05 18:11 ` [PATCH v1 03/14] RISC-V: paravirt: Implement steal-time support Andrew Jones
@ 2023-12-05 18:11 ` Andrew Jones
2023-12-07 14:07 ` Conor Dooley
2023-12-05 18:11 ` [PATCH v1 05/14] RISC-V: KVM: Add SBI STA extension skeleton Andrew Jones
` (9 subsequent siblings)
13 siblings, 1 reply; 19+ messages in thread
From: Andrew Jones @ 2023-12-05 18:11 UTC (permalink / raw)
To: kvm-riscv, linux-riscv, virtualization
Cc: anup, atishp, pbonzini, paul.walmsley, palmer, aou, jgross,
srivatsa, guoren, Conor Dooley
Now that we can support steal-time accounting, add the kconfig
knobs allowing it to be enabled.
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
---
arch/riscv/Kconfig | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 29f0f8fcb5c2..caf6f5ea578b 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -726,6 +726,25 @@ config COMPAT
If you want to execute 32-bit userspace applications, say Y.
+config PARAVIRT
+ bool "Enable paravirtualization code"
+ depends on RISCV_SBI
+ help
+ This changes the kernel so it can modify itself when it is run
+ under a hypervisor, potentially improving performance significantly
+ over full virtualization.
+
+config PARAVIRT_TIME_ACCOUNTING
+ bool "Paravirtual steal time accounting"
+ depends on PARAVIRT
+ help
+ Select this option to enable fine granularity task steal time
+ accounting. Time spent executing other tasks in parallel with
+ the current vCPU is discounted from the vCPU power. To account for
+ that, there can be a small performance impact.
+
+ If in doubt, say N here.
+
config RELOCATABLE
bool "Build a relocatable kernel"
depends on MMU && 64BIT && !XIP_KERNEL
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v1 05/14] RISC-V: KVM: Add SBI STA extension skeleton
2023-12-05 18:11 [PATCH v1 00/14] RISC-V: Add steal-time support Andrew Jones
` (3 preceding siblings ...)
2023-12-05 18:11 ` [PATCH v1 04/14] RISC-V: paravirt: Add kconfigs Andrew Jones
@ 2023-12-05 18:11 ` Andrew Jones
2023-12-05 18:11 ` [PATCH v1 06/14] RISC-V: KVM: Add steal-update vcpu request Andrew Jones
` (8 subsequent siblings)
13 siblings, 0 replies; 19+ messages in thread
From: Andrew Jones @ 2023-12-05 18:11 UTC (permalink / raw)
To: kvm-riscv, linux-riscv, virtualization
Cc: anup, atishp, pbonzini, paul.walmsley, palmer, aou, jgross,
srivatsa, guoren
Add the files and functions needed to support the SBI STA
(steal-time accounting) extension. In the next patches we'll
complete the functions to fully enable SBI STA support.
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
---
arch/riscv/include/asm/kvm_vcpu_sbi.h | 1 +
arch/riscv/include/uapi/asm/kvm.h | 1 +
arch/riscv/kvm/Makefile | 1 +
arch/riscv/kvm/vcpu_sbi.c | 4 +++
arch/riscv/kvm/vcpu_sbi_sta.c | 47 +++++++++++++++++++++++++++
5 files changed, 54 insertions(+)
create mode 100644 arch/riscv/kvm/vcpu_sbi_sta.c
diff --git a/arch/riscv/include/asm/kvm_vcpu_sbi.h b/arch/riscv/include/asm/kvm_vcpu_sbi.h
index bffda0ac59b6..99c23bb37a37 100644
--- a/arch/riscv/include/asm/kvm_vcpu_sbi.h
+++ b/arch/riscv/include/asm/kvm_vcpu_sbi.h
@@ -76,6 +76,7 @@ extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_rfence;
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_srst;
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_hsm;
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_dbcn;
+extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_sta;
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_experimental;
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_vendor;
diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h
index 909bd98220ee..85b979f7d2bd 100644
--- a/arch/riscv/include/uapi/asm/kvm.h
+++ b/arch/riscv/include/uapi/asm/kvm.h
@@ -184,6 +184,7 @@ enum KVM_RISCV_SBI_EXT_ID {
KVM_RISCV_SBI_EXT_EXPERIMENTAL,
KVM_RISCV_SBI_EXT_VENDOR,
KVM_RISCV_SBI_EXT_DBCN,
+ KVM_RISCV_SBI_EXT_STA,
KVM_RISCV_SBI_EXT_MAX,
};
diff --git a/arch/riscv/kvm/Makefile b/arch/riscv/kvm/Makefile
index 4c2067fc59fc..c9646521f113 100644
--- a/arch/riscv/kvm/Makefile
+++ b/arch/riscv/kvm/Makefile
@@ -26,6 +26,7 @@ kvm-$(CONFIG_RISCV_SBI_V01) += vcpu_sbi_v01.o
kvm-y += vcpu_sbi_base.o
kvm-y += vcpu_sbi_replace.o
kvm-y += vcpu_sbi_hsm.o
+kvm-y += vcpu_sbi_sta.o
kvm-y += vcpu_timer.o
kvm-$(CONFIG_RISCV_PMU_SBI) += vcpu_pmu.o vcpu_sbi_pmu.o
kvm-y += aia.o
diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c
index dcdff4458190..088daaa23dd8 100644
--- a/arch/riscv/kvm/vcpu_sbi.c
+++ b/arch/riscv/kvm/vcpu_sbi.c
@@ -70,6 +70,10 @@ static const struct kvm_riscv_sbi_extension_entry sbi_ext[] = {
.ext_idx = KVM_RISCV_SBI_EXT_DBCN,
.ext_ptr = &vcpu_sbi_ext_dbcn,
},
+ {
+ .ext_idx = KVM_RISCV_SBI_EXT_STA,
+ .ext_ptr = &vcpu_sbi_ext_sta,
+ },
{
.ext_idx = KVM_RISCV_SBI_EXT_EXPERIMENTAL,
.ext_ptr = &vcpu_sbi_ext_experimental,
diff --git a/arch/riscv/kvm/vcpu_sbi_sta.c b/arch/riscv/kvm/vcpu_sbi_sta.c
new file mode 100644
index 000000000000..839911dcd837
--- /dev/null
+++ b/arch/riscv/kvm/vcpu_sbi_sta.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023 Ventana Micro Systems Inc.
+ */
+
+#include <linux/kvm_host.h>
+
+#include <asm/kvm_vcpu_sbi.h>
+#include <asm/sbi.h>
+
+static int kvm_sbi_sta_steal_time_set_shmem(struct kvm_vcpu *vcpu)
+{
+ return SBI_ERR_FAILURE;
+}
+
+static int kvm_sbi_ext_sta_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
+ struct kvm_vcpu_sbi_return *retdata)
+{
+ struct kvm_cpu_context *cp = &vcpu->arch.guest_context;
+ unsigned long funcid = cp->a6;
+ int ret;
+
+ switch (funcid) {
+ case SBI_EXT_STA_STEAL_TIME_SET_SHMEM:
+ ret = kvm_sbi_sta_steal_time_set_shmem(vcpu);
+ break;
+ default:
+ ret = SBI_ERR_NOT_SUPPORTED;
+ break;
+ }
+
+ retdata->err_val = ret;
+
+ return 0;
+}
+
+static unsigned long kvm_sbi_ext_sta_probe(struct kvm_vcpu *vcpu)
+{
+ return 0;
+}
+
+const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_sta = {
+ .extid_start = SBI_EXT_STA,
+ .extid_end = SBI_EXT_STA,
+ .handler = kvm_sbi_ext_sta_handler,
+ .probe = kvm_sbi_ext_sta_probe,
+};
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v1 06/14] RISC-V: KVM: Add steal-update vcpu request
2023-12-05 18:11 [PATCH v1 00/14] RISC-V: Add steal-time support Andrew Jones
` (4 preceding siblings ...)
2023-12-05 18:11 ` [PATCH v1 05/14] RISC-V: KVM: Add SBI STA extension skeleton Andrew Jones
@ 2023-12-05 18:11 ` Andrew Jones
2023-12-05 18:11 ` [PATCH v1 07/14] RISC-V: KVM: Add SBI STA info to vcpu_arch Andrew Jones
` (7 subsequent siblings)
13 siblings, 0 replies; 19+ messages in thread
From: Andrew Jones @ 2023-12-05 18:11 UTC (permalink / raw)
To: kvm-riscv, linux-riscv, virtualization
Cc: anup, atishp, pbonzini, paul.walmsley, palmer, aou, jgross,
srivatsa, guoren
Add a new vcpu request to inform a vcpu that it should record its
steal-time information. The request is made each time it has been
detected that the vcpu task was not assigned a cpu for some time,
which is easy to do by making the request from vcpu-load. The record
function is just a stub for now and will be filled in with the rest
of the steal-time support functions in following patches.
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
---
arch/riscv/include/asm/kvm_host.h | 3 +++
arch/riscv/kvm/vcpu.c | 5 +++++
arch/riscv/kvm/vcpu_sbi_sta.c | 4 ++++
3 files changed, 12 insertions(+)
diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm_host.h
index 0eefd9c991ae..230b82c3118d 100644
--- a/arch/riscv/include/asm/kvm_host.h
+++ b/arch/riscv/include/asm/kvm_host.h
@@ -41,6 +41,7 @@
KVM_ARCH_REQ_FLAGS(4, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
#define KVM_REQ_HFENCE \
KVM_ARCH_REQ_FLAGS(5, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
+#define KVM_REQ_STEAL_UPDATE KVM_ARCH_REQ(6)
enum kvm_riscv_hfence_type {
KVM_RISCV_HFENCE_UNKNOWN = 0,
@@ -372,4 +373,6 @@ bool kvm_riscv_vcpu_has_interrupts(struct kvm_vcpu *vcpu, u64 mask);
void kvm_riscv_vcpu_power_off(struct kvm_vcpu *vcpu);
void kvm_riscv_vcpu_power_on(struct kvm_vcpu *vcpu);
+void kvm_riscv_vcpu_record_steal_time(struct kvm_vcpu *vcpu);
+
#endif /* __RISCV_KVM_HOST_H__ */
diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c
index e087c809073c..b77f585879b7 100644
--- a/arch/riscv/kvm/vcpu.c
+++ b/arch/riscv/kvm/vcpu.c
@@ -541,6 +541,8 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
kvm_riscv_vcpu_aia_load(vcpu, cpu);
+ kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu);
+
vcpu->cpu = cpu;
}
@@ -614,6 +616,9 @@ static void kvm_riscv_check_vcpu_requests(struct kvm_vcpu *vcpu)
if (kvm_check_request(KVM_REQ_HFENCE, vcpu))
kvm_riscv_hfence_process(vcpu);
+
+ if (kvm_check_request(KVM_REQ_STEAL_UPDATE, vcpu))
+ kvm_riscv_vcpu_record_steal_time(vcpu);
}
}
diff --git a/arch/riscv/kvm/vcpu_sbi_sta.c b/arch/riscv/kvm/vcpu_sbi_sta.c
index 839911dcd837..e28351c9488b 100644
--- a/arch/riscv/kvm/vcpu_sbi_sta.c
+++ b/arch/riscv/kvm/vcpu_sbi_sta.c
@@ -8,6 +8,10 @@
#include <asm/kvm_vcpu_sbi.h>
#include <asm/sbi.h>
+void kvm_riscv_vcpu_record_steal_time(struct kvm_vcpu *vcpu)
+{
+}
+
static int kvm_sbi_sta_steal_time_set_shmem(struct kvm_vcpu *vcpu)
{
return SBI_ERR_FAILURE;
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v1 07/14] RISC-V: KVM: Add SBI STA info to vcpu_arch
2023-12-05 18:11 [PATCH v1 00/14] RISC-V: Add steal-time support Andrew Jones
` (5 preceding siblings ...)
2023-12-05 18:11 ` [PATCH v1 06/14] RISC-V: KVM: Add steal-update vcpu request Andrew Jones
@ 2023-12-05 18:11 ` Andrew Jones
2023-12-05 18:11 ` [PATCH v1 08/14] RISC-V: KVM: Add support for SBI extension registers Andrew Jones
` (6 subsequent siblings)
13 siblings, 0 replies; 19+ messages in thread
From: Andrew Jones @ 2023-12-05 18:11 UTC (permalink / raw)
To: kvm-riscv, linux-riscv, virtualization
Cc: anup, atishp, pbonzini, paul.walmsley, palmer, aou, jgross,
srivatsa, guoren
KVM's implementation of SBI STA needs to track the address of each
VCPU's steal-time shared memory region as well as the amount of
stolen time. Add a structure to vcpu_arch to contain this state
and make sure that the address is always set to INVALID_GPA on
vcpu reset. And, of course, ensure KVM won't try to update steal-
time when the shared memory address is invalid.
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
---
arch/riscv/include/asm/kvm_host.h | 6 ++++++
arch/riscv/kvm/vcpu.c | 2 ++
arch/riscv/kvm/vcpu_sbi_sta.c | 4 ++++
3 files changed, 12 insertions(+)
diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm_host.h
index 230b82c3118d..b10026fb6412 100644
--- a/arch/riscv/include/asm/kvm_host.h
+++ b/arch/riscv/include/asm/kvm_host.h
@@ -263,6 +263,12 @@ struct kvm_vcpu_arch {
/* 'static' configurations which are set only once */
struct kvm_vcpu_config cfg;
+
+ /* SBI steal-time accounting */
+ struct {
+ gpa_t shmem;
+ u64 last_steal;
+ } sta;
};
static inline void kvm_arch_sync_events(struct kvm *kvm) {}
diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c
index b77f585879b7..fb13a05d7ec5 100644
--- a/arch/riscv/kvm/vcpu.c
+++ b/arch/riscv/kvm/vcpu.c
@@ -83,6 +83,8 @@ static void kvm_riscv_reset_vcpu(struct kvm_vcpu *vcpu)
vcpu->arch.hfence_tail = 0;
memset(vcpu->arch.hfence_queue, 0, sizeof(vcpu->arch.hfence_queue));
+ vcpu->arch.sta.shmem = INVALID_GPA;
+
/* Reset the guest CSRs for hotplug usecase */
if (loaded)
kvm_arch_vcpu_load(vcpu, smp_processor_id());
diff --git a/arch/riscv/kvm/vcpu_sbi_sta.c b/arch/riscv/kvm/vcpu_sbi_sta.c
index e28351c9488b..157c199be0b4 100644
--- a/arch/riscv/kvm/vcpu_sbi_sta.c
+++ b/arch/riscv/kvm/vcpu_sbi_sta.c
@@ -10,6 +10,10 @@
void kvm_riscv_vcpu_record_steal_time(struct kvm_vcpu *vcpu)
{
+ gpa_t shmem = vcpu->arch.sta.shmem;
+
+ if (shmem == INVALID_GPA)
+ return;
}
static int kvm_sbi_sta_steal_time_set_shmem(struct kvm_vcpu *vcpu)
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v1 08/14] RISC-V: KVM: Add support for SBI extension registers
2023-12-05 18:11 [PATCH v1 00/14] RISC-V: Add steal-time support Andrew Jones
` (6 preceding siblings ...)
2023-12-05 18:11 ` [PATCH v1 07/14] RISC-V: KVM: Add SBI STA info to vcpu_arch Andrew Jones
@ 2023-12-05 18:11 ` Andrew Jones
2023-12-05 18:11 ` [PATCH v1 09/14] RISC-V: KVM: Add support for SBI STA registers Andrew Jones
` (5 subsequent siblings)
13 siblings, 0 replies; 19+ messages in thread
From: Andrew Jones @ 2023-12-05 18:11 UTC (permalink / raw)
To: kvm-riscv, linux-riscv, virtualization
Cc: anup, atishp, pbonzini, paul.walmsley, palmer, aou, jgross,
srivatsa, guoren
Some SBI extensions have state that needs to be saved / restored
when migrating the VM. Provide a get/set-one-reg register type
for SBI extension registers. Each SBI extension that uses this type
will have its own subtype. There are currently no subtypes defined.
The next patch introduces the first one.
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
---
arch/riscv/include/uapi/asm/kvm.h | 3 +
arch/riscv/kvm/vcpu_onereg.c | 92 +++++++++++++++++++++++++++++++
2 files changed, 95 insertions(+)
diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h
index 85b979f7d2bd..86df125ef17f 100644
--- a/arch/riscv/include/uapi/asm/kvm.h
+++ b/arch/riscv/include/uapi/asm/kvm.h
@@ -269,6 +269,9 @@ enum KVM_RISCV_SBI_EXT_ID {
#define KVM_REG_RISCV_VECTOR_REG(n) \
((n) + sizeof(struct __riscv_v_ext_state) / sizeof(unsigned long))
+/* Registers for specific SBI extensions are mapped as type 10 */
+#define KVM_REG_RISCV_SBI (0x0a << KVM_REG_RISCV_TYPE_SHIFT)
+
/* Device Control API: RISC-V AIA */
#define KVM_DEV_RISCV_APLIC_ALIGN 0x1000
#define KVM_DEV_RISCV_APLIC_SIZE 0x4000
diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c
index 62c7334f74cf..dbd8cedfd556 100644
--- a/arch/riscv/kvm/vcpu_onereg.c
+++ b/arch/riscv/kvm/vcpu_onereg.c
@@ -1015,6 +1015,87 @@ static unsigned long num_sbi_ext_regs(struct kvm_vcpu *vcpu)
return copy_sbi_ext_reg_indices(vcpu, NULL);
}
+static int kvm_riscv_vcpu_get_reg_sbi(struct kvm_vcpu *vcpu,
+ const struct kvm_one_reg *reg)
+{
+ unsigned long __user *uaddr =
+ (unsigned long __user *)(unsigned long)reg->addr;
+ unsigned long reg_num = reg->id & ~(KVM_REG_ARCH_MASK |
+ KVM_REG_SIZE_MASK |
+ KVM_REG_RISCV_SBI);
+ unsigned long reg_subtype, reg_val;
+ int ret;
+
+ if (KVM_REG_SIZE(reg->id) != sizeof(unsigned long))
+ return -EINVAL;
+
+ reg_subtype = reg_num & KVM_REG_RISCV_SUBTYPE_MASK;
+ reg_num &= ~KVM_REG_RISCV_SUBTYPE_MASK;
+
+ switch (reg_subtype) {
+ default:
+ return -EINVAL;
+ }
+
+ if (ret)
+ return ret;
+
+ if (copy_to_user(uaddr, ®_val, KVM_REG_SIZE(reg->id)))
+ return -EFAULT;
+
+ return 0;
+}
+
+static int kvm_riscv_vcpu_set_reg_sbi(struct kvm_vcpu *vcpu,
+ const struct kvm_one_reg *reg)
+{
+ unsigned long __user *uaddr =
+ (unsigned long __user *)(unsigned long)reg->addr;
+ unsigned long reg_num = reg->id & ~(KVM_REG_ARCH_MASK |
+ KVM_REG_SIZE_MASK |
+ KVM_REG_RISCV_SBI);
+ unsigned long reg_subtype, reg_val;
+
+ if (KVM_REG_SIZE(reg->id) != sizeof(unsigned long))
+ return -EINVAL;
+
+ if (copy_from_user(®_val, uaddr, KVM_REG_SIZE(reg->id)))
+ return -EFAULT;
+
+ reg_subtype = reg_num & KVM_REG_RISCV_SUBTYPE_MASK;
+ reg_num &= ~KVM_REG_RISCV_SUBTYPE_MASK;
+
+ switch (reg_subtype) {
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static inline unsigned long num_sbi_regs(struct kvm_vcpu *vcpu)
+{
+ return 0;
+}
+
+static int copy_sbi_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
+{
+ int n = num_sbi_regs(vcpu);
+
+ for (int i = 0; i < n; i++) {
+ u64 reg = KVM_REG_RISCV | KVM_REG_SIZE_U64 |
+ KVM_REG_RISCV_SBI | i;
+
+ if (uindices) {
+ if (put_user(reg, uindices))
+ return -EFAULT;
+ uindices++;
+ }
+ }
+
+ return n;
+}
+
/*
* kvm_riscv_vcpu_num_regs - how many registers do we present via KVM_GET/SET_ONE_REG
*
@@ -1032,6 +1113,7 @@ unsigned long kvm_riscv_vcpu_num_regs(struct kvm_vcpu *vcpu)
res += num_fp_d_regs(vcpu);
res += num_isa_ext_regs(vcpu);
res += num_sbi_ext_regs(vcpu);
+ res += num_sbi_regs(vcpu);
return res;
}
@@ -1082,6 +1164,12 @@ int kvm_riscv_vcpu_copy_reg_indices(struct kvm_vcpu *vcpu,
ret = copy_sbi_ext_reg_indices(vcpu, uindices);
if (ret < 0)
return ret;
+ uindices += ret;
+
+ ret = copy_sbi_reg_indices(vcpu, uindices);
+ if (ret < 0)
+ return ret;
+ uindices += ret;
return 0;
}
@@ -1110,6 +1198,8 @@ int kvm_riscv_vcpu_set_reg(struct kvm_vcpu *vcpu,
return kvm_riscv_vcpu_set_reg_sbi_ext(vcpu, reg);
case KVM_REG_RISCV_VECTOR:
return kvm_riscv_vcpu_set_reg_vector(vcpu, reg);
+ case KVM_REG_RISCV_SBI:
+ return kvm_riscv_vcpu_set_reg_sbi(vcpu, reg);
default:
break;
}
@@ -1141,6 +1231,8 @@ int kvm_riscv_vcpu_get_reg(struct kvm_vcpu *vcpu,
return kvm_riscv_vcpu_get_reg_sbi_ext(vcpu, reg);
case KVM_REG_RISCV_VECTOR:
return kvm_riscv_vcpu_get_reg_vector(vcpu, reg);
+ case KVM_REG_RISCV_SBI:
+ return kvm_riscv_vcpu_get_reg_sbi(vcpu, reg);
default:
break;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v1 09/14] RISC-V: KVM: Add support for SBI STA registers
2023-12-05 18:11 [PATCH v1 00/14] RISC-V: Add steal-time support Andrew Jones
` (7 preceding siblings ...)
2023-12-05 18:11 ` [PATCH v1 08/14] RISC-V: KVM: Add support for SBI extension registers Andrew Jones
@ 2023-12-05 18:11 ` Andrew Jones
2023-12-05 18:11 ` [PATCH v1 10/14] RISC-V: KVM: Implement SBI STA extension Andrew Jones
` (4 subsequent siblings)
13 siblings, 0 replies; 19+ messages in thread
From: Andrew Jones @ 2023-12-05 18:11 UTC (permalink / raw)
To: kvm-riscv, linux-riscv, virtualization
Cc: anup, atishp, pbonzini, paul.walmsley, palmer, aou, jgross,
srivatsa, guoren
KVM userspace needs to be able to save and restore the steal-time
shared memory address. Provide the address through the get/set-one-reg
interface with two ulong-sized SBI STA extension registers (lo and hi).
64-bit KVM userspace must not set the hi register to anything other
than zero and is allowed to completely neglect saving/restoring it.
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
---
arch/riscv/include/asm/kvm_vcpu_sbi.h | 5 +++
arch/riscv/include/uapi/asm/kvm.h | 9 +++++
arch/riscv/kvm/vcpu_onereg.c | 41 +++++++++++++-------
arch/riscv/kvm/vcpu_sbi_sta.c | 55 +++++++++++++++++++++++++++
4 files changed, 96 insertions(+), 14 deletions(-)
diff --git a/arch/riscv/include/asm/kvm_vcpu_sbi.h b/arch/riscv/include/asm/kvm_vcpu_sbi.h
index 99c23bb37a37..ef56b850d46f 100644
--- a/arch/riscv/include/asm/kvm_vcpu_sbi.h
+++ b/arch/riscv/include/asm/kvm_vcpu_sbi.h
@@ -66,6 +66,11 @@ bool riscv_vcpu_supports_sbi_ext(struct kvm_vcpu *vcpu, int idx);
int kvm_riscv_vcpu_sbi_ecall(struct kvm_vcpu *vcpu, struct kvm_run *run);
void kvm_riscv_vcpu_sbi_init(struct kvm_vcpu *vcpu);
+int kvm_riscv_vcpu_get_reg_sbi_sta(struct kvm_vcpu *vcpu, unsigned long reg_num,
+ unsigned long *reg_val);
+int kvm_riscv_vcpu_set_reg_sbi_sta(struct kvm_vcpu *vcpu, unsigned long reg_num,
+ unsigned long reg_val);
+
#ifdef CONFIG_RISCV_SBI_V01
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_v01;
#endif
diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h
index 86df125ef17f..8d4f15f1b189 100644
--- a/arch/riscv/include/uapi/asm/kvm.h
+++ b/arch/riscv/include/uapi/asm/kvm.h
@@ -188,6 +188,12 @@ enum KVM_RISCV_SBI_EXT_ID {
KVM_RISCV_SBI_EXT_MAX,
};
+/* SBI STA extension registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
+struct kvm_riscv_sbi_sta {
+ unsigned long shmem_lo;
+ unsigned long shmem_hi;
+};
+
/* Possible states for kvm_riscv_timer */
#define KVM_RISCV_TIMER_STATE_OFF 0
#define KVM_RISCV_TIMER_STATE_ON 1
@@ -271,6 +277,9 @@ enum KVM_RISCV_SBI_EXT_ID {
/* Registers for specific SBI extensions are mapped as type 10 */
#define KVM_REG_RISCV_SBI (0x0a << KVM_REG_RISCV_TYPE_SHIFT)
+#define KVM_REG_RISCV_SBI_STA (0x0 << KVM_REG_RISCV_SUBTYPE_SHIFT)
+#define KVM_REG_RISCV_SBI_STA_REG(name) \
+ (offsetof(struct kvm_riscv_sbi_sta, name) / sizeof(unsigned long))
/* Device Control API: RISC-V AIA */
#define KVM_DEV_RISCV_APLIC_ALIGN 0x1000
diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c
index dbd8cedfd556..c2819c99988d 100644
--- a/arch/riscv/kvm/vcpu_onereg.c
+++ b/arch/riscv/kvm/vcpu_onereg.c
@@ -1033,6 +1033,9 @@ static int kvm_riscv_vcpu_get_reg_sbi(struct kvm_vcpu *vcpu,
reg_num &= ~KVM_REG_RISCV_SUBTYPE_MASK;
switch (reg_subtype) {
+ case KVM_REG_RISCV_SBI_STA:
+ ret = kvm_riscv_vcpu_get_reg_sbi_sta(vcpu, reg_num, ®_val);
+ break;
default:
return -EINVAL;
}
@@ -1066,6 +1069,8 @@ static int kvm_riscv_vcpu_set_reg_sbi(struct kvm_vcpu *vcpu,
reg_num &= ~KVM_REG_RISCV_SUBTYPE_MASK;
switch (reg_subtype) {
+ case KVM_REG_RISCV_SBI_STA:
+ return kvm_riscv_vcpu_set_reg_sbi_sta(vcpu, reg_num, reg_val);
default:
return -EINVAL;
}
@@ -1073,27 +1078,35 @@ static int kvm_riscv_vcpu_set_reg_sbi(struct kvm_vcpu *vcpu,
return 0;
}
-static inline unsigned long num_sbi_regs(struct kvm_vcpu *vcpu)
-{
- return 0;
-}
-
static int copy_sbi_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
{
- int n = num_sbi_regs(vcpu);
+ struct kvm_vcpu_sbi_context *scontext = &vcpu->arch.sbi_context;
+ int total = 0;
- for (int i = 0; i < n; i++) {
- u64 reg = KVM_REG_RISCV | KVM_REG_SIZE_U64 |
- KVM_REG_RISCV_SBI | i;
+ if (scontext->ext_status[KVM_RISCV_SBI_EXT_STA] == KVM_RISCV_SBI_EXT_STATUS_ENABLED) {
+ u64 size = IS_ENABLED(CONFIG_32BIT) ? KVM_REG_SIZE_U32 : KVM_REG_SIZE_U64;
+ int n = sizeof(struct kvm_riscv_sbi_sta) / sizeof(unsigned long);
- if (uindices) {
- if (put_user(reg, uindices))
- return -EFAULT;
- uindices++;
+ for (int i = 0; i < n; i++) {
+ u64 reg = KVM_REG_RISCV | size |
+ KVM_REG_RISCV_SBI | KVM_REG_RISCV_SBI_STA | i;
+
+ if (uindices) {
+ if (put_user(reg, uindices))
+ return -EFAULT;
+ uindices++;
+ }
}
+
+ total += n;
}
- return n;
+ return total;
+}
+
+static inline unsigned long num_sbi_regs(struct kvm_vcpu *vcpu)
+{
+ return copy_sbi_reg_indices(vcpu, NULL);
}
/*
diff --git a/arch/riscv/kvm/vcpu_sbi_sta.c b/arch/riscv/kvm/vcpu_sbi_sta.c
index 157c199be0b4..073bc47013b7 100644
--- a/arch/riscv/kvm/vcpu_sbi_sta.c
+++ b/arch/riscv/kvm/vcpu_sbi_sta.c
@@ -3,6 +3,8 @@
* Copyright (c) 2023 Ventana Micro Systems Inc.
*/
+#include <linux/kconfig.h>
+#include <linux/kernel.h>
#include <linux/kvm_host.h>
#include <asm/kvm_vcpu_sbi.h>
@@ -53,3 +55,56 @@ const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_sta = {
.handler = kvm_sbi_ext_sta_handler,
.probe = kvm_sbi_ext_sta_probe,
};
+
+int kvm_riscv_vcpu_get_reg_sbi_sta(struct kvm_vcpu *vcpu,
+ unsigned long reg_num,
+ unsigned long *reg_val)
+{
+ switch (reg_num) {
+ case KVM_REG_RISCV_SBI_STA_REG(shmem_lo):
+ *reg_val = (unsigned long)vcpu->arch.sta.shmem;
+ break;
+ case KVM_REG_RISCV_SBI_STA_REG(shmem_hi):
+ if (IS_ENABLED(CONFIG_32BIT))
+ *reg_val = upper_32_bits(vcpu->arch.sta.shmem);
+ else
+ *reg_val = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int kvm_riscv_vcpu_set_reg_sbi_sta(struct kvm_vcpu *vcpu,
+ unsigned long reg_num,
+ unsigned long reg_val)
+{
+ switch (reg_num) {
+ case KVM_REG_RISCV_SBI_STA_REG(shmem_lo):
+ if (IS_ENABLED(CONFIG_32BIT)) {
+ gpa_t hi = upper_32_bits(vcpu->arch.sta.shmem);
+
+ vcpu->arch.sta.shmem = reg_val;
+ vcpu->arch.sta.shmem |= hi << 32;
+ } else {
+ vcpu->arch.sta.shmem = reg_val;
+ }
+ break;
+ case KVM_REG_RISCV_SBI_STA_REG(shmem_hi):
+ if (IS_ENABLED(CONFIG_32BIT)) {
+ gpa_t lo = lower_32_bits(vcpu->arch.sta.shmem);
+
+ vcpu->arch.sta.shmem = ((gpa_t)reg_val << 32);
+ vcpu->arch.sta.shmem |= lo;
+ } else if (reg_val != 0) {
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v1 10/14] RISC-V: KVM: Implement SBI STA extension
2023-12-05 18:11 [PATCH v1 00/14] RISC-V: Add steal-time support Andrew Jones
` (8 preceding siblings ...)
2023-12-05 18:11 ` [PATCH v1 09/14] RISC-V: KVM: Add support for SBI STA registers Andrew Jones
@ 2023-12-05 18:11 ` Andrew Jones
2023-12-05 18:11 ` [PATCH v1 11/14] RISC-V: KVM: selftests: Move sbi_ecall to processor.c Andrew Jones
` (3 subsequent siblings)
13 siblings, 0 replies; 19+ messages in thread
From: Andrew Jones @ 2023-12-05 18:11 UTC (permalink / raw)
To: kvm-riscv, linux-riscv, virtualization
Cc: anup, atishp, pbonzini, paul.walmsley, palmer, aou, jgross,
srivatsa, guoren
Add a select SCHED_INFO to the KVM config in order to get run_delay
info. Then implement SBI STA's set-steal-time-shmem function and
kvm_riscv_vcpu_record_steal_time() to provide the steal-time info
to guests.
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
---
arch/riscv/kvm/Kconfig | 1 +
arch/riscv/kvm/vcpu_sbi_sta.c | 96 ++++++++++++++++++++++++++++++++++-
2 files changed, 95 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/kvm/Kconfig b/arch/riscv/kvm/Kconfig
index dfc237d7875b..148e52b516cf 100644
--- a/arch/riscv/kvm/Kconfig
+++ b/arch/riscv/kvm/Kconfig
@@ -32,6 +32,7 @@ config KVM
select KVM_XFER_TO_GUEST_WORK
select MMU_NOTIFIER
select PREEMPT_NOTIFIERS
+ select SCHED_INFO
help
Support hosting virtualized guest machines.
diff --git a/arch/riscv/kvm/vcpu_sbi_sta.c b/arch/riscv/kvm/vcpu_sbi_sta.c
index 073bc47013b7..8b8dbee5500a 100644
--- a/arch/riscv/kvm/vcpu_sbi_sta.c
+++ b/arch/riscv/kvm/vcpu_sbi_sta.c
@@ -6,21 +6,113 @@
#include <linux/kconfig.h>
#include <linux/kernel.h>
#include <linux/kvm_host.h>
+#include <linux/mm.h>
+#include <linux/sizes.h>
+#include <asm/bug.h>
+#include <asm/current.h>
#include <asm/kvm_vcpu_sbi.h>
+#include <asm/page.h>
#include <asm/sbi.h>
+#include <asm/uaccess.h>
void kvm_riscv_vcpu_record_steal_time(struct kvm_vcpu *vcpu)
{
gpa_t shmem = vcpu->arch.sta.shmem;
+ u64 last_steal = vcpu->arch.sta.last_steal;
+ u32 *sequence_ptr, sequence;
+ u64 *steal_ptr, steal;
+ unsigned long hva;
+ gfn_t gfn;
if (shmem == INVALID_GPA)
return;
+
+ /*
+ * shmem is 64-byte aligned (see the enforcement in
+ * kvm_sbi_sta_steal_time_set_shmem()) and the size of sbi_sta_struct
+ * is 64 bytes, so we know all its offsets are in the same page.
+ */
+ gfn = shmem >> PAGE_SHIFT;
+ hva = kvm_vcpu_gfn_to_hva(vcpu, gfn);
+
+ if (WARN_ON(kvm_is_error_hva(hva))) {
+ vcpu->arch.sta.shmem = INVALID_GPA;
+ return;
+ }
+
+ sequence_ptr = (u32 *)(hva + offset_in_page(shmem) +
+ offsetof(struct sbi_sta_struct, sequence));
+ steal_ptr = (u64 *)(hva + offset_in_page(shmem) +
+ offsetof(struct sbi_sta_struct, steal));
+
+ if (WARN_ON(get_user(sequence, sequence_ptr)))
+ return;
+
+ sequence = le32_to_cpu(sequence);
+ sequence += 1;
+
+ if (WARN_ON(put_user(cpu_to_le32(sequence), sequence_ptr)))
+ return;
+
+ if (!WARN_ON(get_user(steal, steal_ptr))) {
+ steal = le64_to_cpu(steal);
+ vcpu->arch.sta.last_steal = READ_ONCE(current->sched_info.run_delay);
+ steal += vcpu->arch.sta.last_steal - last_steal;
+ WARN_ON(put_user(cpu_to_le64(steal), steal_ptr));
+ }
+
+ sequence += 1;
+ WARN_ON(put_user(cpu_to_le32(sequence), sequence_ptr));
+
+ kvm_vcpu_mark_page_dirty(vcpu, gfn);
}
static int kvm_sbi_sta_steal_time_set_shmem(struct kvm_vcpu *vcpu)
{
- return SBI_ERR_FAILURE;
+ struct kvm_cpu_context *cp = &vcpu->arch.guest_context;
+ unsigned long shmem_phys_lo = cp->a0;
+ unsigned long shmem_phys_hi = cp->a1;
+ u32 flags = cp->a2;
+ struct sbi_sta_struct zero_sta = {0};
+ unsigned long hva;
+ bool writable;
+ gpa_t shmem;
+ int ret;
+
+ if (flags != 0)
+ return SBI_ERR_INVALID_PARAM;
+
+ if (shmem_phys_lo == SBI_STA_SHMEM_DISABLE &&
+ shmem_phys_hi == SBI_STA_SHMEM_DISABLE) {
+ vcpu->arch.sta.shmem = INVALID_GPA;
+ return 0;
+ }
+
+ if (shmem_phys_lo & (SZ_64 - 1))
+ return SBI_ERR_INVALID_PARAM;
+
+ shmem = shmem_phys_lo;
+
+ if (shmem_phys_hi != 0) {
+ if (IS_ENABLED(CONFIG_32BIT))
+ shmem |= ((gpa_t)shmem_phys_hi << 32);
+ else
+ return SBI_ERR_INVALID_ADDRESS;
+ }
+
+ hva = kvm_vcpu_gfn_to_hva_prot(vcpu, shmem >> PAGE_SHIFT, &writable);
+ if (kvm_is_error_hva(hva) || !writable)
+ return SBI_ERR_INVALID_ADDRESS;
+
+ ret = kvm_vcpu_write_guest(vcpu, shmem, &zero_sta, sizeof(zero_sta));
+ if (ret)
+ return SBI_ERR_FAILURE;
+
+ vcpu->arch.sta.shmem = shmem;
+ vcpu->arch.sta.last_steal = current->sched_info.run_delay;
+
+ return 0;
}
static int kvm_sbi_ext_sta_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
@@ -46,7 +138,7 @@ static int kvm_sbi_ext_sta_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
static unsigned long kvm_sbi_ext_sta_probe(struct kvm_vcpu *vcpu)
{
- return 0;
+ return !!sched_info_on();
}
const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_sta = {
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v1 11/14] RISC-V: KVM: selftests: Move sbi_ecall to processor.c
2023-12-05 18:11 [PATCH v1 00/14] RISC-V: Add steal-time support Andrew Jones
` (9 preceding siblings ...)
2023-12-05 18:11 ` [PATCH v1 10/14] RISC-V: KVM: Implement SBI STA extension Andrew Jones
@ 2023-12-05 18:11 ` Andrew Jones
2023-12-05 18:11 ` [PATCH v1 12/14] RISC-V: KVM: selftests: Add guest_sbi_probe_extension Andrew Jones
` (2 subsequent siblings)
13 siblings, 0 replies; 19+ messages in thread
From: Andrew Jones @ 2023-12-05 18:11 UTC (permalink / raw)
To: kvm-riscv, linux-riscv, virtualization
Cc: anup, atishp, pbonzini, paul.walmsley, palmer, aou, jgross,
srivatsa, guoren
sbi_ecall() isn't ucall specific and its prototype is already in
processor.h. Move its implementation to processor.c.
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
---
.../selftests/kvm/lib/riscv/processor.c | 26 +++++++++++++++++++
tools/testing/selftests/kvm/lib/riscv/ucall.c | 26 -------------------
2 files changed, 26 insertions(+), 26 deletions(-)
diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c b/tools/testing/selftests/kvm/lib/riscv/processor.c
index 6c25f7843ef4..6905a4348380 100644
--- a/tools/testing/selftests/kvm/lib/riscv/processor.c
+++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
@@ -367,3 +367,29 @@ void vcpu_args_set(struct kvm_vcpu *vcpu, unsigned int num, ...)
void assert_on_unhandled_exception(struct kvm_vcpu *vcpu)
{
}
+
+struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
+ unsigned long arg1, unsigned long arg2,
+ unsigned long arg3, unsigned long arg4,
+ unsigned long arg5)
+{
+ register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0);
+ register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1);
+ register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2);
+ register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3);
+ register uintptr_t a4 asm ("a4") = (uintptr_t)(arg4);
+ register uintptr_t a5 asm ("a5") = (uintptr_t)(arg5);
+ register uintptr_t a6 asm ("a6") = (uintptr_t)(fid);
+ register uintptr_t a7 asm ("a7") = (uintptr_t)(ext);
+ struct sbiret ret;
+
+ asm volatile (
+ "ecall"
+ : "+r" (a0), "+r" (a1)
+ : "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7)
+ : "memory");
+ ret.error = a0;
+ ret.value = a1;
+
+ return ret;
+}
diff --git a/tools/testing/selftests/kvm/lib/riscv/ucall.c b/tools/testing/selftests/kvm/lib/riscv/ucall.c
index fe6d1004f018..14ee17151a59 100644
--- a/tools/testing/selftests/kvm/lib/riscv/ucall.c
+++ b/tools/testing/selftests/kvm/lib/riscv/ucall.c
@@ -10,32 +10,6 @@
#include "kvm_util.h"
#include "processor.h"
-struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
- unsigned long arg1, unsigned long arg2,
- unsigned long arg3, unsigned long arg4,
- unsigned long arg5)
-{
- register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0);
- register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1);
- register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2);
- register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3);
- register uintptr_t a4 asm ("a4") = (uintptr_t)(arg4);
- register uintptr_t a5 asm ("a5") = (uintptr_t)(arg5);
- register uintptr_t a6 asm ("a6") = (uintptr_t)(fid);
- register uintptr_t a7 asm ("a7") = (uintptr_t)(ext);
- struct sbiret ret;
-
- asm volatile (
- "ecall"
- : "+r" (a0), "+r" (a1)
- : "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7)
- : "memory");
- ret.error = a0;
- ret.value = a1;
-
- return ret;
-}
-
void *ucall_arch_get_ucall(struct kvm_vcpu *vcpu)
{
struct kvm_run *run = vcpu->run;
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v1 12/14] RISC-V: KVM: selftests: Add guest_sbi_probe_extension
2023-12-05 18:11 [PATCH v1 00/14] RISC-V: Add steal-time support Andrew Jones
` (10 preceding siblings ...)
2023-12-05 18:11 ` [PATCH v1 11/14] RISC-V: KVM: selftests: Move sbi_ecall to processor.c Andrew Jones
@ 2023-12-05 18:11 ` Andrew Jones
2023-12-05 18:11 ` [PATCH v1 13/14] RISC-V: KVM: selftests: Add steal_time test support Andrew Jones
2023-12-05 18:11 ` [PATCH v1 14/14] RISC-V: KVM: selftests: Add get-reg-list test for STA registers Andrew Jones
13 siblings, 0 replies; 19+ messages in thread
From: Andrew Jones @ 2023-12-05 18:11 UTC (permalink / raw)
To: kvm-riscv, linux-riscv, virtualization
Cc: anup, atishp, pbonzini, paul.walmsley, palmer, aou, jgross,
srivatsa, guoren
Add guest_sbi_probe_extension(), allowing guest code to probe for
SBI extensions. As guest_sbi_probe_extension() needs
SBI_ERR_NOT_SUPPORTED, take the opportunity to bring in all SBI
error codes. We don't bring in all current extension IDs or base
extension function IDs though, even though we need one of each,
because we'd prefer to bring those in as necessary.
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
---
.../selftests/kvm/include/riscv/processor.h | 21 +++++++++++++++++++
.../selftests/kvm/lib/riscv/processor.c | 19 +++++++++++++++++
2 files changed, 40 insertions(+)
diff --git a/tools/testing/selftests/kvm/include/riscv/processor.h b/tools/testing/selftests/kvm/include/riscv/processor.h
index e70ccda2011b..dc50ad62e150 100644
--- a/tools/testing/selftests/kvm/include/riscv/processor.h
+++ b/tools/testing/selftests/kvm/include/riscv/processor.h
@@ -108,6 +108,17 @@ static inline uint64_t __kvm_reg_id(uint64_t type, uint64_t subtype,
#define SATP_ASID_SHIFT 44
#define SATP_ASID_MASK _AC(0xFFFF, UL)
+/* SBI return error codes */
+#define SBI_SUCCESS 0
+#define SBI_ERR_FAILURE -1
+#define SBI_ERR_NOT_SUPPORTED -2
+#define SBI_ERR_INVALID_PARAM -3
+#define SBI_ERR_DENIED -4
+#define SBI_ERR_INVALID_ADDRESS -5
+#define SBI_ERR_ALREADY_AVAILABLE -6
+#define SBI_ERR_ALREADY_STARTED -7
+#define SBI_ERR_ALREADY_STOPPED -8
+
#define SBI_EXT_EXPERIMENTAL_START 0x08000000
#define SBI_EXT_EXPERIMENTAL_END 0x08FFFFFF
@@ -115,6 +126,14 @@ static inline uint64_t __kvm_reg_id(uint64_t type, uint64_t subtype,
#define KVM_RISCV_SELFTESTS_SBI_UCALL 0
#define KVM_RISCV_SELFTESTS_SBI_UNEXP 1
+enum sbi_ext_id {
+ SBI_EXT_BASE = 0x10,
+};
+
+enum sbi_ext_base_fid {
+ SBI_EXT_BASE_PROBE_EXT = 3,
+};
+
struct sbiret {
long error;
long value;
@@ -125,4 +144,6 @@ struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
unsigned long arg3, unsigned long arg4,
unsigned long arg5);
+bool guest_sbi_probe_extension(int extid, long *out_val);
+
#endif /* SELFTEST_KVM_PROCESSOR_H */
diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c b/tools/testing/selftests/kvm/lib/riscv/processor.c
index 6905a4348380..7ca736fb4194 100644
--- a/tools/testing/selftests/kvm/lib/riscv/processor.c
+++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
@@ -393,3 +393,22 @@ struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
return ret;
}
+
+bool guest_sbi_probe_extension(int extid, long *out_val)
+{
+ struct sbiret ret;
+
+ ret = sbi_ecall(SBI_EXT_BASE, SBI_EXT_BASE_PROBE_EXT, extid,
+ 0, 0, 0, 0, 0);
+
+ __GUEST_ASSERT(!ret.error || ret.error == SBI_ERR_NOT_SUPPORTED,
+ "ret.error=%ld, ret.value=%ld\n", ret.error, ret.value);
+
+ if (ret.error == SBI_ERR_NOT_SUPPORTED)
+ return false;
+
+ if (out_val)
+ *out_val = ret.value;
+
+ return true;
+}
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v1 13/14] RISC-V: KVM: selftests: Add steal_time test support
2023-12-05 18:11 [PATCH v1 00/14] RISC-V: Add steal-time support Andrew Jones
` (11 preceding siblings ...)
2023-12-05 18:11 ` [PATCH v1 12/14] RISC-V: KVM: selftests: Add guest_sbi_probe_extension Andrew Jones
@ 2023-12-05 18:11 ` Andrew Jones
2023-12-05 18:11 ` [PATCH v1 14/14] RISC-V: KVM: selftests: Add get-reg-list test for STA registers Andrew Jones
13 siblings, 0 replies; 19+ messages in thread
From: Andrew Jones @ 2023-12-05 18:11 UTC (permalink / raw)
To: kvm-riscv, linux-riscv, virtualization
Cc: anup, atishp, pbonzini, paul.walmsley, palmer, aou, jgross,
srivatsa, guoren
With the introduction of steal-time accounting support for
RISC-V KVM we can add RISC-V support to the steal_time test.
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
---
tools/testing/selftests/kvm/Makefile | 5 +-
.../selftests/kvm/include/riscv/processor.h | 1 +
tools/testing/selftests/kvm/steal_time.c | 99 +++++++++++++++++++
3 files changed, 103 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index a5963ab9215b..ab52bd0c0c5b 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -193,12 +193,13 @@ TEST_GEN_PROGS_s390x += kvm_binary_stats_test
TEST_GEN_PROGS_riscv += demand_paging_test
TEST_GEN_PROGS_riscv += dirty_log_test
-TEST_GEN_PROGS_riscv += guest_print_test
TEST_GEN_PROGS_riscv += get-reg-list
+TEST_GEN_PROGS_riscv += guest_print_test
+TEST_GEN_PROGS_riscv += kvm_binary_stats_test
TEST_GEN_PROGS_riscv += kvm_create_max_vcpus
TEST_GEN_PROGS_riscv += kvm_page_table_test
TEST_GEN_PROGS_riscv += set_memory_region_test
-TEST_GEN_PROGS_riscv += kvm_binary_stats_test
+TEST_GEN_PROGS_riscv += steal_time
SPLIT_TESTS += get-reg-list
diff --git a/tools/testing/selftests/kvm/include/riscv/processor.h b/tools/testing/selftests/kvm/include/riscv/processor.h
index dc50ad62e150..a0f9efe5a2a8 100644
--- a/tools/testing/selftests/kvm/include/riscv/processor.h
+++ b/tools/testing/selftests/kvm/include/riscv/processor.h
@@ -128,6 +128,7 @@ static inline uint64_t __kvm_reg_id(uint64_t type, uint64_t subtype,
enum sbi_ext_id {
SBI_EXT_BASE = 0x10,
+ SBI_EXT_STA = 0x535441,
};
enum sbi_ext_base_fid {
diff --git a/tools/testing/selftests/kvm/steal_time.c b/tools/testing/selftests/kvm/steal_time.c
index 171adfb2a6cb..bae0c5026f82 100644
--- a/tools/testing/selftests/kvm/steal_time.c
+++ b/tools/testing/selftests/kvm/steal_time.c
@@ -11,7 +11,9 @@
#include <pthread.h>
#include <linux/kernel.h>
#include <asm/kvm.h>
+#ifndef __riscv
#include <asm/kvm_para.h>
+#endif
#include "test_util.h"
#include "kvm_util.h"
@@ -203,6 +205,103 @@ static void steal_time_dump(struct kvm_vm *vm, uint32_t vcpu_idx)
pr_info(" st_time: %ld\n", st->st_time);
}
+#elif defined(__riscv)
+
+/* SBI STA shmem must have 64-byte alignment */
+#define STEAL_TIME_SIZE ((sizeof(struct sta_struct) + 63) & ~63)
+
+static vm_paddr_t st_gpa[NR_VCPUS];
+
+struct sta_struct {
+ uint32_t sequence;
+ uint32_t flags;
+ uint64_t steal;
+ uint8_t preempted;
+ uint8_t pad[47];
+} __packed;
+
+static void sta_set_shmem(vm_paddr_t gpa, unsigned long flags)
+{
+ unsigned long lo = (unsigned long)gpa;
+#if __riscv_xlen == 32
+ unsigned long hi = (unsigned long)(gpa >> 32);
+#else
+ unsigned long hi = gpa == -1 ? -1 : 0;
+#endif
+ struct sbiret ret = sbi_ecall(SBI_EXT_STA, 0, lo, hi, flags, 0, 0, 0);
+
+ GUEST_ASSERT(ret.value == 0 && ret.error == 0);
+}
+
+static void check_status(struct sta_struct *st)
+{
+ GUEST_ASSERT(!(READ_ONCE(st->sequence) & 1));
+ GUEST_ASSERT(READ_ONCE(st->flags) == 0);
+ GUEST_ASSERT(READ_ONCE(st->preempted) == 0);
+}
+
+static void guest_code(int cpu)
+{
+ struct sta_struct *st = st_gva[cpu];
+ uint32_t sequence;
+ long out_val = 0;
+ bool probe;
+
+ probe = guest_sbi_probe_extension(SBI_EXT_STA, &out_val);
+ GUEST_ASSERT(probe && out_val == 1);
+
+ sta_set_shmem(st_gpa[cpu], 0);
+ GUEST_SYNC(0);
+
+ check_status(st);
+ WRITE_ONCE(guest_stolen_time[cpu], st->steal);
+ sequence = READ_ONCE(st->sequence);
+ check_status(st);
+ GUEST_SYNC(1);
+
+ check_status(st);
+ GUEST_ASSERT(sequence < READ_ONCE(st->sequence));
+ WRITE_ONCE(guest_stolen_time[cpu], st->steal);
+ check_status(st);
+ GUEST_DONE();
+}
+
+static bool is_steal_time_supported(struct kvm_vcpu *vcpu)
+{
+ uint64_t id = RISCV_SBI_EXT_REG(KVM_RISCV_SBI_EXT_STA);
+ unsigned long enabled;
+
+ vcpu_get_reg(vcpu, id, &enabled);
+ TEST_ASSERT(enabled == 0 || enabled == 1, "Expected boolean result");
+
+ return enabled;
+}
+
+static void steal_time_init(struct kvm_vcpu *vcpu, uint32_t i)
+{
+ /* ST_GPA_BASE is identity mapped */
+ st_gva[i] = (void *)(ST_GPA_BASE + i * STEAL_TIME_SIZE);
+ st_gpa[i] = addr_gva2gpa(vcpu->vm, (vm_vaddr_t)st_gva[i]);
+ sync_global_to_guest(vcpu->vm, st_gva[i]);
+ sync_global_to_guest(vcpu->vm, st_gpa[i]);
+}
+
+static void steal_time_dump(struct kvm_vm *vm, uint32_t vcpu_idx)
+{
+ struct sta_struct *st = addr_gva2hva(vm, (ulong)st_gva[vcpu_idx]);
+ int i;
+
+ pr_info("VCPU%d:\n", vcpu_idx);
+ pr_info(" sequence: %d\n", st->sequence);
+ pr_info(" flags: %d\n", st->flags);
+ pr_info(" steal: %"PRIu64"\n", st->steal);
+ pr_info(" preempted: %d\n", st->preempted);
+ pr_info(" pad: ");
+ for (i = 0; i < 47; ++i)
+ pr_info("%d", st->pad[i]);
+ pr_info("\n");
+}
+
#endif
static void *do_steal_time(void *arg)
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v1 14/14] RISC-V: KVM: selftests: Add get-reg-list test for STA registers
2023-12-05 18:11 [PATCH v1 00/14] RISC-V: Add steal-time support Andrew Jones
` (12 preceding siblings ...)
2023-12-05 18:11 ` [PATCH v1 13/14] RISC-V: KVM: selftests: Add steal_time test support Andrew Jones
@ 2023-12-05 18:11 ` Andrew Jones
13 siblings, 0 replies; 19+ messages in thread
From: Andrew Jones @ 2023-12-05 18:11 UTC (permalink / raw)
To: kvm-riscv, linux-riscv, virtualization
Cc: anup, atishp, pbonzini, paul.walmsley, palmer, aou, jgross,
srivatsa, guoren
Add SBI STA and its two registers to the get-reg-list test.
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
---
.../selftests/kvm/riscv/get-reg-list.c | 43 +++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
index bd21991f5d99..6fc849284573 100644
--- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
+++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
@@ -98,6 +98,7 @@ bool filter_reg(__u64 reg)
case KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_HSM:
case KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_PMU:
case KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_DBCN:
+ case KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_STA:
case KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_EXPERIMENTAL:
case KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_VENDOR:
return true;
@@ -515,6 +516,7 @@ static const char *sbi_ext_single_id_to_str(__u64 reg_off)
KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_SRST),
KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_HSM),
KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_PMU),
+ KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_STA),
KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_EXPERIMENTAL),
KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_VENDOR),
KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_DBCN),
@@ -563,6 +565,32 @@ static const char *sbi_ext_id_to_str(const char *prefix, __u64 id)
return strdup_printf("%lld | %lld /* UNKNOWN */", reg_subtype, reg_off);
}
+static const char *sbi_sta_id_to_str(__u64 reg_off)
+{
+ switch (reg_off) {
+ case 0: return "KVM_REG_RISCV_SBI_STA | KVM_REG_RISCV_SBI_STA_REG(shmem_lo)";
+ case 1: return "KVM_REG_RISCV_SBI_STA | KVM_REG_RISCV_SBI_STA_REG(shmem_hi)";
+ }
+ return strdup_printf("KVM_REG_RISCV_SBI_STA | %lld /* UNKNOWN */", reg_off);
+}
+
+static const char *sbi_id_to_str(const char *prefix, __u64 id)
+{
+ __u64 reg_off = id & ~(REG_MASK | KVM_REG_RISCV_SBI);
+ __u64 reg_subtype = reg_off & KVM_REG_RISCV_SUBTYPE_MASK;
+
+ assert((id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_SBI);
+
+ reg_off &= ~KVM_REG_RISCV_SUBTYPE_MASK;
+
+ switch (reg_subtype) {
+ case KVM_REG_RISCV_SBI_STA:
+ return sbi_sta_id_to_str(reg_off);
+ }
+
+ return strdup_printf("%lld | %lld /* UNKNOWN */", reg_subtype, reg_off);
+}
+
void print_reg(const char *prefix, __u64 id)
{
const char *reg_size = NULL;
@@ -618,6 +646,10 @@ void print_reg(const char *prefix, __u64 id)
printf("\tKVM_REG_RISCV | %s | KVM_REG_RISCV_SBI_EXT | %s,\n",
reg_size, sbi_ext_id_to_str(prefix, id));
break;
+ case KVM_REG_RISCV_SBI:
+ printf("\tKVM_REG_RISCV | %s | KVM_REG_RISCV_SBI | %s,\n",
+ reg_size, sbi_id_to_str(prefix, id));
+ break;
default:
printf("\tKVM_REG_RISCV | %s | 0x%llx /* UNKNOWN */,",
reg_size, id & REG_MASK);
@@ -703,6 +735,12 @@ static __u64 sbi_base_regs[] = {
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_VENDOR,
};
+static __u64 sbi_sta_regs[] = {
+ KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_STA,
+ KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI | KVM_REG_RISCV_SBI_STA | KVM_REG_RISCV_SBI_STA_REG(shmem_lo),
+ KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI | KVM_REG_RISCV_SBI_STA | KVM_REG_RISCV_SBI_STA_REG(shmem_hi),
+};
+
static __u64 zicbom_regs[] = {
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_CONFIG | KVM_REG_RISCV_CONFIG_REG(zicbom_block_size),
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZICBOM,
@@ -809,6 +847,9 @@ static __u64 fp_d_regs[] = {
#define SUBLIST_SBI_BASE \
{"sbi-base", .feature_type = VCPU_FEATURE_SBI_EXT, .feature = KVM_RISCV_SBI_EXT_V01, \
.regs = sbi_base_regs, .regs_n = ARRAY_SIZE(sbi_base_regs),}
+#define SUBLIST_SBI_STA \
+ {"sbi-sta", .feature_type = VCPU_FEATURE_SBI_EXT, .feature = KVM_RISCV_SBI_EXT_STA, \
+ .regs = sbi_sta_regs, .regs_n = ARRAY_SIZE(sbi_sta_regs),}
#define SUBLIST_ZICBOM \
{"zicbom", .feature = KVM_RISCV_ISA_EXT_ZICBOM, .regs = zicbom_regs, .regs_n = ARRAY_SIZE(zicbom_regs),}
#define SUBLIST_ZICBOZ \
@@ -884,6 +925,7 @@ static struct vcpu_reg_list config_sbi_##ext = { \
/* Note: The below list is alphabetically sorted. */
KVM_SBI_EXT_SUBLIST_CONFIG(base, BASE);
+KVM_SBI_EXT_SUBLIST_CONFIG(sta, STA);
KVM_SBI_EXT_SIMPLE_CONFIG(pmu, PMU);
KVM_SBI_EXT_SIMPLE_CONFIG(dbcn, DBCN);
@@ -937,6 +979,7 @@ KVM_ISA_EXT_SIMPLE_CONFIG(zvkt, ZVKT);
struct vcpu_reg_list *vcpu_configs[] = {
&config_sbi_base,
+ &config_sbi_sta,
&config_sbi_pmu,
&config_sbi_dbcn,
&config_aia,
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH v1 03/14] RISC-V: paravirt: Implement steal-time support
2023-12-05 18:11 ` [PATCH v1 03/14] RISC-V: paravirt: Implement steal-time support Andrew Jones
@ 2023-12-07 14:06 ` Conor Dooley
2023-12-07 14:44 ` Andrew Jones
0 siblings, 1 reply; 19+ messages in thread
From: Conor Dooley @ 2023-12-07 14:06 UTC (permalink / raw)
To: Andrew Jones
Cc: kvm-riscv, linux-riscv, virtualization, anup, atishp, pbonzini,
paul.walmsley, palmer, aou, jgross, srivatsa, guoren
[-- Attachment #1: Type: text/plain, Size: 638 bytes --]
On Tue, Dec 05, 2023 at 07:11:23PM +0100, Andrew Jones wrote:
> +static int sbi_sta_steal_time_set_shmem(unsigned long lo, unsigned long hi,
> + unsigned long flags)
> {
> + struct sbiret ret;
> +
> + ret = sbi_ecall(SBI_EXT_STA, SBI_EXT_STA_STEAL_TIME_SET_SHMEM,
> + lo, hi, flags, 0, 0, 0);
> + if (ret.error) {
> + if (lo == SBI_STA_SHMEM_DISABLE && hi == SBI_STA_SHMEM_DISABLE)
> + pr_warn("Failed to disable steal-time shmem");
> + else
> + pr_warn("Failed to set steal-time shmem");
> + return -ENOMEM;
btw, how come this is an ENOMEM and not a propagation of the error from
the ecall?
> + }
> +
> return 0;
> }
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v1 04/14] RISC-V: paravirt: Add kconfigs
2023-12-05 18:11 ` [PATCH v1 04/14] RISC-V: paravirt: Add kconfigs Andrew Jones
@ 2023-12-07 14:07 ` Conor Dooley
2023-12-07 14:46 ` Andrew Jones
0 siblings, 1 reply; 19+ messages in thread
From: Conor Dooley @ 2023-12-07 14:07 UTC (permalink / raw)
To: Andrew Jones
Cc: kvm-riscv, linux-riscv, virtualization, anup, atishp, pbonzini,
paul.walmsley, palmer, aou, jgross, srivatsa, guoren
[-- Attachment #1: Type: text/plain, Size: 369 bytes --]
On Tue, Dec 05, 2023 at 07:11:24PM +0100, Andrew Jones wrote:
> Now that we can support steal-time accounting, add the kconfig
> knobs allowing it to be enabled.
>
> Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
> Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
In hindsight, should this be squashed with the code actually adding the
support?
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v1 03/14] RISC-V: paravirt: Implement steal-time support
2023-12-07 14:06 ` Conor Dooley
@ 2023-12-07 14:44 ` Andrew Jones
0 siblings, 0 replies; 19+ messages in thread
From: Andrew Jones @ 2023-12-07 14:44 UTC (permalink / raw)
To: Conor Dooley
Cc: kvm-riscv, linux-riscv, virtualization, anup, atishp, pbonzini,
paul.walmsley, palmer, aou, jgross, srivatsa, guoren
On Thu, Dec 07, 2023 at 02:06:37PM +0000, Conor Dooley wrote:
> On Tue, Dec 05, 2023 at 07:11:23PM +0100, Andrew Jones wrote:
>
> > +static int sbi_sta_steal_time_set_shmem(unsigned long lo, unsigned long hi,
> > + unsigned long flags)
> > {
> > + struct sbiret ret;
> > +
> > + ret = sbi_ecall(SBI_EXT_STA, SBI_EXT_STA_STEAL_TIME_SET_SHMEM,
> > + lo, hi, flags, 0, 0, 0);
> > + if (ret.error) {
> > + if (lo == SBI_STA_SHMEM_DISABLE && hi == SBI_STA_SHMEM_DISABLE)
> > + pr_warn("Failed to disable steal-time shmem");
> > + else
> > + pr_warn("Failed to set steal-time shmem");
> > + return -ENOMEM;
>
> btw, how come this is an ENOMEM and not a propagation of the error from
> the ecall?
Hmm, I can't recall why I did that. I think I should have used
sbi_err_map_linux_errno() to convert the possible SBI_ERR_INVALID_PARAM
and SBI_ERR_INVALID_ADDRESS errors appropriately instead. I don't much
like how SBI_ERR_FAILURE gets converted to ENOTSUPP, but I don't suppose
it matters much in practice anyway, and at least, in this case, it has a
1-to-1 mapping which is good for debug.
I'll change this for v2.
Thanks,
drew
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v1 04/14] RISC-V: paravirt: Add kconfigs
2023-12-07 14:07 ` Conor Dooley
@ 2023-12-07 14:46 ` Andrew Jones
0 siblings, 0 replies; 19+ messages in thread
From: Andrew Jones @ 2023-12-07 14:46 UTC (permalink / raw)
To: Conor Dooley
Cc: kvm-riscv, linux-riscv, virtualization, anup, atishp, pbonzini,
paul.walmsley, palmer, aou, jgross, srivatsa, guoren
On Thu, Dec 07, 2023 at 02:07:28PM +0000, Conor Dooley wrote:
> On Tue, Dec 05, 2023 at 07:11:24PM +0100, Andrew Jones wrote:
> > Now that we can support steal-time accounting, add the kconfig
> > knobs allowing it to be enabled.
> >
> > Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
> > Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
>
> In hindsight, should this be squashed with the code actually adding the
> support?
Yeah, this can be squashed, particularly because the configs are off by
default anyway. Will do.
Thanks,
drew
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2023-12-07 14:46 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-12-05 18:11 [PATCH v1 00/14] RISC-V: Add steal-time support Andrew Jones
2023-12-05 18:11 ` [PATCH v1 01/14] RISC-V: paravirt: Add skeleton for pv-time support Andrew Jones
2023-12-05 18:11 ` [PATCH v1 02/14] RISC-V: Add SBI STA extension definitions Andrew Jones
2023-12-05 18:11 ` [PATCH v1 03/14] RISC-V: paravirt: Implement steal-time support Andrew Jones
2023-12-07 14:06 ` Conor Dooley
2023-12-07 14:44 ` Andrew Jones
2023-12-05 18:11 ` [PATCH v1 04/14] RISC-V: paravirt: Add kconfigs Andrew Jones
2023-12-07 14:07 ` Conor Dooley
2023-12-07 14:46 ` Andrew Jones
2023-12-05 18:11 ` [PATCH v1 05/14] RISC-V: KVM: Add SBI STA extension skeleton Andrew Jones
2023-12-05 18:11 ` [PATCH v1 06/14] RISC-V: KVM: Add steal-update vcpu request Andrew Jones
2023-12-05 18:11 ` [PATCH v1 07/14] RISC-V: KVM: Add SBI STA info to vcpu_arch Andrew Jones
2023-12-05 18:11 ` [PATCH v1 08/14] RISC-V: KVM: Add support for SBI extension registers Andrew Jones
2023-12-05 18:11 ` [PATCH v1 09/14] RISC-V: KVM: Add support for SBI STA registers Andrew Jones
2023-12-05 18:11 ` [PATCH v1 10/14] RISC-V: KVM: Implement SBI STA extension Andrew Jones
2023-12-05 18:11 ` [PATCH v1 11/14] RISC-V: KVM: selftests: Move sbi_ecall to processor.c Andrew Jones
2023-12-05 18:11 ` [PATCH v1 12/14] RISC-V: KVM: selftests: Add guest_sbi_probe_extension Andrew Jones
2023-12-05 18:11 ` [PATCH v1 13/14] RISC-V: KVM: selftests: Add steal_time test support Andrew Jones
2023-12-05 18:11 ` [PATCH v1 14/14] RISC-V: KVM: selftests: Add get-reg-list test for STA registers Andrew Jones
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).