1c62a7685SAtish Patra // SPDX-License-Identifier: GPL-2.0 2c62a7685SAtish Patra /* 3c62a7685SAtish Patra * Copyright (c) 2021 Western Digital Corporation or its affiliates. 4c62a7685SAtish Patra * 5c62a7685SAtish Patra * Authors: 6c62a7685SAtish Patra * Atish Patra <atish.patra@wdc.com> 7c62a7685SAtish Patra */ 8c62a7685SAtish Patra 9c62a7685SAtish Patra #include <linux/errno.h> 10c62a7685SAtish Patra #include <linux/err.h> 11c62a7685SAtish Patra #include <linux/kvm_host.h> 1240327154SAnup Patel #include <linux/version.h> 13c62a7685SAtish Patra #include <asm/sbi.h> 14c62a7685SAtish Patra #include <asm/kvm_vcpu_sbi.h> 15c62a7685SAtish Patra 16c62a7685SAtish Patra static int kvm_sbi_ext_base_handler(struct kvm_vcpu *vcpu, struct kvm_run *run, 17c62a7685SAtish Patra unsigned long *out_val, 18c62a7685SAtish Patra struct kvm_cpu_trap *trap, bool *exit) 19c62a7685SAtish Patra { 20c62a7685SAtish Patra int ret = 0; 21c62a7685SAtish Patra struct kvm_cpu_context *cp = &vcpu->arch.guest_context; 22c62a7685SAtish Patra 23c62a7685SAtish Patra switch (cp->a6) { 24c62a7685SAtish Patra case SBI_EXT_BASE_GET_SPEC_VERSION: 25c62a7685SAtish Patra *out_val = (KVM_SBI_VERSION_MAJOR << 26c62a7685SAtish Patra SBI_SPEC_VERSION_MAJOR_SHIFT) | 27c62a7685SAtish Patra KVM_SBI_VERSION_MINOR; 28c62a7685SAtish Patra break; 29c62a7685SAtish Patra case SBI_EXT_BASE_GET_IMP_ID: 30c62a7685SAtish Patra *out_val = KVM_SBI_IMPID; 31c62a7685SAtish Patra break; 32c62a7685SAtish Patra case SBI_EXT_BASE_GET_IMP_VERSION: 3340327154SAnup Patel *out_val = LINUX_VERSION_CODE; 34c62a7685SAtish Patra break; 35c62a7685SAtish Patra case SBI_EXT_BASE_PROBE_EXT: 36c62a7685SAtish Patra if ((cp->a0 >= SBI_EXT_EXPERIMENTAL_START && 37c62a7685SAtish Patra cp->a0 <= SBI_EXT_EXPERIMENTAL_END) || 38c62a7685SAtish Patra (cp->a0 >= SBI_EXT_VENDOR_START && 39c62a7685SAtish Patra cp->a0 <= SBI_EXT_VENDOR_END)) { 40c62a7685SAtish Patra /* 41c62a7685SAtish Patra * For experimental/vendor extensions 42c62a7685SAtish Patra * forward it to the userspace 43c62a7685SAtish Patra */ 44c62a7685SAtish Patra kvm_riscv_vcpu_sbi_forward(vcpu, run); 45c62a7685SAtish Patra *exit = true; 46c62a7685SAtish Patra } else 47c62a7685SAtish Patra *out_val = kvm_vcpu_sbi_find_ext(cp->a0) ? 1 : 0; 48c62a7685SAtish Patra break; 49c62a7685SAtish Patra case SBI_EXT_BASE_GET_MVENDORID: 50*52ec4b69SAnup Patel *out_val = vcpu->arch.mvendorid; 51*52ec4b69SAnup Patel break; 52c62a7685SAtish Patra case SBI_EXT_BASE_GET_MARCHID: 53*52ec4b69SAnup Patel *out_val = vcpu->arch.marchid; 54*52ec4b69SAnup Patel break; 55c62a7685SAtish Patra case SBI_EXT_BASE_GET_MIMPID: 56*52ec4b69SAnup Patel *out_val = vcpu->arch.mimpid; 57c62a7685SAtish Patra break; 58c62a7685SAtish Patra default: 59c62a7685SAtish Patra ret = -EOPNOTSUPP; 60c62a7685SAtish Patra break; 61c62a7685SAtish Patra } 62c62a7685SAtish Patra 63c62a7685SAtish Patra return ret; 64c62a7685SAtish Patra } 65c62a7685SAtish Patra 66c62a7685SAtish Patra const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_base = { 67c62a7685SAtish Patra .extid_start = SBI_EXT_BASE, 68c62a7685SAtish Patra .extid_end = SBI_EXT_BASE, 69c62a7685SAtish Patra .handler = kvm_sbi_ext_base_handler, 70c62a7685SAtish Patra }; 71ef8949a9SAnup Patel 72ef8949a9SAnup Patel static int kvm_sbi_ext_forward_handler(struct kvm_vcpu *vcpu, 73ef8949a9SAnup Patel struct kvm_run *run, 74ef8949a9SAnup Patel unsigned long *out_val, 75ef8949a9SAnup Patel struct kvm_cpu_trap *utrap, 76ef8949a9SAnup Patel bool *exit) 77ef8949a9SAnup Patel { 78ef8949a9SAnup Patel /* 79ef8949a9SAnup Patel * Both SBI experimental and vendor extensions are 80ef8949a9SAnup Patel * unconditionally forwarded to userspace. 81ef8949a9SAnup Patel */ 82ef8949a9SAnup Patel kvm_riscv_vcpu_sbi_forward(vcpu, run); 83ef8949a9SAnup Patel *exit = true; 84ef8949a9SAnup Patel return 0; 85ef8949a9SAnup Patel } 86ef8949a9SAnup Patel 87ef8949a9SAnup Patel const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_experimental = { 88ef8949a9SAnup Patel .extid_start = SBI_EXT_EXPERIMENTAL_START, 89ef8949a9SAnup Patel .extid_end = SBI_EXT_EXPERIMENTAL_END, 90ef8949a9SAnup Patel .handler = kvm_sbi_ext_forward_handler, 91ef8949a9SAnup Patel }; 92ef8949a9SAnup Patel 93ef8949a9SAnup Patel const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_vendor = { 94ef8949a9SAnup Patel .extid_start = SBI_EXT_VENDOR_START, 95ef8949a9SAnup Patel .extid_end = SBI_EXT_VENDOR_END, 96ef8949a9SAnup Patel .handler = kvm_sbi_ext_forward_handler, 97ef8949a9SAnup Patel }; 98