aboutsummaryrefslogtreecommitdiff
path: root/target/riscv/kvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/riscv/kvm.c')
-rw-r--r--target/riscv/kvm.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
index c3976a588d..7402bfbfc5 100644
--- a/target/riscv/kvm.c
+++ b/target/riscv/kvm.c
@@ -309,6 +309,91 @@ static void kvm_riscv_put_regs_timer(CPUState *cs)
env->kvm_timer_dirty = false;
}
+typedef struct KVMScratchCPU {
+ int kvmfd;
+ int vmfd;
+ int cpufd;
+} KVMScratchCPU;
+
+/*
+ * Heavily inspired by kvm_arm_create_scratch_host_vcpu()
+ * from target/arm/kvm.c.
+ */
+static bool kvm_riscv_create_scratch_vcpu(KVMScratchCPU *scratch)
+{
+ int kvmfd = -1, vmfd = -1, cpufd = -1;
+
+ kvmfd = qemu_open_old("/dev/kvm", O_RDWR);
+ if (kvmfd < 0) {
+ goto err;
+ }
+ do {
+ vmfd = ioctl(kvmfd, KVM_CREATE_VM, 0);
+ } while (vmfd == -1 && errno == EINTR);
+ if (vmfd < 0) {
+ goto err;
+ }
+ cpufd = ioctl(vmfd, KVM_CREATE_VCPU, 0);
+ if (cpufd < 0) {
+ goto err;
+ }
+
+ scratch->kvmfd = kvmfd;
+ scratch->vmfd = vmfd;
+ scratch->cpufd = cpufd;
+
+ return true;
+
+ err:
+ if (cpufd >= 0) {
+ close(cpufd);
+ }
+ if (vmfd >= 0) {
+ close(vmfd);
+ }
+ if (kvmfd >= 0) {
+ close(kvmfd);
+ }
+
+ return false;
+}
+
+static void kvm_riscv_destroy_scratch_vcpu(KVMScratchCPU *scratch)
+{
+ close(scratch->cpufd);
+ close(scratch->vmfd);
+ close(scratch->kvmfd);
+}
+
+static void kvm_riscv_init_machine_ids(RISCVCPU *cpu, KVMScratchCPU *kvmcpu)
+{
+ CPURISCVState *env = &cpu->env;
+ struct kvm_one_reg reg;
+ int ret;
+
+ reg.id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
+ KVM_REG_RISCV_CONFIG_REG(mvendorid));
+ reg.addr = (uint64_t)&cpu->cfg.mvendorid;
+ ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, &reg);
+ if (ret != 0) {
+ error_report("Unable to retrieve mvendorid from host, error %d", ret);
+ }
+}
+
+void kvm_riscv_init_user_properties(Object *cpu_obj)
+{
+ RISCVCPU *cpu = RISCV_CPU(cpu_obj);
+ KVMScratchCPU kvmcpu;
+
+ if (!kvm_riscv_create_scratch_vcpu(&kvmcpu)) {
+ return;
+ }
+
+ kvm_riscv_init_machine_ids(cpu, &kvmcpu);
+
+ kvm_riscv_destroy_scratch_vcpu(&kvmcpu);
+}
+
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
KVM_CAP_LAST_INFO
};