1 /****************************************************************************** 2 * vm_event.h 3 * 4 * Memory event common structures. 5 * 6 * Copyright (c) 2009 by Citrix Systems, Inc. (Patrick Colp) 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * of this software and associated documentation files (the "Software"), to 10 * deal in the Software without restriction, including without limitation the 11 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 12 * sell copies of the Software, and to permit persons to whom the Software is 13 * furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included in 16 * all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 * DEALINGS IN THE SOFTWARE. 25 */ 26 27 #ifndef _XEN_PUBLIC_VM_EVENT_H 28 #define _XEN_PUBLIC_VM_EVENT_H 29 30 #include "xen.h" 31 32 #define VM_EVENT_INTERFACE_VERSION 0x00000006 33 34 #if defined(__XEN__) || defined(__XEN_TOOLS__) 35 36 #include "io/ring.h" 37 38 /* 39 * Memory event flags 40 */ 41 42 /* 43 * VCPU_PAUSED in a request signals that the vCPU triggering the event has been 44 * paused 45 * VCPU_PAUSED in a response signals to unpause the vCPU 46 */ 47 #define VM_EVENT_FLAG_VCPU_PAUSED (1 << 0) 48 /* Flags to aid debugging vm_event */ 49 #define VM_EVENT_FLAG_FOREIGN (1 << 1) 50 /* 51 * The following flags can be set in response to a mem_access event. 52 * 53 * Emulate the fault-causing instruction (if set in the event response flags). 54 * This will allow the guest to continue execution without lifting the page 55 * access restrictions. 56 */ 57 #define VM_EVENT_FLAG_EMULATE (1 << 2) 58 /* 59 * Same as VM_EVENT_FLAG_EMULATE, but with write operations or operations 60 * potentially having side effects (like memory mapped or port I/O) disabled. 61 */ 62 #define VM_EVENT_FLAG_EMULATE_NOWRITE (1 << 3) 63 /* 64 * Toggle singlestepping on vm_event response. 65 * Requires the vCPU to be paused already (synchronous events only). 66 */ 67 #define VM_EVENT_FLAG_TOGGLE_SINGLESTEP (1 << 4) 68 /* 69 * Data is being sent back to the hypervisor in the event response, to be 70 * returned by the read function when emulating an instruction. 71 * This flag is only useful when combined with VM_EVENT_FLAG_EMULATE 72 * and takes precedence if combined with VM_EVENT_FLAG_EMULATE_NOWRITE 73 * (i.e. if both VM_EVENT_FLAG_EMULATE_NOWRITE and 74 * VM_EVENT_FLAG_SET_EMUL_READ_DATA are set, only the latter will be honored). 75 */ 76 #define VM_EVENT_FLAG_SET_EMUL_READ_DATA (1 << 5) 77 /* 78 * Deny completion of the operation that triggered the event. 79 * Currently only useful for MSR and control-register write events. 80 * Requires the vCPU to be paused already (synchronous events only). 81 */ 82 #define VM_EVENT_FLAG_DENY (1 << 6) 83 /* 84 * This flag can be set in a request or a response 85 * 86 * On a request, indicates that the event occurred in the alternate p2m 87 * specified by the altp2m_idx request field. 88 * 89 * On a response, indicates that the VCPU should resume in the alternate p2m 90 * specified by the altp2m_idx response field if possible. 91 */ 92 #define VM_EVENT_FLAG_ALTERNATE_P2M (1 << 7) 93 /* 94 * Set the vCPU registers to the values in the vm_event response. 95 * At the moment x86-only, applies to EAX-EDX, ESP, EBP, ESI, EDI, R8-R15, 96 * EFLAGS, and EIP. 97 * Requires the vCPU to be paused already (synchronous events only). 98 */ 99 #define VM_EVENT_FLAG_SET_REGISTERS (1 << 8) 100 /* 101 * Instruction cache is being sent back to the hypervisor in the event response 102 * to be used by the emulator. This flag is only useful when combined with 103 * VM_EVENT_FLAG_EMULATE and does not take presedence if combined with 104 * VM_EVENT_FLAG_EMULATE_NOWRITE or VM_EVENT_FLAG_SET_EMUL_READ_DATA, (i.e. 105 * if any of those flags are set, only those will be honored). 106 */ 107 #define VM_EVENT_FLAG_SET_EMUL_INSN_DATA (1 << 9) 108 /* 109 * Have a one-shot VM_EVENT_REASON_INTERRUPT event sent for the first 110 * interrupt pending after resuming the VCPU. 111 */ 112 #define VM_EVENT_FLAG_GET_NEXT_INTERRUPT (1 << 10) 113 /* 114 * Execute fast singlestepping on vm_event response. 115 * Requires the vCPU to be paused already (synchronous events only). 116 * 117 * On a response requires setting the p2midx field of fast_singlestep to which 118 * Xen will switch the vCPU to on the occurance of the first singlestep, after 119 * which singlestep gets automatically disabled. 120 */ 121 #define VM_EVENT_FLAG_FAST_SINGLESTEP (1 << 11) 122 123 /* 124 * Reasons for the vm event request 125 */ 126 127 /* Default case */ 128 #define VM_EVENT_REASON_UNKNOWN 0 129 /* Memory access violation */ 130 #define VM_EVENT_REASON_MEM_ACCESS 1 131 /* Memory sharing event */ 132 #define VM_EVENT_REASON_MEM_SHARING 2 133 /* Memory paging event */ 134 #define VM_EVENT_REASON_MEM_PAGING 3 135 /* A control register was updated */ 136 #define VM_EVENT_REASON_WRITE_CTRLREG 4 137 /* An MSR was updated. */ 138 #define VM_EVENT_REASON_MOV_TO_MSR 5 139 /* Debug operation executed (e.g. int3) */ 140 #define VM_EVENT_REASON_SOFTWARE_BREAKPOINT 6 141 /* Single-step (e.g. MTF) */ 142 #define VM_EVENT_REASON_SINGLESTEP 7 143 /* An event has been requested via HVMOP_guest_request_vm_event. */ 144 #define VM_EVENT_REASON_GUEST_REQUEST 8 145 /* A debug exception was caught */ 146 #define VM_EVENT_REASON_DEBUG_EXCEPTION 9 147 /* CPUID executed */ 148 #define VM_EVENT_REASON_CPUID 10 149 /* 150 * Privileged call executed (e.g. SMC). 151 * Note: event may be generated even if SMC condition check fails on some CPUs. 152 * As this behavior is CPU-specific, users are advised to not rely on it. 153 * These kinds of events will be filtered out in future versions. 154 */ 155 #define VM_EVENT_REASON_PRIVILEGED_CALL 11 156 /* An interrupt has been delivered. */ 157 #define VM_EVENT_REASON_INTERRUPT 12 158 /* A descriptor table register was accessed. */ 159 #define VM_EVENT_REASON_DESCRIPTOR_ACCESS 13 160 /* Current instruction is not implemented by the emulator */ 161 #define VM_EVENT_REASON_EMUL_UNIMPLEMENTED 14 162 163 /* Supported values for the vm_event_write_ctrlreg index. */ 164 #define VM_EVENT_X86_CR0 0 165 #define VM_EVENT_X86_CR3 1 166 #define VM_EVENT_X86_CR4 2 167 #define VM_EVENT_X86_XCR0 3 168 169 /* The limit field is right-shifted by 12 bits if .ar.g is set. */ 170 struct vm_event_x86_selector_reg { 171 uint32_t limit : 20; 172 uint32_t ar : 12; 173 }; 174 175 /* 176 * Using custom vCPU structs (i.e. not hvm_hw_cpu) for both x86 and ARM 177 * so as to not fill the vm_event ring buffer too quickly. 178 */ 179 struct vm_event_regs_x86 { 180 uint64_t rax; 181 uint64_t rcx; 182 uint64_t rdx; 183 uint64_t rbx; 184 uint64_t rsp; 185 uint64_t rbp; 186 uint64_t rsi; 187 uint64_t rdi; 188 uint64_t r8; 189 uint64_t r9; 190 uint64_t r10; 191 uint64_t r11; 192 uint64_t r12; 193 uint64_t r13; 194 uint64_t r14; 195 uint64_t r15; 196 uint64_t rflags; 197 uint64_t dr6; 198 uint64_t dr7; 199 uint64_t rip; 200 uint64_t cr0; 201 uint64_t cr2; 202 uint64_t cr3; 203 uint64_t cr4; 204 uint64_t sysenter_cs; 205 uint64_t sysenter_esp; 206 uint64_t sysenter_eip; 207 uint64_t msr_efer; 208 uint64_t msr_star; 209 uint64_t msr_lstar; 210 uint64_t gdtr_base; 211 uint32_t cs_base; 212 uint32_t ss_base; 213 uint32_t ds_base; 214 uint32_t es_base; 215 uint64_t fs_base; 216 uint64_t gs_base; 217 struct vm_event_x86_selector_reg cs; 218 struct vm_event_x86_selector_reg ss; 219 struct vm_event_x86_selector_reg ds; 220 struct vm_event_x86_selector_reg es; 221 struct vm_event_x86_selector_reg fs; 222 struct vm_event_x86_selector_reg gs; 223 uint64_t shadow_gs; 224 uint16_t gdtr_limit; 225 uint16_t cs_sel; 226 uint16_t ss_sel; 227 uint16_t ds_sel; 228 uint16_t es_sel; 229 uint16_t fs_sel; 230 uint16_t gs_sel; 231 uint16_t _pad; 232 }; 233 234 /* 235 * Only the register 'pc' can be set on a vm_event response using the 236 * VM_EVENT_FLAG_SET_REGISTERS flag. 237 */ 238 struct vm_event_regs_arm { 239 uint64_t ttbr0; 240 uint64_t ttbr1; 241 uint64_t ttbcr; 242 uint64_t pc; 243 uint32_t cpsr; 244 uint32_t _pad; 245 }; 246 247 /* 248 * mem_access flag definitions 249 * 250 * These flags are set only as part of a mem_event request. 251 * 252 * R/W/X: Defines the type of violation that has triggered the event 253 * Multiple types can be set in a single violation! 254 * GLA_VALID: If the gla field holds a guest VA associated with the event 255 * FAULT_WITH_GLA: If the violation was triggered by accessing gla 256 * FAULT_IN_GPT: If the violation was triggered during translating gla 257 */ 258 #define MEM_ACCESS_R (1 << 0) 259 #define MEM_ACCESS_W (1 << 1) 260 #define MEM_ACCESS_X (1 << 2) 261 #define MEM_ACCESS_RWX (MEM_ACCESS_R | MEM_ACCESS_W | MEM_ACCESS_X) 262 #define MEM_ACCESS_RW (MEM_ACCESS_R | MEM_ACCESS_W) 263 #define MEM_ACCESS_RX (MEM_ACCESS_R | MEM_ACCESS_X) 264 #define MEM_ACCESS_WX (MEM_ACCESS_W | MEM_ACCESS_X) 265 #define MEM_ACCESS_GLA_VALID (1 << 3) 266 #define MEM_ACCESS_FAULT_WITH_GLA (1 << 4) 267 #define MEM_ACCESS_FAULT_IN_GPT (1 << 5) 268 269 struct vm_event_mem_access { 270 uint64_t gfn; 271 uint64_t offset; 272 uint64_t gla; /* if flags has MEM_ACCESS_GLA_VALID set */ 273 uint32_t flags; /* MEM_ACCESS_* */ 274 uint32_t _pad; 275 }; 276 277 struct vm_event_write_ctrlreg { 278 uint32_t index; 279 uint32_t _pad; 280 uint64_t new_value; 281 uint64_t old_value; 282 }; 283 284 struct vm_event_singlestep { 285 uint64_t gfn; 286 }; 287 288 struct vm_event_fast_singlestep { 289 uint16_t p2midx; 290 }; 291 292 struct vm_event_debug { 293 uint64_t gfn; 294 uint64_t pending_dbg; /* Behaves like the VT-x PENDING_DBG field. */ 295 uint32_t insn_length; 296 uint8_t type; /* HVMOP_TRAP_* */ 297 uint8_t _pad[3]; 298 }; 299 300 struct vm_event_mov_to_msr { 301 uint64_t msr; 302 uint64_t new_value; 303 uint64_t old_value; 304 }; 305 306 #define VM_EVENT_DESC_IDTR 1 307 #define VM_EVENT_DESC_GDTR 2 308 #define VM_EVENT_DESC_LDTR 3 309 #define VM_EVENT_DESC_TR 4 310 311 struct vm_event_desc_access { 312 union { 313 struct { 314 uint32_t instr_info; /* VMX: VMCS Instruction-Information */ 315 uint32_t _pad1; 316 uint64_t exit_qualification; /* VMX: VMCS Exit Qualification */ 317 } vmx; 318 } arch; 319 uint8_t descriptor; /* VM_EVENT_DESC_* */ 320 uint8_t is_write; 321 uint8_t _pad[6]; 322 }; 323 324 struct vm_event_cpuid { 325 uint32_t insn_length; 326 uint32_t leaf; 327 uint32_t subleaf; 328 uint32_t _pad; 329 }; 330 331 struct vm_event_interrupt_x86 { 332 uint32_t vector; 333 uint32_t type; 334 uint32_t error_code; 335 uint32_t _pad; 336 uint64_t cr2; 337 }; 338 339 #define MEM_PAGING_DROP_PAGE (1 << 0) 340 #define MEM_PAGING_EVICT_FAIL (1 << 1) 341 342 struct vm_event_paging { 343 uint64_t gfn; 344 uint32_t p2mt; 345 uint32_t flags; 346 }; 347 348 struct vm_event_sharing { 349 uint64_t gfn; 350 uint32_t p2mt; 351 uint32_t _pad; 352 }; 353 354 struct vm_event_emul_read_data { 355 uint32_t size; 356 /* The struct is used in a union with vm_event_regs_x86. */ 357 uint8_t data[sizeof(struct vm_event_regs_x86) - sizeof(uint32_t)]; 358 }; 359 360 struct vm_event_emul_insn_data { 361 uint8_t data[16]; /* Has to be completely filled */ 362 }; 363 364 typedef struct vm_event_st { 365 uint32_t version; /* VM_EVENT_INTERFACE_VERSION */ 366 uint32_t flags; /* VM_EVENT_FLAG_* */ 367 uint32_t reason; /* VM_EVENT_REASON_* */ 368 uint32_t vcpu_id; 369 uint16_t altp2m_idx; /* may be used during request and response */ 370 uint16_t _pad[3]; 371 372 union { 373 struct vm_event_paging mem_paging; 374 struct vm_event_sharing mem_sharing; 375 struct vm_event_mem_access mem_access; 376 struct vm_event_write_ctrlreg write_ctrlreg; 377 struct vm_event_mov_to_msr mov_to_msr; 378 struct vm_event_desc_access desc_access; 379 struct vm_event_singlestep singlestep; 380 struct vm_event_fast_singlestep fast_singlestep; 381 struct vm_event_debug software_breakpoint; 382 struct vm_event_debug debug_exception; 383 struct vm_event_cpuid cpuid; 384 union { 385 struct vm_event_interrupt_x86 x86; 386 } interrupt; 387 } u; 388 389 union { 390 union { 391 struct vm_event_regs_x86 x86; 392 struct vm_event_regs_arm arm; 393 } regs; 394 395 union { 396 struct vm_event_emul_read_data read; 397 struct vm_event_emul_insn_data insn; 398 } emul; 399 } data; 400 } vm_event_request_t, vm_event_response_t; 401 402 DEFINE_RING_TYPES(vm_event, vm_event_request_t, vm_event_response_t); 403 404 #endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */ 405 #endif /* _XEN_PUBLIC_VM_EVENT_H */ 406 407 /* 408 * Local variables: 409 * mode: C 410 * c-file-style: "BSD" 411 * c-basic-offset: 4 412 * tab-width: 4 413 * indent-tabs-mode: nil 414 * End: 415 */ 416