1 #ifndef KVM__KVM_CPU_ARCH_H
2 #define KVM__KVM_CPU_ARCH_H
3
4 #include <linux/kvm.h>
5 #include <pthread.h>
6 #include <stdbool.h>
7
8 #include "kvm/kvm.h"
9
__kvm_reg_id(__u64 type,__u64 subtype,__u64 idx,__u64 size)10 static inline __u64 __kvm_reg_id(__u64 type, __u64 subtype,
11 __u64 idx, __u64 size)
12 {
13 return KVM_REG_RISCV | type | subtype | idx | size;
14 }
15
16 #if __riscv_xlen == 64
17 #define KVM_REG_SIZE_ULONG KVM_REG_SIZE_U64
18 #else
19 #define KVM_REG_SIZE_ULONG KVM_REG_SIZE_U32
20 #endif
21
22 #define RISCV_CONFIG_REG(name) __kvm_reg_id(KVM_REG_RISCV_CONFIG, 0, \
23 KVM_REG_RISCV_CONFIG_REG(name), \
24 KVM_REG_SIZE_ULONG)
25
26 #define RISCV_ISA_EXT_REG(id) __kvm_reg_id(KVM_REG_RISCV_ISA_EXT, 0, \
27 id, KVM_REG_SIZE_ULONG)
28
29 #define RISCV_CORE_REG(name) __kvm_reg_id(KVM_REG_RISCV_CORE, 0, \
30 KVM_REG_RISCV_CORE_REG(name), \
31 KVM_REG_SIZE_ULONG)
32
33 #define RISCV_CSR_REG(name) __kvm_reg_id(KVM_REG_RISCV_CSR, 0, \
34 KVM_REG_RISCV_CSR_REG(name), \
35 KVM_REG_SIZE_ULONG)
36
37 #define RISCV_TIMER_REG(name) __kvm_reg_id(KVM_REG_RISCV_TIMER, 0, \
38 KVM_REG_RISCV_TIMER_REG(name), \
39 KVM_REG_SIZE_U64)
40
41 #define RISCV_SBI_EXT_REG(subtype, id) \
42 __kvm_reg_id(KVM_REG_RISCV_SBI_EXT, subtype, \
43 id, KVM_REG_SIZE_ULONG)
44
45 struct kvm_cpu {
46 pthread_t thread;
47
48 unsigned long cpu_id;
49
50 unsigned long riscv_xlen;
51 unsigned long riscv_isa;
52 unsigned long riscv_timebase;
53
54 struct kvm *kvm;
55 int vcpu_fd;
56 struct kvm_run *kvm_run;
57 struct kvm_cpu_task *task;
58
59 u8 is_running;
60 u8 paused;
61 u8 needs_nmi;
62
63 struct kvm_coalesced_mmio_ring *ring;
64 };
65
kvm_cpu__emulate_io(struct kvm_cpu * vcpu,u16 port,void * data,int direction,int size,u32 count)66 static inline bool kvm_cpu__emulate_io(struct kvm_cpu *vcpu, u16 port,
67 void *data, int direction,
68 int size, u32 count)
69 {
70 return false;
71 }
72
kvm_cpu__emulate_mmio(struct kvm_cpu * vcpu,u64 phys_addr,u8 * data,u32 len,u8 is_write)73 static inline bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr,
74 u8 *data, u32 len, u8 is_write)
75 {
76 if (riscv_addr_in_ioport_region(phys_addr)) {
77 int direction = is_write ? KVM_EXIT_IO_OUT : KVM_EXIT_IO_IN;
78 u16 port = (phys_addr - KVM_IOPORT_AREA) & USHRT_MAX;
79
80 return kvm__emulate_io(vcpu, port, data, direction, len, 1);
81 }
82
83 return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write);
84 }
85
86 #endif /* KVM__KVM_CPU_ARCH_H */
87