1 /* $NetBSD: nvmm_internal.h,v 1.21 2022/09/13 20:10:04 riastradh Exp $ */ 2 3 /* 4 * Copyright (c) 2018-2020 Maxime Villard, m00nbsd.net 5 * All rights reserved. 6 * 7 * This code is part of the NVMM hypervisor. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 #ifndef _NVMM_INTERNAL_H_ 32 #define _NVMM_INTERNAL_H_ 33 34 #include <sys/types.h> 35 36 #include <sys/lwp.h> 37 #include <sys/mutex.h> 38 #include <sys/rwlock.h> 39 #include <sys/sched.h> 40 41 #include <dev/nvmm/nvmm.h> 42 43 struct uvm_object; 44 struct vmspace; 45 46 #define NVMM_MAX_MACHINES 128 47 #define NVMM_MAX_VCPUS 256 48 #define NVMM_MAX_HMAPPINGS 32 49 #define NVMM_MAX_RAM (128ULL * (1 << 30)) 50 51 struct nvmm_owner { 52 pid_t pid; 53 }; 54 55 struct nvmm_cpu { 56 /* Shared. */ 57 bool present; 58 nvmm_cpuid_t cpuid; 59 kmutex_t lock; 60 61 /* Comm page. */ 62 struct nvmm_comm_page *comm; 63 64 /* Last host CPU on which the VCPU ran. */ 65 int hcpu_last; 66 67 /* Implementation-specific. */ 68 void *cpudata; 69 }; 70 71 struct nvmm_hmapping { 72 bool present; 73 uintptr_t hva; 74 size_t size; 75 struct uvm_object *uobj; 76 }; 77 78 struct nvmm_machine { 79 bool present; 80 nvmm_machid_t machid; 81 time_t time; 82 struct nvmm_owner *owner; 83 krwlock_t lock; 84 85 /* Comm */ 86 struct uvm_object *commuobj; 87 88 /* Kernel */ 89 struct vmspace *vm; 90 gpaddr_t gpa_begin; 91 gpaddr_t gpa_end; 92 93 /* Host Mappings */ 94 struct nvmm_hmapping hmap[NVMM_MAX_HMAPPINGS]; 95 96 /* CPU */ 97 volatile unsigned int ncpus; 98 struct nvmm_cpu cpus[NVMM_MAX_VCPUS]; 99 100 /* Implementation-specific */ 101 void *machdata; 102 }; 103 104 struct nvmm_impl { 105 const char *name; 106 bool (*ident)(void); 107 void (*init)(void); 108 void (*fini)(void); 109 void (*capability)(struct nvmm_capability *); 110 void (*suspend_interrupt)(void); 111 void (*suspend)(void); 112 void (*resume)(void); 113 114 size_t mach_conf_max; 115 const size_t *mach_conf_sizes; 116 117 size_t vcpu_conf_max; 118 const size_t *vcpu_conf_sizes; 119 120 size_t state_size; 121 122 void (*machine_create)(struct nvmm_machine *); 123 void (*machine_destroy)(struct nvmm_machine *); 124 int (*machine_configure)(struct nvmm_machine *, uint64_t, void *); 125 void (*machine_suspend)(struct nvmm_machine *); 126 void (*machine_resume)(struct nvmm_machine *); 127 128 int (*vcpu_create)(struct nvmm_machine *, struct nvmm_cpu *); 129 void (*vcpu_destroy)(struct nvmm_machine *, struct nvmm_cpu *); 130 int (*vcpu_configure)(struct nvmm_cpu *, uint64_t, void *); 131 void (*vcpu_setstate)(struct nvmm_cpu *); 132 void (*vcpu_getstate)(struct nvmm_cpu *); 133 int (*vcpu_inject)(struct nvmm_cpu *); 134 int (*vcpu_run)(struct nvmm_machine *, struct nvmm_cpu *, 135 struct nvmm_vcpu_exit *); 136 void (*vcpu_suspend)(struct nvmm_machine *, struct nvmm_cpu *); 137 void (*vcpu_resume)(struct nvmm_machine *, struct nvmm_cpu *); 138 }; 139 140 #if defined(__x86_64__) 141 extern const struct nvmm_impl nvmm_x86_svm; 142 extern const struct nvmm_impl nvmm_x86_vmx; 143 #endif 144 145 extern volatile bool nvmm_suspending; 146 147 static inline bool 148 nvmm_return_needed(struct nvmm_cpu *vcpu, struct nvmm_vcpu_exit *exit) 149 { 150 151 if (preempt_needed()) { 152 exit->reason = NVMM_VCPU_EXIT_NONE; 153 return true; 154 } 155 if (curlwp->l_flag & LW_USERRET) { 156 exit->reason = NVMM_VCPU_EXIT_NONE; 157 return true; 158 } 159 if (vcpu->comm->stop) { 160 exit->reason = NVMM_VCPU_EXIT_STOPPED; 161 return true; 162 } 163 if (atomic_load_relaxed(&nvmm_suspending)) { 164 exit->reason = NVMM_VCPU_EXIT_NONE; 165 return true; 166 } 167 168 return false; 169 } 170 171 #endif /* _NVMM_INTERNAL_H_ */ 172