1/*
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2015 Mihai Carabas <mihai.carabas@gmail.com>
5 * Copyright (c) 2024 Ruslan Bukin <br@bsdpad.com>
6 *
7 * This software was developed by the University of Cambridge Computer
8 * Laboratory (Department of Computer Science and Technology) under Innovate
9 * UK project 105694, "Digital Security by Design (DSbD) Technology Platform
10 * Prototype".
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 *
21 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef _VMM_DEV_H_
35#define _VMM_DEV_H_
36
37#include <sys/domainset.h>
38
39#include <machine/vmm.h>
40
41struct vm_memmap {
42 vm_paddr_t gpa;
43 int segid; /* memory segment */
44 vm_ooffset_t segoff; /* offset into memory segment */
45 size_t len; /* mmap length */
46 int prot; /* RWX */
47 int flags;
48};
49#define VM_MEMMAP_F_WIRED 0x01
50
51struct vm_munmap {
52 vm_paddr_t gpa;
53 size_t len;
54};
55
56#define VM_MEMSEG_NAME(m) ((m)->name[0] != '\0' ? (m)->name : NULL)
57struct vm_memseg {
58 int segid;
59 size_t len;
60 char name[VM_MAX_SUFFIXLEN + 1];
61 domainset_t *ds_mask;
62 size_t ds_mask_size;
63 int ds_policy;
64};
65
66struct vm_register {
67 int cpuid;
68 int regnum; /* enum vm_reg_name */
69 uint64_t regval;
70};
71
72struct vm_register_set {
73 int cpuid;
74 unsigned int count;
75 const int *regnums; /* enum vm_reg_name */
76 uint64_t *regvals;
77};
78
79struct vm_run {
80 int cpuid;
81 cpuset_t *cpuset; /* CPU set storage */
82 size_t cpusetsize;
83 struct vm_exit *vm_exit;
84};
85
86struct vm_exception {
87 int cpuid;
88 uint64_t scause;
89};
90
91struct vm_msi {
92 uint64_t msg;
93 uint64_t addr;
94 int bus;
95 int slot;
96 int func;
97};
98
99struct vm_capability {
100 int cpuid;
101 enum vm_cap_type captype;
102 int capval;
103 int allcpus;
104};
105
106#define MAX_VM_STATS 64
107struct vm_stats {
108 int cpuid; /* in */
109 int index; /* in */
110 int num_entries; /* out */
111 struct timeval tv;
112 uint64_t statbuf[MAX_VM_STATS];
113};
114struct vm_stat_desc {
115 int index; /* in */
116 char desc[128]; /* out */
117};
118
119struct vm_suspend {
120 enum vm_suspend_how how;
121};
122
123struct vm_gla2gpa {
124 int vcpuid; /* inputs */
125 int prot; /* PROT_READ or PROT_WRITE */
126 uint64_t gla;
127 struct vm_guest_paging paging;
128 int fault; /* outputs */
129 uint64_t gpa;
130};
131
132struct vm_activate_cpu {
133 int vcpuid;
134};
135
136struct vm_cpuset {
137 int which;
138 int cpusetsize;
139 cpuset_t *cpus;
140};
141#define VM_ACTIVE_CPUS 0
142#define VM_SUSPENDED_CPUS 1
143#define VM_DEBUG_CPUS 2
144
145struct vm_aplic_descr {
146 uint64_t mem_start;
147 uint64_t mem_size;
148};
149
150struct vm_irq {
151 uint32_t irq;
152};
153
154struct vm_cpu_topology {
155 uint16_t sockets;
156 uint16_t cores;
157 uint16_t threads;
158 uint16_t maxcpus;
159};
160
161enum {
162 /* general routines */
163 IOCNUM_ABIVERS = 0,
164 IOCNUM_RUN = 1,
165 IOCNUM_SET_CAPABILITY = 2,
166 IOCNUM_GET_CAPABILITY = 3,
167 IOCNUM_SUSPEND = 4,
168 IOCNUM_REINIT = 5,
169
170 /* memory apis */
171 IOCNUM_GET_GPA_PMAP = 12,
172 IOCNUM_GLA2GPA_NOFAULT = 13,
173 IOCNUM_ALLOC_MEMSEG = 14,
174 IOCNUM_GET_MEMSEG = 15,
175 IOCNUM_MMAP_MEMSEG = 16,
176 IOCNUM_MMAP_GETNEXT = 17,
177 IOCNUM_MUNMAP_MEMSEG = 18,
178
179 /* register/state accessors */
180 IOCNUM_SET_REGISTER = 20,
181 IOCNUM_GET_REGISTER = 21,
182 IOCNUM_SET_REGISTER_SET = 24,
183 IOCNUM_GET_REGISTER_SET = 25,
184
185 /* statistics */
186 IOCNUM_VM_STATS = 50,
187 IOCNUM_VM_STAT_DESC = 51,
188
189 /* CPU Topology */
190 IOCNUM_SET_TOPOLOGY = 63,
191 IOCNUM_GET_TOPOLOGY = 64,
192
193 /* interrupt injection */
194 IOCNUM_ASSERT_IRQ = 80,
195 IOCNUM_DEASSERT_IRQ = 81,
196 IOCNUM_RAISE_MSI = 82,
197 IOCNUM_INJECT_EXCEPTION = 83,
198
199 /* vm_cpuset */
200 IOCNUM_ACTIVATE_CPU = 90,
201 IOCNUM_GET_CPUSET = 91,
202 IOCNUM_SUSPEND_CPU = 92,
203 IOCNUM_RESUME_CPU = 93,
204
205 /* vm_attach_aplic */
206 IOCNUM_ATTACH_APLIC = 110,
207};
208
209#define VM_RUN \
210 _IOWR('v', IOCNUM_RUN, struct vm_run)
211#define VM_SUSPEND \
212 _IOW('v', IOCNUM_SUSPEND, struct vm_suspend)
213#define VM_REINIT \
214 _IO('v', IOCNUM_REINIT)
215#define VM_ALLOC_MEMSEG \
216 _IOW('v', IOCNUM_ALLOC_MEMSEG, struct vm_memseg)
217#define VM_GET_MEMSEG \
218 _IOWR('v', IOCNUM_GET_MEMSEG, struct vm_memseg)
219#define VM_MMAP_MEMSEG \
220 _IOW('v', IOCNUM_MMAP_MEMSEG, struct vm_memmap)
221#define VM_MMAP_GETNEXT \
222 _IOWR('v', IOCNUM_MMAP_GETNEXT, struct vm_memmap)
223#define VM_MUNMAP_MEMSEG \
224 _IOW('v', IOCNUM_MUNMAP_MEMSEG, struct vm_munmap)
225#define VM_SET_REGISTER \
226 _IOW('v', IOCNUM_SET_REGISTER, struct vm_register)
227#define VM_GET_REGISTER \
228 _IOWR('v', IOCNUM_GET_REGISTER, struct vm_register)
229#define VM_SET_REGISTER_SET \
230 _IOW('v', IOCNUM_SET_REGISTER_SET, struct vm_register_set)
231#define VM_GET_REGISTER_SET \
232 _IOWR('v', IOCNUM_GET_REGISTER_SET, struct vm_register_set)
233#define VM_SET_CAPABILITY \
234 _IOW('v', IOCNUM_SET_CAPABILITY, struct vm_capability)
235#define VM_GET_CAPABILITY \
236 _IOWR('v', IOCNUM_GET_CAPABILITY, struct vm_capability)
237#define VM_STATS \
238 _IOWR('v', IOCNUM_VM_STATS, struct vm_stats)
239#define VM_STAT_DESC \
240 _IOWR('v', IOCNUM_VM_STAT_DESC, struct vm_stat_desc)
241#define VM_ASSERT_IRQ \
242 _IOW('v', IOCNUM_ASSERT_IRQ, struct vm_irq)
243#define VM_DEASSERT_IRQ \
244 _IOW('v', IOCNUM_DEASSERT_IRQ, struct vm_irq)
245#define VM_RAISE_MSI \
246 _IOW('v', IOCNUM_RAISE_MSI, struct vm_msi)
247#define VM_INJECT_EXCEPTION \
248 _IOW('v', IOCNUM_INJECT_EXCEPTION, struct vm_exception)
249#define VM_SET_TOPOLOGY \
250 _IOW('v', IOCNUM_SET_TOPOLOGY, struct vm_cpu_topology)
251#define VM_GET_TOPOLOGY \
252 _IOR('v', IOCNUM_GET_TOPOLOGY, struct vm_cpu_topology)
253#define VM_GLA2GPA_NOFAULT \
254 _IOWR('v', IOCNUM_GLA2GPA_NOFAULT, struct vm_gla2gpa)
255#define VM_ACTIVATE_CPU \
256 _IOW('v', IOCNUM_ACTIVATE_CPU, struct vm_activate_cpu)
257#define VM_GET_CPUS \
258 _IOW('v', IOCNUM_GET_CPUSET, struct vm_cpuset)
259#define VM_SUSPEND_CPU \
260 _IOW('v', IOCNUM_SUSPEND_CPU, struct vm_activate_cpu)
261#define VM_RESUME_CPU \
262 _IOW('v', IOCNUM_RESUME_CPU, struct vm_activate_cpu)
263#define VM_ATTACH_APLIC \
264 _IOW('v', IOCNUM_ATTACH_APLIC, struct vm_aplic_descr)
265#endif