This series adds initial support for SBI v0.3 which includes:
1) SBI SRST support for Guest
2) SBI HSM suspend for Guest
The SBI PMU support is intentionally left out and will be added as
a separate patch series.
These patches can also be found in riscv_kvm_sbi_v03_v1 branch at:
https://github.com/avpatel/linux.git
Anup Patel (6):
RISC-V: KVM: Upgrade SBI spec version to v0.3
RISC-V: KVM: Add common kvm_riscv_vcpu_sbi_system_reset() function
RISC-V: KVM: Implement SBI v0.3 SRST extension
RISC-V: Add SBI HSM suspend related defines
RISC-V: KVM: Add common kvm_riscv_vcpu_wfi() function
RISC-V: KVM: Implement SBI HSM suspend call
arch/riscv/include/asm/kvm_host.h | 1 +
arch/riscv/include/asm/kvm_vcpu_sbi.h | 5 ++-
arch/riscv/include/asm/sbi.h | 27 +++++++++++++---
arch/riscv/kernel/cpu_ops_sbi.c | 2 +-
arch/riscv/kvm/vcpu_exit.c | 22 ++++++++++----
arch/riscv/kvm/vcpu_sbi.c | 19 ++++++++++++
arch/riscv/kvm/vcpu_sbi_hsm.c | 18 +++++++++--
arch/riscv/kvm/vcpu_sbi_replace.c | 44 +++++++++++++++++++++++++++
arch/riscv/kvm/vcpu_sbi_v01.c | 18 ++---------
9 files changed, 125 insertions(+), 31 deletions(-)
--
2.25.1
We upgrade SBI spec version implemented by KVM RISC-V to v0.3 so
that Guest kernel can probe and use SBI extensions added by the
SBI v0.3 specification.
Signed-off-by: Anup Patel <[email protected]>
---
arch/riscv/include/asm/kvm_vcpu_sbi.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/riscv/include/asm/kvm_vcpu_sbi.h b/arch/riscv/include/asm/kvm_vcpu_sbi.h
index 76e4e17a3e00..04cd81f2ab5b 100644
--- a/arch/riscv/include/asm/kvm_vcpu_sbi.h
+++ b/arch/riscv/include/asm/kvm_vcpu_sbi.h
@@ -12,7 +12,7 @@
#define KVM_SBI_IMPID 3
#define KVM_SBI_VERSION_MAJOR 0
-#define KVM_SBI_VERSION_MINOR 2
+#define KVM_SBI_VERSION_MINOR 3
struct kvm_vcpu_sbi_extension {
unsigned long extid_start;
--
2.25.1
We rename kvm_sbi_system_shutdown() to kvm_riscv_vcpu_sbi_system_reset()
and move it to vcpu_sbi.c so that it can be shared by SBI v0.1 shutdown
and SBI v0.3 SRST extension.
Signed-off-by: Anup Patel <[email protected]>
---
arch/riscv/include/asm/kvm_vcpu_sbi.h | 3 +++
arch/riscv/kvm/vcpu_sbi.c | 17 +++++++++++++++++
arch/riscv/kvm/vcpu_sbi_v01.c | 18 ++----------------
3 files changed, 22 insertions(+), 16 deletions(-)
diff --git a/arch/riscv/include/asm/kvm_vcpu_sbi.h b/arch/riscv/include/asm/kvm_vcpu_sbi.h
index 04cd81f2ab5b..83d6d4d2b1df 100644
--- a/arch/riscv/include/asm/kvm_vcpu_sbi.h
+++ b/arch/riscv/include/asm/kvm_vcpu_sbi.h
@@ -28,6 +28,9 @@ struct kvm_vcpu_sbi_extension {
};
void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run);
+void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu,
+ struct kvm_run *run,
+ u32 type, u64 flags);
const struct kvm_vcpu_sbi_extension *kvm_vcpu_sbi_find_ext(unsigned long extid);
#endif /* __RISCV_KVM_VCPU_SBI_H__ */
diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c
index 78aa3db76225..11ae4f621f0d 100644
--- a/arch/riscv/kvm/vcpu_sbi.c
+++ b/arch/riscv/kvm/vcpu_sbi.c
@@ -79,6 +79,23 @@ void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run)
run->riscv_sbi.ret[1] = cp->a1;
}
+void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu,
+ struct kvm_run *run,
+ u32 type, u64 flags)
+{
+ unsigned long i;
+ struct kvm_vcpu *tmp;
+
+ kvm_for_each_vcpu(i, tmp, vcpu->kvm)
+ tmp->arch.power_off = true;
+ kvm_make_all_cpus_request(vcpu->kvm, KVM_REQ_SLEEP);
+
+ memset(&run->system_event, 0, sizeof(run->system_event));
+ run->system_event.type = type;
+ run->system_event.flags = flags;
+ run->exit_reason = KVM_EXIT_SYSTEM_EVENT;
+}
+
int kvm_riscv_vcpu_sbi_return(struct kvm_vcpu *vcpu, struct kvm_run *run)
{
struct kvm_cpu_context *cp = &vcpu->arch.guest_context;
diff --git a/arch/riscv/kvm/vcpu_sbi_v01.c b/arch/riscv/kvm/vcpu_sbi_v01.c
index 2ab52b6d9ed3..da4d6c99c2cf 100644
--- a/arch/riscv/kvm/vcpu_sbi_v01.c
+++ b/arch/riscv/kvm/vcpu_sbi_v01.c
@@ -14,21 +14,6 @@
#include <asm/kvm_vcpu_timer.h>
#include <asm/kvm_vcpu_sbi.h>
-static void kvm_sbi_system_shutdown(struct kvm_vcpu *vcpu,
- struct kvm_run *run, u32 type)
-{
- unsigned long i;
- struct kvm_vcpu *tmp;
-
- kvm_for_each_vcpu(i, tmp, vcpu->kvm)
- tmp->arch.power_off = true;
- kvm_make_all_cpus_request(vcpu->kvm, KVM_REQ_SLEEP);
-
- memset(&run->system_event, 0, sizeof(run->system_event));
- run->system_event.type = type;
- run->exit_reason = KVM_EXIT_SYSTEM_EVENT;
-}
-
static int kvm_sbi_ext_v01_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
unsigned long *out_val,
struct kvm_cpu_trap *utrap,
@@ -80,7 +65,8 @@ static int kvm_sbi_ext_v01_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
}
break;
case SBI_EXT_0_1_SHUTDOWN:
- kvm_sbi_system_shutdown(vcpu, run, KVM_SYSTEM_EVENT_SHUTDOWN);
+ kvm_riscv_vcpu_sbi_system_reset(vcpu, run,
+ KVM_SYSTEM_EVENT_SHUTDOWN, 0);
*exit = true;
break;
case SBI_EXT_0_1_REMOTE_FENCE_I:
--
2.25.1
The SBI v0.3 specification extends SBI HSM extension by adding SBI HSM
suspend call and related HART states. This patch extends the KVM RISC-V
HSM implementation to provide KVM guest a minimal SBI HSM suspend call
which is equivalent to a WFI instruction.
Signed-off-by: Anup Patel <[email protected]>
---
arch/riscv/kvm/vcpu_sbi_hsm.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/arch/riscv/kvm/vcpu_sbi_hsm.c b/arch/riscv/kvm/vcpu_sbi_hsm.c
index 1ac4b2e8e4ec..239dec0a628a 100644
--- a/arch/riscv/kvm/vcpu_sbi_hsm.c
+++ b/arch/riscv/kvm/vcpu_sbi_hsm.c
@@ -61,6 +61,8 @@ static int kvm_sbi_hsm_vcpu_get_status(struct kvm_vcpu *vcpu)
return -EINVAL;
if (!target_vcpu->arch.power_off)
return SBI_HSM_STATE_STARTED;
+ else if (vcpu->stat.generic.blocking)
+ return SBI_HSM_STATE_SUSPENDED;
else
return SBI_HSM_STATE_STOPPED;
}
@@ -91,6 +93,18 @@ static int kvm_sbi_ext_hsm_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
ret = 0;
}
break;
+ case SBI_EXT_HSM_HART_SUSPEND:
+ switch (cp->a0) {
+ case SBI_HSM_SUSPEND_RET_DEFAULT:
+ kvm_riscv_vcpu_wfi(vcpu);
+ break;
+ case SBI_HSM_SUSPEND_NON_RET_DEFAULT:
+ ret = -EOPNOTSUPP;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ break;
default:
ret = -EOPNOTSUPP;
}
--
2.25.1
We add defines related to SBI HSM suspend call and also update HSM states
naming as-per the latest SBI specification.
Signed-off-by: Anup Patel <[email protected]>
---
arch/riscv/include/asm/sbi.h | 27 ++++++++++++++++++++++-----
arch/riscv/kernel/cpu_ops_sbi.c | 2 +-
arch/riscv/kvm/vcpu_sbi_hsm.c | 4 ++--
3 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index d1c37479d828..06133b4f8e20 100644
--- a/arch/riscv/include/asm/sbi.h
+++ b/arch/riscv/include/asm/sbi.h
@@ -71,15 +71,32 @@ enum sbi_ext_hsm_fid {
SBI_EXT_HSM_HART_START = 0,
SBI_EXT_HSM_HART_STOP,
SBI_EXT_HSM_HART_STATUS,
+ SBI_EXT_HSM_HART_SUSPEND,
};
-enum sbi_hsm_hart_status {
- SBI_HSM_HART_STATUS_STARTED = 0,
- SBI_HSM_HART_STATUS_STOPPED,
- SBI_HSM_HART_STATUS_START_PENDING,
- SBI_HSM_HART_STATUS_STOP_PENDING,
+enum sbi_hsm_hart_state {
+ SBI_HSM_STATE_STARTED = 0,
+ SBI_HSM_STATE_STOPPED,
+ SBI_HSM_STATE_START_PENDING,
+ SBI_HSM_STATE_STOP_PENDING,
+ SBI_HSM_STATE_SUSPENDED,
+ SBI_HSM_STATE_SUSPEND_PENDING,
+ SBI_HSM_STATE_RESUME_PENDING,
};
+#define SBI_HSM_SUSP_BASE_MASK 0x7fffffff
+#define SBI_HSM_SUSP_NON_RET_BIT 0x80000000
+#define SBI_HSM_SUSP_PLAT_BASE 0x10000000
+
+#define SBI_HSM_SUSPEND_RET_DEFAULT 0x00000000
+#define SBI_HSM_SUSPEND_RET_PLATFORM SBI_HSM_SUSP_PLAT_BASE
+#define SBI_HSM_SUSPEND_RET_LAST SBI_HSM_SUSP_BASE_MASK
+#define SBI_HSM_SUSPEND_NON_RET_DEFAULT SBI_HSM_SUSP_NON_RET_BIT
+#define SBI_HSM_SUSPEND_NON_RET_PLATFORM (SBI_HSM_SUSP_NON_RET_BIT | \
+ SBI_HSM_SUSP_PLAT_BASE)
+#define SBI_HSM_SUSPEND_NON_RET_LAST (SBI_HSM_SUSP_NON_RET_BIT | \
+ SBI_HSM_SUSP_BASE_MASK)
+
enum sbi_ext_srst_fid {
SBI_EXT_SRST_RESET = 0,
};
diff --git a/arch/riscv/kernel/cpu_ops_sbi.c b/arch/riscv/kernel/cpu_ops_sbi.c
index dae29cbfe550..2e16f6732cdf 100644
--- a/arch/riscv/kernel/cpu_ops_sbi.c
+++ b/arch/riscv/kernel/cpu_ops_sbi.c
@@ -111,7 +111,7 @@ static int sbi_cpu_is_stopped(unsigned int cpuid)
rc = sbi_hsm_hart_get_status(hartid);
- if (rc == SBI_HSM_HART_STATUS_STOPPED)
+ if (rc == SBI_HSM_STATE_STOPPED)
return 0;
return rc;
}
diff --git a/arch/riscv/kvm/vcpu_sbi_hsm.c b/arch/riscv/kvm/vcpu_sbi_hsm.c
index 2e383687fa48..1ac4b2e8e4ec 100644
--- a/arch/riscv/kvm/vcpu_sbi_hsm.c
+++ b/arch/riscv/kvm/vcpu_sbi_hsm.c
@@ -60,9 +60,9 @@ static int kvm_sbi_hsm_vcpu_get_status(struct kvm_vcpu *vcpu)
if (!target_vcpu)
return -EINVAL;
if (!target_vcpu->arch.power_off)
- return SBI_HSM_HART_STATUS_STARTED;
+ return SBI_HSM_STATE_STARTED;
else
- return SBI_HSM_HART_STATUS_STOPPED;
+ return SBI_HSM_STATE_STOPPED;
}
static int kvm_sbi_ext_hsm_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
--
2.25.1
The wait for interrupt (WFI) instruction emulation can share the VCPU
halt logic with SBI HSM suspend emulation so this patch adds a common
kvm_riscv_vcpu_wfi() function for this purpose.
Signed-off-by: Anup Patel <[email protected]>
---
arch/riscv/include/asm/kvm_host.h | 1 +
arch/riscv/kvm/vcpu_exit.c | 22 ++++++++++++++++------
2 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm_host.h
index 99ef6a120617..78da839657e5 100644
--- a/arch/riscv/include/asm/kvm_host.h
+++ b/arch/riscv/include/asm/kvm_host.h
@@ -228,6 +228,7 @@ void kvm_riscv_stage2_vmid_update(struct kvm_vcpu *vcpu);
void __kvm_riscv_unpriv_trap(void);
+void kvm_riscv_vcpu_wfi(struct kvm_vcpu *vcpu);
unsigned long kvm_riscv_vcpu_unpriv_read(struct kvm_vcpu *vcpu,
bool read_insn,
unsigned long guest_addr,
diff --git a/arch/riscv/kvm/vcpu_exit.c b/arch/riscv/kvm/vcpu_exit.c
index 571f319e995a..aa8af129e4bb 100644
--- a/arch/riscv/kvm/vcpu_exit.c
+++ b/arch/riscv/kvm/vcpu_exit.c
@@ -144,12 +144,7 @@ static int system_opcode_insn(struct kvm_vcpu *vcpu,
{
if ((insn & INSN_MASK_WFI) == INSN_MATCH_WFI) {
vcpu->stat.wfi_exit_stat++;
- if (!kvm_arch_vcpu_runnable(vcpu)) {
- srcu_read_unlock(&vcpu->kvm->srcu, vcpu->arch.srcu_idx);
- kvm_vcpu_halt(vcpu);
- vcpu->arch.srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
- kvm_clear_request(KVM_REQ_UNHALT, vcpu);
- }
+ kvm_riscv_vcpu_wfi(vcpu);
vcpu->arch.guest_context.sepc += INSN_LEN(insn);
return 1;
}
@@ -453,6 +448,21 @@ static int stage2_page_fault(struct kvm_vcpu *vcpu, struct kvm_run *run,
return 1;
}
+/**
+ * kvm_riscv_vcpu_wfi -- Emulate wait for interrupt (WFI) behaviour
+ *
+ * @vcpu: The VCPU pointer
+ */
+void kvm_riscv_vcpu_wfi(struct kvm_vcpu *vcpu)
+{
+ if (!kvm_arch_vcpu_runnable(vcpu)) {
+ srcu_read_unlock(&vcpu->kvm->srcu, vcpu->arch.srcu_idx);
+ kvm_vcpu_halt(vcpu);
+ vcpu->arch.srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
+ kvm_clear_request(KVM_REQ_UNHALT, vcpu);
+ }
+}
+
/**
* kvm_riscv_vcpu_unpriv_read -- Read machine word from Guest memory
*
--
2.25.1
The SBI v0.3 specification defines SRST (System Reset) extension which
provides a standard poweroff and reboot interface. This patch implements
SRST extension for the KVM Guest.
Signed-off-by: Anup Patel <[email protected]>
---
arch/riscv/kvm/vcpu_sbi.c | 2 ++
arch/riscv/kvm/vcpu_sbi_replace.c | 44 +++++++++++++++++++++++++++++++
2 files changed, 46 insertions(+)
diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c
index 11ae4f621f0d..a09ecb97b890 100644
--- a/arch/riscv/kvm/vcpu_sbi.c
+++ b/arch/riscv/kvm/vcpu_sbi.c
@@ -45,6 +45,7 @@ extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_base;
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_time;
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_ipi;
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_experimental;
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_vendor;
@@ -55,6 +56,7 @@ static const struct kvm_vcpu_sbi_extension *sbi_ext[] = {
&vcpu_sbi_ext_time,
&vcpu_sbi_ext_ipi,
&vcpu_sbi_ext_rfence,
+ &vcpu_sbi_ext_srst,
&vcpu_sbi_ext_hsm,
&vcpu_sbi_ext_experimental,
&vcpu_sbi_ext_vendor,
diff --git a/arch/riscv/kvm/vcpu_sbi_replace.c b/arch/riscv/kvm/vcpu_sbi_replace.c
index 1bc0608a5bfd..0f217365c287 100644
--- a/arch/riscv/kvm/vcpu_sbi_replace.c
+++ b/arch/riscv/kvm/vcpu_sbi_replace.c
@@ -130,3 +130,47 @@ const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_rfence = {
.extid_end = SBI_EXT_RFENCE,
.handler = kvm_sbi_ext_rfence_handler,
};
+
+static int kvm_sbi_ext_srst_handler(struct kvm_vcpu *vcpu,
+ struct kvm_run *run,
+ unsigned long *out_val,
+ struct kvm_cpu_trap *utrap, bool *exit)
+{
+ struct kvm_cpu_context *cp = &vcpu->arch.guest_context;
+ unsigned long funcid = cp->a6;
+ u32 reason = cp->a1;
+ u32 type = cp->a0;
+ int ret = 0;
+
+ switch (funcid) {
+ case SBI_EXT_SRST_RESET:
+ switch (type) {
+ case SBI_SRST_RESET_TYPE_SHUTDOWN:
+ kvm_riscv_vcpu_sbi_system_reset(vcpu, run,
+ KVM_SYSTEM_EVENT_SHUTDOWN,
+ reason);
+ *exit = true;
+ break;
+ case SBI_SRST_RESET_TYPE_COLD_REBOOT:
+ case SBI_SRST_RESET_TYPE_WARM_REBOOT:
+ kvm_riscv_vcpu_sbi_system_reset(vcpu, run,
+ KVM_SYSTEM_EVENT_RESET,
+ reason);
+ *exit = true;
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ }
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ }
+
+ return ret;
+}
+
+const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_srst = {
+ .extid_start = SBI_EXT_SRST,
+ .extid_end = SBI_EXT_SRST,
+ .handler = kvm_sbi_ext_srst_handler,
+};
--
2.25.1
On Tue, Feb 1, 2022 at 12:23 AM Anup Patel <[email protected]> wrote:
>
> We upgrade SBI spec version implemented by KVM RISC-V to v0.3 so
> that Guest kernel can probe and use SBI extensions added by the
> SBI v0.3 specification.
>
> Signed-off-by: Anup Patel <[email protected]>
> ---
> arch/riscv/include/asm/kvm_vcpu_sbi.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/riscv/include/asm/kvm_vcpu_sbi.h b/arch/riscv/include/asm/kvm_vcpu_sbi.h
> index 76e4e17a3e00..04cd81f2ab5b 100644
> --- a/arch/riscv/include/asm/kvm_vcpu_sbi.h
> +++ b/arch/riscv/include/asm/kvm_vcpu_sbi.h
> @@ -12,7 +12,7 @@
> #define KVM_SBI_IMPID 3
>
> #define KVM_SBI_VERSION_MAJOR 0
> -#define KVM_SBI_VERSION_MINOR 2
> +#define KVM_SBI_VERSION_MINOR 3
>
> struct kvm_vcpu_sbi_extension {
> unsigned long extid_start;
> --
> 2.25.1
>
Reviewed-by: Atish Patra <[email protected]>
--
Regards,
Atish
On Tue, Feb 1, 2022 at 12:23 AM Anup Patel <[email protected]> wrote:
>
> We rename kvm_sbi_system_shutdown() to kvm_riscv_vcpu_sbi_system_reset()
> and move it to vcpu_sbi.c so that it can be shared by SBI v0.1 shutdown
> and SBI v0.3 SRST extension.
>
> Signed-off-by: Anup Patel <[email protected]>
> ---
> arch/riscv/include/asm/kvm_vcpu_sbi.h | 3 +++
> arch/riscv/kvm/vcpu_sbi.c | 17 +++++++++++++++++
> arch/riscv/kvm/vcpu_sbi_v01.c | 18 ++----------------
> 3 files changed, 22 insertions(+), 16 deletions(-)
>
> diff --git a/arch/riscv/include/asm/kvm_vcpu_sbi.h b/arch/riscv/include/asm/kvm_vcpu_sbi.h
> index 04cd81f2ab5b..83d6d4d2b1df 100644
> --- a/arch/riscv/include/asm/kvm_vcpu_sbi.h
> +++ b/arch/riscv/include/asm/kvm_vcpu_sbi.h
> @@ -28,6 +28,9 @@ struct kvm_vcpu_sbi_extension {
> };
>
> void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run);
> +void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu,
> + struct kvm_run *run,
> + u32 type, u64 flags);
> const struct kvm_vcpu_sbi_extension *kvm_vcpu_sbi_find_ext(unsigned long extid);
>
> #endif /* __RISCV_KVM_VCPU_SBI_H__ */
> diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c
> index 78aa3db76225..11ae4f621f0d 100644
> --- a/arch/riscv/kvm/vcpu_sbi.c
> +++ b/arch/riscv/kvm/vcpu_sbi.c
> @@ -79,6 +79,23 @@ void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run)
> run->riscv_sbi.ret[1] = cp->a1;
> }
>
> +void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu,
> + struct kvm_run *run,
> + u32 type, u64 flags)
> +{
> + unsigned long i;
> + struct kvm_vcpu *tmp;
> +
> + kvm_for_each_vcpu(i, tmp, vcpu->kvm)
> + tmp->arch.power_off = true;
> + kvm_make_all_cpus_request(vcpu->kvm, KVM_REQ_SLEEP);
> +
> + memset(&run->system_event, 0, sizeof(run->system_event));
> + run->system_event.type = type;
> + run->system_event.flags = flags;
> + run->exit_reason = KVM_EXIT_SYSTEM_EVENT;
> +}
> +
> int kvm_riscv_vcpu_sbi_return(struct kvm_vcpu *vcpu, struct kvm_run *run)
> {
> struct kvm_cpu_context *cp = &vcpu->arch.guest_context;
> diff --git a/arch/riscv/kvm/vcpu_sbi_v01.c b/arch/riscv/kvm/vcpu_sbi_v01.c
> index 2ab52b6d9ed3..da4d6c99c2cf 100644
> --- a/arch/riscv/kvm/vcpu_sbi_v01.c
> +++ b/arch/riscv/kvm/vcpu_sbi_v01.c
> @@ -14,21 +14,6 @@
> #include <asm/kvm_vcpu_timer.h>
> #include <asm/kvm_vcpu_sbi.h>
>
> -static void kvm_sbi_system_shutdown(struct kvm_vcpu *vcpu,
> - struct kvm_run *run, u32 type)
> -{
> - unsigned long i;
> - struct kvm_vcpu *tmp;
> -
> - kvm_for_each_vcpu(i, tmp, vcpu->kvm)
> - tmp->arch.power_off = true;
> - kvm_make_all_cpus_request(vcpu->kvm, KVM_REQ_SLEEP);
> -
> - memset(&run->system_event, 0, sizeof(run->system_event));
> - run->system_event.type = type;
> - run->exit_reason = KVM_EXIT_SYSTEM_EVENT;
> -}
> -
> static int kvm_sbi_ext_v01_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
> unsigned long *out_val,
> struct kvm_cpu_trap *utrap,
> @@ -80,7 +65,8 @@ static int kvm_sbi_ext_v01_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
> }
> break;
> case SBI_EXT_0_1_SHUTDOWN:
> - kvm_sbi_system_shutdown(vcpu, run, KVM_SYSTEM_EVENT_SHUTDOWN);
> + kvm_riscv_vcpu_sbi_system_reset(vcpu, run,
> + KVM_SYSTEM_EVENT_SHUTDOWN, 0);
> *exit = true;
> break;
> case SBI_EXT_0_1_REMOTE_FENCE_I:
> --
> 2.25.1
>
Reviewed-by: Atish Patra <[email protected]>
--
Regards,
Atish
On Tue, Feb 1, 2022 at 12:23 AM Anup Patel <[email protected]> wrote:
>
> We add defines related to SBI HSM suspend call and also update HSM states
> naming as-per the latest SBI specification.
>
> Signed-off-by: Anup Patel <[email protected]>
> ---
> arch/riscv/include/asm/sbi.h | 27 ++++++++++++++++++++++-----
> arch/riscv/kernel/cpu_ops_sbi.c | 2 +-
> arch/riscv/kvm/vcpu_sbi_hsm.c | 4 ++--
> 3 files changed, 25 insertions(+), 8 deletions(-)
>
> diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
> index d1c37479d828..06133b4f8e20 100644
> --- a/arch/riscv/include/asm/sbi.h
> +++ b/arch/riscv/include/asm/sbi.h
> @@ -71,15 +71,32 @@ enum sbi_ext_hsm_fid {
> SBI_EXT_HSM_HART_START = 0,
> SBI_EXT_HSM_HART_STOP,
> SBI_EXT_HSM_HART_STATUS,
> + SBI_EXT_HSM_HART_SUSPEND,
> };
>
> -enum sbi_hsm_hart_status {
> - SBI_HSM_HART_STATUS_STARTED = 0,
> - SBI_HSM_HART_STATUS_STOPPED,
> - SBI_HSM_HART_STATUS_START_PENDING,
> - SBI_HSM_HART_STATUS_STOP_PENDING,
> +enum sbi_hsm_hart_state {
> + SBI_HSM_STATE_STARTED = 0,
> + SBI_HSM_STATE_STOPPED,
> + SBI_HSM_STATE_START_PENDING,
> + SBI_HSM_STATE_STOP_PENDING,
> + SBI_HSM_STATE_SUSPENDED,
> + SBI_HSM_STATE_SUSPEND_PENDING,
> + SBI_HSM_STATE_RESUME_PENDING,
> };
>
> +#define SBI_HSM_SUSP_BASE_MASK 0x7fffffff
> +#define SBI_HSM_SUSP_NON_RET_BIT 0x80000000
> +#define SBI_HSM_SUSP_PLAT_BASE 0x10000000
> +
> +#define SBI_HSM_SUSPEND_RET_DEFAULT 0x00000000
> +#define SBI_HSM_SUSPEND_RET_PLATFORM SBI_HSM_SUSP_PLAT_BASE
> +#define SBI_HSM_SUSPEND_RET_LAST SBI_HSM_SUSP_BASE_MASK
> +#define SBI_HSM_SUSPEND_NON_RET_DEFAULT SBI_HSM_SUSP_NON_RET_BIT
> +#define SBI_HSM_SUSPEND_NON_RET_PLATFORM (SBI_HSM_SUSP_NON_RET_BIT | \
> + SBI_HSM_SUSP_PLAT_BASE)
> +#define SBI_HSM_SUSPEND_NON_RET_LAST (SBI_HSM_SUSP_NON_RET_BIT | \
> + SBI_HSM_SUSP_BASE_MASK)
> +
> enum sbi_ext_srst_fid {
> SBI_EXT_SRST_RESET = 0,
> };
> diff --git a/arch/riscv/kernel/cpu_ops_sbi.c b/arch/riscv/kernel/cpu_ops_sbi.c
> index dae29cbfe550..2e16f6732cdf 100644
> --- a/arch/riscv/kernel/cpu_ops_sbi.c
> +++ b/arch/riscv/kernel/cpu_ops_sbi.c
> @@ -111,7 +111,7 @@ static int sbi_cpu_is_stopped(unsigned int cpuid)
>
> rc = sbi_hsm_hart_get_status(hartid);
>
> - if (rc == SBI_HSM_HART_STATUS_STOPPED)
> + if (rc == SBI_HSM_STATE_STOPPED)
> return 0;
> return rc;
> }
> diff --git a/arch/riscv/kvm/vcpu_sbi_hsm.c b/arch/riscv/kvm/vcpu_sbi_hsm.c
> index 2e383687fa48..1ac4b2e8e4ec 100644
> --- a/arch/riscv/kvm/vcpu_sbi_hsm.c
> +++ b/arch/riscv/kvm/vcpu_sbi_hsm.c
> @@ -60,9 +60,9 @@ static int kvm_sbi_hsm_vcpu_get_status(struct kvm_vcpu *vcpu)
> if (!target_vcpu)
> return -EINVAL;
> if (!target_vcpu->arch.power_off)
> - return SBI_HSM_HART_STATUS_STARTED;
> + return SBI_HSM_STATE_STARTED;
> else
> - return SBI_HSM_HART_STATUS_STOPPED;
> + return SBI_HSM_STATE_STOPPED;
> }
>
> static int kvm_sbi_ext_hsm_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
> --
> 2.25.1
>
Reviewed-by: Atish Patra <[email protected]>
--
Regards,
Atish
On Tue, Feb 1, 2022 at 12:23 AM Anup Patel <[email protected]> wrote:
>
> The SBI v0.3 specification defines SRST (System Reset) extension which
> provides a standard poweroff and reboot interface. This patch implements
> SRST extension for the KVM Guest.
>
> Signed-off-by: Anup Patel <[email protected]>
> ---
> arch/riscv/kvm/vcpu_sbi.c | 2 ++
> arch/riscv/kvm/vcpu_sbi_replace.c | 44 +++++++++++++++++++++++++++++++
> 2 files changed, 46 insertions(+)
>
> diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c
> index 11ae4f621f0d..a09ecb97b890 100644
> --- a/arch/riscv/kvm/vcpu_sbi.c
> +++ b/arch/riscv/kvm/vcpu_sbi.c
> @@ -45,6 +45,7 @@ extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_base;
> extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_time;
> extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_ipi;
> 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_experimental;
> extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_vendor;
> @@ -55,6 +56,7 @@ static const struct kvm_vcpu_sbi_extension *sbi_ext[] = {
> &vcpu_sbi_ext_time,
> &vcpu_sbi_ext_ipi,
> &vcpu_sbi_ext_rfence,
> + &vcpu_sbi_ext_srst,
> &vcpu_sbi_ext_hsm,
> &vcpu_sbi_ext_experimental,
> &vcpu_sbi_ext_vendor,
> diff --git a/arch/riscv/kvm/vcpu_sbi_replace.c b/arch/riscv/kvm/vcpu_sbi_replace.c
> index 1bc0608a5bfd..0f217365c287 100644
> --- a/arch/riscv/kvm/vcpu_sbi_replace.c
> +++ b/arch/riscv/kvm/vcpu_sbi_replace.c
> @@ -130,3 +130,47 @@ const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_rfence = {
> .extid_end = SBI_EXT_RFENCE,
> .handler = kvm_sbi_ext_rfence_handler,
> };
> +
> +static int kvm_sbi_ext_srst_handler(struct kvm_vcpu *vcpu,
> + struct kvm_run *run,
> + unsigned long *out_val,
> + struct kvm_cpu_trap *utrap, bool *exit)
> +{
> + struct kvm_cpu_context *cp = &vcpu->arch.guest_context;
> + unsigned long funcid = cp->a6;
> + u32 reason = cp->a1;
> + u32 type = cp->a0;
> + int ret = 0;
> +
> + switch (funcid) {
> + case SBI_EXT_SRST_RESET:
> + switch (type) {
> + case SBI_SRST_RESET_TYPE_SHUTDOWN:
> + kvm_riscv_vcpu_sbi_system_reset(vcpu, run,
> + KVM_SYSTEM_EVENT_SHUTDOWN,
> + reason);
> + *exit = true;
> + break;
> + case SBI_SRST_RESET_TYPE_COLD_REBOOT:
> + case SBI_SRST_RESET_TYPE_WARM_REBOOT:
> + kvm_riscv_vcpu_sbi_system_reset(vcpu, run,
> + KVM_SYSTEM_EVENT_RESET,
> + reason);
> + *exit = true;
> + break;
> + default:
> + ret = -EOPNOTSUPP;
> + }
> + break;
> + default:
> + ret = -EOPNOTSUPP;
> + }
> +
> + return ret;
> +}
> +
> +const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_srst = {
> + .extid_start = SBI_EXT_SRST,
> + .extid_end = SBI_EXT_SRST,
> + .handler = kvm_sbi_ext_srst_handler,
> +};
> --
> 2.25.1
>
Reviewed-by: Atish Patra <[email protected]>
--
Regards,
Atish
On Tue, Feb 1, 2022 at 12:24 AM Anup Patel <[email protected]> wrote:
>
> The SBI v0.3 specification extends SBI HSM extension by adding SBI HSM
> suspend call and related HART states. This patch extends the KVM RISC-V
> HSM implementation to provide KVM guest a minimal SBI HSM suspend call
> which is equivalent to a WFI instruction.
>
> Signed-off-by: Anup Patel <[email protected]>
> ---
> arch/riscv/kvm/vcpu_sbi_hsm.c | 14 ++++++++++++++
> 1 file changed, 14 insertions(+)
>
> diff --git a/arch/riscv/kvm/vcpu_sbi_hsm.c b/arch/riscv/kvm/vcpu_sbi_hsm.c
> index 1ac4b2e8e4ec..239dec0a628a 100644
> --- a/arch/riscv/kvm/vcpu_sbi_hsm.c
> +++ b/arch/riscv/kvm/vcpu_sbi_hsm.c
> @@ -61,6 +61,8 @@ static int kvm_sbi_hsm_vcpu_get_status(struct kvm_vcpu *vcpu)
> return -EINVAL;
> if (!target_vcpu->arch.power_off)
> return SBI_HSM_STATE_STARTED;
> + else if (vcpu->stat.generic.blocking)
> + return SBI_HSM_STATE_SUSPENDED;
> else
> return SBI_HSM_STATE_STOPPED;
> }
> @@ -91,6 +93,18 @@ static int kvm_sbi_ext_hsm_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
> ret = 0;
> }
> break;
> + case SBI_EXT_HSM_HART_SUSPEND:
> + switch (cp->a0) {
> + case SBI_HSM_SUSPEND_RET_DEFAULT:
> + kvm_riscv_vcpu_wfi(vcpu);
> + break;
> + case SBI_HSM_SUSPEND_NON_RET_DEFAULT:
> + ret = -EOPNOTSUPP;
> + break;
> + default:
> + ret = -EINVAL;
> + }
> + break;
> default:
> ret = -EOPNOTSUPP;
> }
> --
> 2.25.1
>
Reviewed-by: Atish Patra <[email protected]>
--
Regards,
Atish
On Tue, Feb 1, 2022 at 12:24 AM Anup Patel <[email protected]> wrote:
>
> The wait for interrupt (WFI) instruction emulation can share the VCPU
> halt logic with SBI HSM suspend emulation so this patch adds a common
> kvm_riscv_vcpu_wfi() function for this purpose.
>
> Signed-off-by: Anup Patel <[email protected]>
> ---
> arch/riscv/include/asm/kvm_host.h | 1 +
> arch/riscv/kvm/vcpu_exit.c | 22 ++++++++++++++++------
> 2 files changed, 17 insertions(+), 6 deletions(-)
>
> diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm_host.h
> index 99ef6a120617..78da839657e5 100644
> --- a/arch/riscv/include/asm/kvm_host.h
> +++ b/arch/riscv/include/asm/kvm_host.h
> @@ -228,6 +228,7 @@ void kvm_riscv_stage2_vmid_update(struct kvm_vcpu *vcpu);
>
> void __kvm_riscv_unpriv_trap(void);
>
> +void kvm_riscv_vcpu_wfi(struct kvm_vcpu *vcpu);
> unsigned long kvm_riscv_vcpu_unpriv_read(struct kvm_vcpu *vcpu,
> bool read_insn,
> unsigned long guest_addr,
> diff --git a/arch/riscv/kvm/vcpu_exit.c b/arch/riscv/kvm/vcpu_exit.c
> index 571f319e995a..aa8af129e4bb 100644
> --- a/arch/riscv/kvm/vcpu_exit.c
> +++ b/arch/riscv/kvm/vcpu_exit.c
> @@ -144,12 +144,7 @@ static int system_opcode_insn(struct kvm_vcpu *vcpu,
> {
> if ((insn & INSN_MASK_WFI) == INSN_MATCH_WFI) {
> vcpu->stat.wfi_exit_stat++;
> - if (!kvm_arch_vcpu_runnable(vcpu)) {
> - srcu_read_unlock(&vcpu->kvm->srcu, vcpu->arch.srcu_idx);
> - kvm_vcpu_halt(vcpu);
> - vcpu->arch.srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
> - kvm_clear_request(KVM_REQ_UNHALT, vcpu);
> - }
> + kvm_riscv_vcpu_wfi(vcpu);
> vcpu->arch.guest_context.sepc += INSN_LEN(insn);
> return 1;
> }
> @@ -453,6 +448,21 @@ static int stage2_page_fault(struct kvm_vcpu *vcpu, struct kvm_run *run,
> return 1;
> }
>
> +/**
> + * kvm_riscv_vcpu_wfi -- Emulate wait for interrupt (WFI) behaviour
> + *
> + * @vcpu: The VCPU pointer
> + */
> +void kvm_riscv_vcpu_wfi(struct kvm_vcpu *vcpu)
> +{
> + if (!kvm_arch_vcpu_runnable(vcpu)) {
> + srcu_read_unlock(&vcpu->kvm->srcu, vcpu->arch.srcu_idx);
> + kvm_vcpu_halt(vcpu);
> + vcpu->arch.srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
> + kvm_clear_request(KVM_REQ_UNHALT, vcpu);
> + }
> +}
> +
> /**
> * kvm_riscv_vcpu_unpriv_read -- Read machine word from Guest memory
> *
> --
> 2.25.1
>
Reviewed-by: Atish Patra <[email protected]>
--
Regards,
Atish
On Tue, Feb 1, 2022 at 1:53 PM Anup Patel <[email protected]> wrote:
>
> This series adds initial support for SBI v0.3 which includes:
> 1) SBI SRST support for Guest
> 2) SBI HSM suspend for Guest
>
> The SBI PMU support is intentionally left out and will be added as
> a separate patch series.
>
> These patches can also be found in riscv_kvm_sbi_v03_v1 branch at:
> https://github.com/avpatel/linux.git
Queued this series for Linux-5.18
Thanks,
Anup
>
> Anup Patel (6):
> RISC-V: KVM: Upgrade SBI spec version to v0.3
> RISC-V: KVM: Add common kvm_riscv_vcpu_sbi_system_reset() function
> RISC-V: KVM: Implement SBI v0.3 SRST extension
> RISC-V: Add SBI HSM suspend related defines
> RISC-V: KVM: Add common kvm_riscv_vcpu_wfi() function
> RISC-V: KVM: Implement SBI HSM suspend call
>
> arch/riscv/include/asm/kvm_host.h | 1 +
> arch/riscv/include/asm/kvm_vcpu_sbi.h | 5 ++-
> arch/riscv/include/asm/sbi.h | 27 +++++++++++++---
> arch/riscv/kernel/cpu_ops_sbi.c | 2 +-
> arch/riscv/kvm/vcpu_exit.c | 22 ++++++++++----
> arch/riscv/kvm/vcpu_sbi.c | 19 ++++++++++++
> arch/riscv/kvm/vcpu_sbi_hsm.c | 18 +++++++++--
> arch/riscv/kvm/vcpu_sbi_replace.c | 44 +++++++++++++++++++++++++++
> arch/riscv/kvm/vcpu_sbi_v01.c | 18 ++---------
> 9 files changed, 125 insertions(+), 31 deletions(-)
>
> --
> 2.25.1
>