Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/riscv/kvm/vcpu_sbi_system.c
26442 views
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
* Copyright (c) 2024 Ventana Micro Systems Inc.
4
*/
5
6
#include <linux/kvm_host.h>
7
#include <linux/wordpart.h>
8
9
#include <asm/kvm_vcpu_sbi.h>
10
#include <asm/sbi.h>
11
12
static int kvm_sbi_ext_susp_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
13
struct kvm_vcpu_sbi_return *retdata)
14
{
15
struct kvm_cpu_context *cp = &vcpu->arch.guest_context;
16
unsigned long funcid = cp->a6;
17
unsigned long hva, i;
18
struct kvm_vcpu *tmp;
19
20
switch (funcid) {
21
case SBI_EXT_SUSP_SYSTEM_SUSPEND:
22
if (lower_32_bits(cp->a0) != SBI_SUSP_SLEEP_TYPE_SUSPEND_TO_RAM) {
23
retdata->err_val = SBI_ERR_INVALID_PARAM;
24
return 0;
25
}
26
27
if (!(cp->sstatus & SR_SPP)) {
28
retdata->err_val = SBI_ERR_FAILURE;
29
return 0;
30
}
31
32
hva = kvm_vcpu_gfn_to_hva_prot(vcpu, cp->a1 >> PAGE_SHIFT, NULL);
33
if (kvm_is_error_hva(hva)) {
34
retdata->err_val = SBI_ERR_INVALID_ADDRESS;
35
return 0;
36
}
37
38
kvm_for_each_vcpu(i, tmp, vcpu->kvm) {
39
if (tmp == vcpu)
40
continue;
41
if (!kvm_riscv_vcpu_stopped(tmp)) {
42
retdata->err_val = SBI_ERR_DENIED;
43
return 0;
44
}
45
}
46
47
kvm_riscv_vcpu_sbi_request_reset(vcpu, cp->a1, cp->a2);
48
49
/* userspace provides the suspend implementation */
50
kvm_riscv_vcpu_sbi_forward(vcpu, run);
51
retdata->uexit = true;
52
break;
53
default:
54
retdata->err_val = SBI_ERR_NOT_SUPPORTED;
55
break;
56
}
57
58
return 0;
59
}
60
61
const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_susp = {
62
.extid_start = SBI_EXT_SUSP,
63
.extid_end = SBI_EXT_SUSP,
64
.default_disabled = true,
65
.handler = kvm_sbi_ext_susp_handler,
66
};
67
68