147e07394SAndrew Turner /*
247e07394SAndrew Turner * Copyright (C) 2015 Mihai Carabas <mihai.carabas@gmail.com>
347e07394SAndrew Turner * All rights reserved.
447e07394SAndrew Turner *
547e07394SAndrew Turner * Redistribution and use in source and binary forms, with or without
647e07394SAndrew Turner * modification, are permitted provided that the following conditions
747e07394SAndrew Turner * are met:
847e07394SAndrew Turner * 1. Redistributions of source code must retain the above copyright
947e07394SAndrew Turner * notice, this list of conditions and the following disclaimer.
1047e07394SAndrew Turner * 2. Redistributions in binary form must reproduce the above copyright
1147e07394SAndrew Turner * notice, this list of conditions and the following disclaimer in the
1247e07394SAndrew Turner * documentation and/or other materials provided with the distribution.
1347e07394SAndrew Turner *
1447e07394SAndrew Turner * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1547e07394SAndrew Turner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1647e07394SAndrew Turner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1747e07394SAndrew Turner * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
1847e07394SAndrew Turner * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1947e07394SAndrew Turner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2047e07394SAndrew Turner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2147e07394SAndrew Turner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2247e07394SAndrew Turner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2347e07394SAndrew Turner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2447e07394SAndrew Turner * SUCH DAMAGE.
2547e07394SAndrew Turner */
2647e07394SAndrew Turner
2747e07394SAndrew Turner #ifndef _VMM_H_
2847e07394SAndrew Turner #define _VMM_H_
2947e07394SAndrew Turner
3047e07394SAndrew Turner #include <sys/param.h>
3147e07394SAndrew Turner #include <sys/cpuset.h>
3247e07394SAndrew Turner #include <vm/vm.h>
3347e07394SAndrew Turner #include <vm/pmap.h>
3447e07394SAndrew Turner
3547e07394SAndrew Turner #include "pte.h"
3647e07394SAndrew Turner #include "pmap.h"
3747e07394SAndrew Turner
3847e07394SAndrew Turner struct vcpu;
3947e07394SAndrew Turner
4047e07394SAndrew Turner enum vm_suspend_how {
4147e07394SAndrew Turner VM_SUSPEND_NONE,
4247e07394SAndrew Turner VM_SUSPEND_RESET,
4347e07394SAndrew Turner VM_SUSPEND_POWEROFF,
4447e07394SAndrew Turner VM_SUSPEND_HALT,
4547e07394SAndrew Turner VM_SUSPEND_LAST
4647e07394SAndrew Turner };
4747e07394SAndrew Turner
4847e07394SAndrew Turner /*
4947e07394SAndrew Turner * Identifiers for architecturally defined registers.
5047e07394SAndrew Turner */
5147e07394SAndrew Turner enum vm_reg_name {
5247e07394SAndrew Turner VM_REG_GUEST_X0 = 0,
5347e07394SAndrew Turner VM_REG_GUEST_X1,
5447e07394SAndrew Turner VM_REG_GUEST_X2,
5547e07394SAndrew Turner VM_REG_GUEST_X3,
5647e07394SAndrew Turner VM_REG_GUEST_X4,
5747e07394SAndrew Turner VM_REG_GUEST_X5,
5847e07394SAndrew Turner VM_REG_GUEST_X6,
5947e07394SAndrew Turner VM_REG_GUEST_X7,
6047e07394SAndrew Turner VM_REG_GUEST_X8,
6147e07394SAndrew Turner VM_REG_GUEST_X9,
6247e07394SAndrew Turner VM_REG_GUEST_X10,
6347e07394SAndrew Turner VM_REG_GUEST_X11,
6447e07394SAndrew Turner VM_REG_GUEST_X12,
6547e07394SAndrew Turner VM_REG_GUEST_X13,
6647e07394SAndrew Turner VM_REG_GUEST_X14,
6747e07394SAndrew Turner VM_REG_GUEST_X15,
6847e07394SAndrew Turner VM_REG_GUEST_X16,
6947e07394SAndrew Turner VM_REG_GUEST_X17,
7047e07394SAndrew Turner VM_REG_GUEST_X18,
7147e07394SAndrew Turner VM_REG_GUEST_X19,
7247e07394SAndrew Turner VM_REG_GUEST_X20,
7347e07394SAndrew Turner VM_REG_GUEST_X21,
7447e07394SAndrew Turner VM_REG_GUEST_X22,
7547e07394SAndrew Turner VM_REG_GUEST_X23,
7647e07394SAndrew Turner VM_REG_GUEST_X24,
7747e07394SAndrew Turner VM_REG_GUEST_X25,
7847e07394SAndrew Turner VM_REG_GUEST_X26,
7947e07394SAndrew Turner VM_REG_GUEST_X27,
8047e07394SAndrew Turner VM_REG_GUEST_X28,
8147e07394SAndrew Turner VM_REG_GUEST_X29,
8247e07394SAndrew Turner VM_REG_GUEST_LR,
8347e07394SAndrew Turner VM_REG_GUEST_SP,
8447e07394SAndrew Turner VM_REG_GUEST_PC,
8547e07394SAndrew Turner VM_REG_GUEST_CPSR,
8647e07394SAndrew Turner
8747e07394SAndrew Turner VM_REG_GUEST_SCTLR_EL1,
8847e07394SAndrew Turner VM_REG_GUEST_TTBR0_EL1,
8947e07394SAndrew Turner VM_REG_GUEST_TTBR1_EL1,
9047e07394SAndrew Turner VM_REG_GUEST_TCR_EL1,
9147e07394SAndrew Turner VM_REG_GUEST_TCR2_EL1,
9247e07394SAndrew Turner VM_REG_LAST
9347e07394SAndrew Turner };
9447e07394SAndrew Turner
9547e07394SAndrew Turner #define VM_INTINFO_VECTOR(info) ((info) & 0xff)
9647e07394SAndrew Turner #define VM_INTINFO_DEL_ERRCODE 0x800
9747e07394SAndrew Turner #define VM_INTINFO_RSVD 0x7ffff000
9847e07394SAndrew Turner #define VM_INTINFO_VALID 0x80000000
9947e07394SAndrew Turner #define VM_INTINFO_TYPE 0x700
10047e07394SAndrew Turner #define VM_INTINFO_HWINTR (0 << 8)
10147e07394SAndrew Turner #define VM_INTINFO_NMI (2 << 8)
10247e07394SAndrew Turner #define VM_INTINFO_HWEXCEPTION (3 << 8)
10347e07394SAndrew Turner #define VM_INTINFO_SWINTR (4 << 8)
10447e07394SAndrew Turner
10547e07394SAndrew Turner #define VM_GUEST_BASE_IPA 0x80000000UL /* Guest kernel start ipa */
10647e07394SAndrew Turner
107*780675e1SMark Johnston /*
108*780675e1SMark Johnston * The VM name has to fit into the pathname length constraints of devfs,
109*780675e1SMark Johnston * governed primarily by SPECNAMELEN. The length is the total number of
110*780675e1SMark Johnston * characters in the full path, relative to the mount point and not
111*780675e1SMark Johnston * including any leading '/' characters.
112*780675e1SMark Johnston * A prefix and a suffix are added to the name specified by the user.
113*780675e1SMark Johnston * The prefix is usually "vmm/" or "vmm.io/", but can be a few characters
114*780675e1SMark Johnston * longer for future use.
115*780675e1SMark Johnston * The suffix is a string that identifies a bootrom image or some similar
116*780675e1SMark Johnston * image that is attached to the VM. A separator character gets added to
117*780675e1SMark Johnston * the suffix automatically when generating the full path, so it must be
118*780675e1SMark Johnston * accounted for, reducing the effective length by 1.
119*780675e1SMark Johnston * The effective length of a VM name is 229 bytes for FreeBSD 13 and 37
120*780675e1SMark Johnston * bytes for FreeBSD 12. A minimum length is set for safety and supports
121*780675e1SMark Johnston * a SPECNAMELEN as small as 32 on old systems.
122*780675e1SMark Johnston */
123*780675e1SMark Johnston #define VM_MAX_PREFIXLEN 10
124*780675e1SMark Johnston #define VM_MAX_SUFFIXLEN 15
125*780675e1SMark Johnston #define VM_MAX_NAMELEN \
126*780675e1SMark Johnston (SPECNAMELEN - VM_MAX_PREFIXLEN - VM_MAX_SUFFIXLEN - 1)
127*780675e1SMark Johnston
12847e07394SAndrew Turner #ifdef _KERNEL
12947e07394SAndrew Turner struct vm;
13047e07394SAndrew Turner struct vm_exception;
13147e07394SAndrew Turner struct vm_exit;
13247e07394SAndrew Turner struct vm_run;
13347e07394SAndrew Turner struct vm_object;
13447e07394SAndrew Turner struct vm_guest_paging;
13547e07394SAndrew Turner struct vm_vgic_descr;
13647e07394SAndrew Turner struct pmap;
13747e07394SAndrew Turner
13847e07394SAndrew Turner struct vm_eventinfo {
13947e07394SAndrew Turner void *rptr; /* rendezvous cookie */
14047e07394SAndrew Turner int *sptr; /* suspend cookie */
14147e07394SAndrew Turner int *iptr; /* reqidle cookie */
14247e07394SAndrew Turner };
14347e07394SAndrew Turner
14447e07394SAndrew Turner int vm_create(const char *name, struct vm **retvm);
14547e07394SAndrew Turner struct vcpu *vm_alloc_vcpu(struct vm *vm, int vcpuid);
146a03354b0SMark Johnston void vm_disable_vcpu_creation(struct vm *vm);
14747e07394SAndrew Turner void vm_slock_vcpus(struct vm *vm);
14847e07394SAndrew Turner void vm_unlock_vcpus(struct vm *vm);
14947e07394SAndrew Turner void vm_destroy(struct vm *vm);
15047e07394SAndrew Turner int vm_reinit(struct vm *vm);
15147e07394SAndrew Turner const char *vm_name(struct vm *vm);
15247e07394SAndrew Turner
15347e07394SAndrew Turner /*
15447e07394SAndrew Turner * APIs that modify the guest memory map require all vcpus to be frozen.
15547e07394SAndrew Turner */
15647e07394SAndrew Turner void vm_slock_memsegs(struct vm *vm);
15747e07394SAndrew Turner void vm_xlock_memsegs(struct vm *vm);
15847e07394SAndrew Turner void vm_unlock_memsegs(struct vm *vm);
15947e07394SAndrew Turner int vm_mmap_memseg(struct vm *vm, vm_paddr_t gpa, int segid, vm_ooffset_t off,
16047e07394SAndrew Turner size_t len, int prot, int flags);
16147e07394SAndrew Turner int vm_munmap_memseg(struct vm *vm, vm_paddr_t gpa, size_t len);
16247e07394SAndrew Turner int vm_alloc_memseg(struct vm *vm, int ident, size_t len, bool sysmem);
16347e07394SAndrew Turner void vm_free_memseg(struct vm *vm, int ident);
16447e07394SAndrew Turner
16547e07394SAndrew Turner /*
16647e07394SAndrew Turner * APIs that inspect the guest memory map require only a *single* vcpu to
16747e07394SAndrew Turner * be frozen. This acts like a read lock on the guest memory map since any
16847e07394SAndrew Turner * modification requires *all* vcpus to be frozen.
16947e07394SAndrew Turner */
17047e07394SAndrew Turner int vm_mmap_getnext(struct vm *vm, vm_paddr_t *gpa, int *segid,
17147e07394SAndrew Turner vm_ooffset_t *segoff, size_t *len, int *prot, int *flags);
17247e07394SAndrew Turner int vm_get_memseg(struct vm *vm, int ident, size_t *len, bool *sysmem,
17347e07394SAndrew Turner struct vm_object **objptr);
17447e07394SAndrew Turner vm_paddr_t vmm_sysmem_maxaddr(struct vm *vm);
17547e07394SAndrew Turner void *vm_gpa_hold(struct vcpu *vcpu, vm_paddr_t gpa, size_t len,
17647e07394SAndrew Turner int prot, void **cookie);
17747e07394SAndrew Turner void *vm_gpa_hold_global(struct vm *vm, vm_paddr_t gpa, size_t len,
17847e07394SAndrew Turner int prot, void **cookie);
17947e07394SAndrew Turner void vm_gpa_release(void *cookie);
18047e07394SAndrew Turner bool vm_mem_allocated(struct vcpu *vcpu, vm_paddr_t gpa);
18147e07394SAndrew Turner
18247e07394SAndrew Turner int vm_gla2gpa_nofault(struct vcpu *vcpu, struct vm_guest_paging *paging,
18347e07394SAndrew Turner uint64_t gla, int prot, uint64_t *gpa, int *is_fault);
18447e07394SAndrew Turner
18547e07394SAndrew Turner uint16_t vm_get_maxcpus(struct vm *vm);
18647e07394SAndrew Turner void vm_get_topology(struct vm *vm, uint16_t *sockets, uint16_t *cores,
18747e07394SAndrew Turner uint16_t *threads, uint16_t *maxcpus);
18847e07394SAndrew Turner int vm_set_topology(struct vm *vm, uint16_t sockets, uint16_t cores,
18947e07394SAndrew Turner uint16_t threads, uint16_t maxcpus);
19047e07394SAndrew Turner int vm_get_register(struct vcpu *vcpu, int reg, uint64_t *retval);
19147e07394SAndrew Turner int vm_set_register(struct vcpu *vcpu, int reg, uint64_t val);
19247e07394SAndrew Turner int vm_run(struct vcpu *vcpu);
19347e07394SAndrew Turner int vm_suspend(struct vm *vm, enum vm_suspend_how how);
19447e07394SAndrew Turner void* vm_get_cookie(struct vm *vm);
19547e07394SAndrew Turner int vcpu_vcpuid(struct vcpu *vcpu);
19647e07394SAndrew Turner void *vcpu_get_cookie(struct vcpu *vcpu);
19747e07394SAndrew Turner struct vm *vcpu_vm(struct vcpu *vcpu);
19847e07394SAndrew Turner struct vcpu *vm_vcpu(struct vm *vm, int cpu);
19947e07394SAndrew Turner int vm_get_capability(struct vcpu *vcpu, int type, int *val);
20047e07394SAndrew Turner int vm_set_capability(struct vcpu *vcpu, int type, int val);
20147e07394SAndrew Turner int vm_activate_cpu(struct vcpu *vcpu);
20247e07394SAndrew Turner int vm_suspend_cpu(struct vm *vm, struct vcpu *vcpu);
20347e07394SAndrew Turner int vm_resume_cpu(struct vm *vm, struct vcpu *vcpu);
20447e07394SAndrew Turner int vm_inject_exception(struct vcpu *vcpu, uint64_t esr, uint64_t far);
20547e07394SAndrew Turner int vm_attach_vgic(struct vm *vm, struct vm_vgic_descr *descr);
20647e07394SAndrew Turner int vm_assert_irq(struct vm *vm, uint32_t irq);
20747e07394SAndrew Turner int vm_deassert_irq(struct vm *vm, uint32_t irq);
20847e07394SAndrew Turner int vm_raise_msi(struct vm *vm, uint64_t msg, uint64_t addr, int bus, int slot,
20947e07394SAndrew Turner int func);
21047e07394SAndrew Turner struct vm_exit *vm_exitinfo(struct vcpu *vcpu);
21147e07394SAndrew Turner void vm_exit_suspended(struct vcpu *vcpu, uint64_t pc);
21247e07394SAndrew Turner void vm_exit_debug(struct vcpu *vcpu, uint64_t pc);
21347e07394SAndrew Turner void vm_exit_rendezvous(struct vcpu *vcpu, uint64_t pc);
21447e07394SAndrew Turner void vm_exit_astpending(struct vcpu *vcpu, uint64_t pc);
21547e07394SAndrew Turner
21647e07394SAndrew Turner cpuset_t vm_active_cpus(struct vm *vm);
21747e07394SAndrew Turner cpuset_t vm_debug_cpus(struct vm *vm);
21847e07394SAndrew Turner cpuset_t vm_suspended_cpus(struct vm *vm);
21947e07394SAndrew Turner
22047e07394SAndrew Turner static __inline int
vcpu_rendezvous_pending(struct vm_eventinfo * info)22147e07394SAndrew Turner vcpu_rendezvous_pending(struct vm_eventinfo *info)
22247e07394SAndrew Turner {
22347e07394SAndrew Turner
22447e07394SAndrew Turner return (*((uintptr_t *)(info->rptr)) != 0);
22547e07394SAndrew Turner }
22647e07394SAndrew Turner
22747e07394SAndrew Turner static __inline int
vcpu_suspended(struct vm_eventinfo * info)22847e07394SAndrew Turner vcpu_suspended(struct vm_eventinfo *info)
22947e07394SAndrew Turner {
23047e07394SAndrew Turner
23147e07394SAndrew Turner return (*info->sptr);
23247e07394SAndrew Turner }
23347e07394SAndrew Turner
23447e07394SAndrew Turner int vcpu_debugged(struct vcpu *vcpu);
23547e07394SAndrew Turner
23647e07394SAndrew Turner enum vcpu_state {
23747e07394SAndrew Turner VCPU_IDLE,
23847e07394SAndrew Turner VCPU_FROZEN,
23947e07394SAndrew Turner VCPU_RUNNING,
24047e07394SAndrew Turner VCPU_SLEEPING,
24147e07394SAndrew Turner };
24247e07394SAndrew Turner
24347e07394SAndrew Turner int vcpu_set_state(struct vcpu *vcpu, enum vcpu_state state, bool from_idle);
24447e07394SAndrew Turner enum vcpu_state vcpu_get_state(struct vcpu *vcpu, int *hostcpu);
24547e07394SAndrew Turner
24647e07394SAndrew Turner static int __inline
vcpu_is_running(struct vcpu * vcpu,int * hostcpu)24747e07394SAndrew Turner vcpu_is_running(struct vcpu *vcpu, int *hostcpu)
24847e07394SAndrew Turner {
24947e07394SAndrew Turner return (vcpu_get_state(vcpu, hostcpu) == VCPU_RUNNING);
25047e07394SAndrew Turner }
25147e07394SAndrew Turner
25247e07394SAndrew Turner #ifdef _SYS_PROC_H_
25347e07394SAndrew Turner static int __inline
vcpu_should_yield(struct vcpu * vcpu)25447e07394SAndrew Turner vcpu_should_yield(struct vcpu *vcpu)
25547e07394SAndrew Turner {
25647e07394SAndrew Turner struct thread *td;
25747e07394SAndrew Turner
25847e07394SAndrew Turner td = curthread;
25947e07394SAndrew Turner return (td->td_ast != 0 || td->td_owepreempt != 0);
26047e07394SAndrew Turner }
26147e07394SAndrew Turner #endif
26247e07394SAndrew Turner
26347e07394SAndrew Turner void *vcpu_stats(struct vcpu *vcpu);
26447e07394SAndrew Turner void vcpu_notify_event(struct vcpu *vcpu);
26547e07394SAndrew Turner
26647e07394SAndrew Turner enum vm_reg_name vm_segment_name(int seg_encoding);
26747e07394SAndrew Turner
26847e07394SAndrew Turner struct vm_copyinfo {
26947e07394SAndrew Turner uint64_t gpa;
27047e07394SAndrew Turner size_t len;
27147e07394SAndrew Turner void *hva;
27247e07394SAndrew Turner void *cookie;
27347e07394SAndrew Turner };
27447e07394SAndrew Turner
27547e07394SAndrew Turner #endif /* _KERNEL */
27647e07394SAndrew Turner
27747e07394SAndrew Turner #define VM_DIR_READ 0
27847e07394SAndrew Turner #define VM_DIR_WRITE 1
27947e07394SAndrew Turner
28047e07394SAndrew Turner #define VM_GP_M_MASK 0x1f
28147e07394SAndrew Turner #define VM_GP_MMU_ENABLED (1 << 5)
28247e07394SAndrew Turner
28347e07394SAndrew Turner struct vm_guest_paging {
28447e07394SAndrew Turner uint64_t ttbr0_addr;
28547e07394SAndrew Turner uint64_t ttbr1_addr;
28647e07394SAndrew Turner uint64_t tcr_el1;
28747e07394SAndrew Turner uint64_t tcr2_el1;
28847e07394SAndrew Turner int flags;
28947e07394SAndrew Turner int padding;
29047e07394SAndrew Turner };
29147e07394SAndrew Turner
29247e07394SAndrew Turner struct vie {
29347e07394SAndrew Turner uint8_t access_size:4, sign_extend:1, dir:1, unused:2;
29447e07394SAndrew Turner enum vm_reg_name reg;
29547e07394SAndrew Turner };
29647e07394SAndrew Turner
29747e07394SAndrew Turner struct vre {
29847e07394SAndrew Turner uint32_t inst_syndrome;
29947e07394SAndrew Turner uint8_t dir:1, unused:7;
30047e07394SAndrew Turner enum vm_reg_name reg;
30147e07394SAndrew Turner };
30247e07394SAndrew Turner
30347e07394SAndrew Turner /*
30447e07394SAndrew Turner * Identifiers for optional vmm capabilities
30547e07394SAndrew Turner */
30647e07394SAndrew Turner enum vm_cap_type {
30747e07394SAndrew Turner VM_CAP_HALT_EXIT,
30847e07394SAndrew Turner VM_CAP_PAUSE_EXIT,
30947e07394SAndrew Turner VM_CAP_UNRESTRICTED_GUEST,
31075cb9492SMark Johnston VM_CAP_BRK_EXIT,
31175cb9492SMark Johnston VM_CAP_SS_EXIT,
31275cb9492SMark Johnston VM_CAP_MASK_HWINTR,
31347e07394SAndrew Turner VM_CAP_MAX
31447e07394SAndrew Turner };
31547e07394SAndrew Turner
31647e07394SAndrew Turner enum vm_exitcode {
31747e07394SAndrew Turner VM_EXITCODE_BOGUS,
31847e07394SAndrew Turner VM_EXITCODE_INST_EMUL,
31947e07394SAndrew Turner VM_EXITCODE_REG_EMUL,
32047e07394SAndrew Turner VM_EXITCODE_HVC,
32147e07394SAndrew Turner VM_EXITCODE_SUSPENDED,
32247e07394SAndrew Turner VM_EXITCODE_HYP,
32347e07394SAndrew Turner VM_EXITCODE_WFI,
32447e07394SAndrew Turner VM_EXITCODE_PAGING,
32547e07394SAndrew Turner VM_EXITCODE_SMCCC,
32647e07394SAndrew Turner VM_EXITCODE_DEBUG,
32775cb9492SMark Johnston VM_EXITCODE_BRK,
32875cb9492SMark Johnston VM_EXITCODE_SS,
32947e07394SAndrew Turner VM_EXITCODE_MAX
33047e07394SAndrew Turner };
33147e07394SAndrew Turner
33247e07394SAndrew Turner struct vm_exit {
33347e07394SAndrew Turner enum vm_exitcode exitcode;
33447e07394SAndrew Turner int inst_length;
33547e07394SAndrew Turner uint64_t pc;
33647e07394SAndrew Turner union {
33747e07394SAndrew Turner /*
33847e07394SAndrew Turner * ARM specific payload.
33947e07394SAndrew Turner */
34047e07394SAndrew Turner struct {
34147e07394SAndrew Turner uint32_t exception_nr;
34247e07394SAndrew Turner uint32_t pad;
34347e07394SAndrew Turner uint64_t esr_el2; /* Exception Syndrome Register */
34447e07394SAndrew Turner uint64_t far_el2; /* Fault Address Register */
34547e07394SAndrew Turner uint64_t hpfar_el2; /* Hypervisor IPA Fault Address Register */
34647e07394SAndrew Turner } hyp;
34747e07394SAndrew Turner struct {
34847e07394SAndrew Turner struct vre vre;
34947e07394SAndrew Turner } reg_emul;
35047e07394SAndrew Turner struct {
35147e07394SAndrew Turner uint64_t gpa;
35247e07394SAndrew Turner uint64_t esr;
35347e07394SAndrew Turner } paging;
35447e07394SAndrew Turner struct {
35547e07394SAndrew Turner uint64_t gpa;
35647e07394SAndrew Turner struct vm_guest_paging paging;
35747e07394SAndrew Turner struct vie vie;
35847e07394SAndrew Turner } inst_emul;
35947e07394SAndrew Turner
36047e07394SAndrew Turner /*
36147e07394SAndrew Turner * A SMCCC call, e.g. starting a core via PSCI.
36247e07394SAndrew Turner * Further arguments can be read by asking the kernel for
36347e07394SAndrew Turner * all register values.
36447e07394SAndrew Turner */
36547e07394SAndrew Turner struct {
36647e07394SAndrew Turner uint64_t func_id;
36747e07394SAndrew Turner uint64_t args[7];
36847e07394SAndrew Turner } smccc_call;
36947e07394SAndrew Turner
37047e07394SAndrew Turner struct {
37147e07394SAndrew Turner enum vm_suspend_how how;
37247e07394SAndrew Turner } suspended;
37347e07394SAndrew Turner } u;
37447e07394SAndrew Turner };
37547e07394SAndrew Turner
37647e07394SAndrew Turner #endif /* _VMM_H_ */
377