L4Re Operating System Framework – Interface and Usage Documentation
Loading...
Searching...
No Matches
__vm-vmx.h
1
6/*
7 * (c) 2010-2013 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
8 * Alexander Warg <warg@os.inf.tu-dresden.de>
9 * economic rights: Technische Universität Dresden (Germany)
10 *
11 * This file is part of TUD:OS and distributed under the terms of the
12 * GNU General Public License 2.
13 * Please see the COPYING-GPL-2 file for details.
14 *
15 * As a special exception, you may use this file as part of a free software
16 * library without restriction. Specifically, if other files instantiate
17 * templates or use macros or inline functions from this file, or you compile
18 * this file and link it with other files to produce an executable, this
19 * file does not by itself cause the resulting executable to be covered by
20 * the GNU General Public License. This exception does not however
21 * invalidate any other reasons why the executable file might be covered by
22 * the GNU General Public License.
23 */
24#pragma once
25
26#include <l4/sys/vcpu.h>
27
56
57
70
81l4_vm_vmx_get_caps(void const *vcpu_state, unsigned cap_msr) L4_NOTHROW;
82
93l4_vm_vmx_get_caps_default1(void const *vcpu_state, unsigned cap_msr) L4_NOTHROW;
94
95
105enum
106{
129};
130
139unsigned
140l4_vm_vmx_field_len(unsigned field) L4_NOTHROW;
141
150unsigned
151l4_vm_vmx_field_order(unsigned field) L4_NOTHROW;
152
164void *
165l4_vm_vmx_field_ptr(void *vmcs, unsigned field) L4_NOTHROW;
166
177void
178l4_vm_vmx_clear(void *vmcs, void *user_vmcs) L4_NOTHROW;
179
190void
191l4_vm_vmx_ptr_load(void *vmcs, void *user_vmcs) L4_NOTHROW;
192
193
210l4_vm_vmx_get_cr2_index(void const *vmcs) L4_NOTHROW;
211
223l4_vm_vmx_read_nat(void *vmcs, unsigned field) L4_NOTHROW;
224
236l4_vm_vmx_read_16(void *vmcs, unsigned field) L4_NOTHROW;
237
249l4_vm_vmx_read_32(void *vmcs, unsigned field) L4_NOTHROW;
250
262l4_vm_vmx_read_64(void *vmcs, unsigned field) L4_NOTHROW;
263
275l4_vm_vmx_read(void *vmcs, unsigned field) L4_NOTHROW;
276
286void
287l4_vm_vmx_write_nat(void *vmcs, unsigned field, l4_umword_t val) L4_NOTHROW;
288
298void
299l4_vm_vmx_write_16(void *vmcs, unsigned field, l4_uint16_t val) L4_NOTHROW;
300
310void
311l4_vm_vmx_write_32(void *vmcs, unsigned field, l4_uint32_t val) L4_NOTHROW;
312
322void
323l4_vm_vmx_write_64(void *vmcs, unsigned field, l4_uint64_t val) L4_NOTHROW;
324
334void
335l4_vm_vmx_write(void *vmcs, unsigned field, l4_uint64_t val) L4_NOTHROW;
336
337
338/* Implementations */
339
341unsigned
343{
344 switch (field >> 13)
345 {
346 case 0: return 1;
347 case 1: return 3;
348 case 2: return 2;
349 case 3: if (sizeof(l4_umword_t) == 8) return 3; else return 2;
350 default: return 0;
351 }
352}
353
354
356unsigned
358{
359 return 1 << l4_vm_vmx_field_order(field);
360}
361
362
363/* Internal VCPU state layout:
364 *
365 * VCPU State:
366 * 0 - xxx: normal IA32 VCPU state (l4_vcpu_state_t)
367 * 200h: VMX capabilities (see l4_vm_vmx_get_caps)
368 * 400h: Fiasco.OC VMCS
369 *
370 * Fiasco.OC VMCS:
371 * 0h - 7h: Reserved
372 * 8h - Fh: ignored by kernel, stores current VMCS for l4_vm_vmx_clear...
373 * 10h - 13h: L4_VM_VMX_VMCS_CR2 value used by the kernel
374 * 14h - 1Fh: Reserved
375 * 20h - 3Fh: VMCS field offset table
376 * 40h - BFFh: Data (VMCS field data)
377 *
378 * VMCS field offset table:
379 * 0h - 2h: 3 offsets for 16bit fields:
380 * 0: Control fields, 1: read-only fields, 2: guest state
381 * all offsets in 64byte granules relative to the start of the VMCS
382 * 3h: Reserved
383 * 4h - 7h: Index shift values for 16bit, 64bit, 32bit, and natural width fields
384 * 8h - Ah: 3 offsets for 64bit fields
385 * Bh - Fh: Reserved
386 * 10h - 12h: 3 offsets for 32bit fields
387 * 13h - 17h: Reserved
388 * 18h - 1Ah: 3 offsets for natural width fields
389 * 1Bh: Reserved
390 * 1Ch: Offset of first VMCS field
391 * 1Dh: Full size of VMCS fields
392 * 1Eh - 1Fh: Reserved
393 *
394 */
395
397unsigned
398l4_vm_vmx_field_offset(void const *vmcs, unsigned field) L4_NOTHROW
399{
400 // the offset table is at 0x20 offset
401 enum { Si = 4 };
402 l4_uint8_t const *offsets = (l4_uint8_t const *)vmcs;
403 offsets += 0x20;
404 return (unsigned)offsets[field >> 10] * 64 + ((field & 0x3ff) << offsets[Si + (field >> 13)]);
405}
406
408void *
409l4_vm_vmx_field_ptr(void *vmcs, unsigned field) L4_NOTHROW
410{
411 return (void *)((char *)vmcs + l4_vm_vmx_field_offset(vmcs, field));
412}
413
419void
420l4_vm_vmx_copy_state(void const *vmcs, void *_dst, void const *_src) L4_NOTHROW
421{
422 l4_uint8_t const *offsets = (l4_uint8_t const *)vmcs + 0x20;
423
424 unsigned offs = offsets[28] * 64;
425 unsigned size = offsets[29] * 64;
426 char *const dst = (char*)_dst + offs;
427 char const *const src = (char const *)_src + offs;
428 __builtin_memcpy(dst, src, size);
429}
430
432void
433l4_vm_vmx_clear(void *vmcs, void *user_vmcs) L4_NOTHROW
434{
435 void **current_vmcs = (void **)((char *)vmcs + 8);
436 if (*current_vmcs != user_vmcs)
437 return;
438
439 l4_vm_vmx_copy_state(vmcs, user_vmcs, vmcs);
440 *current_vmcs = 0;
441}
442
444void
445l4_vm_vmx_ptr_load(void *vmcs, void *user_vmcs) L4_NOTHROW
446{
447 void **current_vmcs = (void **)((char *)vmcs + 8);
448 if (*current_vmcs == user_vmcs)
449 return;
450
451 if (*current_vmcs && *current_vmcs != user_vmcs)
452 l4_vm_vmx_clear(vmcs, *current_vmcs);
453
454 *current_vmcs = user_vmcs;
455 l4_vm_vmx_copy_state(vmcs, vmcs, user_vmcs);
456}
457
458
461l4_vm_vmx_read_nat(void *vmcs, unsigned field) L4_NOTHROW
462{ return *(l4_umword_t*)(l4_vm_vmx_field_ptr(vmcs, field)); }
463
466l4_vm_vmx_read_16(void *vmcs, unsigned field) L4_NOTHROW
467{ return *(l4_uint16_t*)(l4_vm_vmx_field_ptr(vmcs, field)); }
468
471l4_vm_vmx_read_32(void *vmcs, unsigned field) L4_NOTHROW
472{ return *(l4_uint32_t*)(l4_vm_vmx_field_ptr(vmcs, field)); }
473
476l4_vm_vmx_read_64(void *vmcs, unsigned field) L4_NOTHROW
477{ return *(l4_uint64_t*)(l4_vm_vmx_field_ptr(vmcs, field)); }
478
481l4_vm_vmx_read(void *vmcs, unsigned field) L4_NOTHROW
482{
483 switch(field >> 13)
484 {
485 case 0: return l4_vm_vmx_read_16(vmcs, field);
486 case 1: return l4_vm_vmx_read_64(vmcs, field);
487 case 2: return l4_vm_vmx_read_32(vmcs, field);
488 case 3: return l4_vm_vmx_read_nat(vmcs, field);
489 }
490 __builtin_trap();
491}
492
494void
495l4_vm_vmx_write_nat(void *vmcs, unsigned field, l4_umword_t val) L4_NOTHROW
496{ *(l4_umword_t*)(l4_vm_vmx_field_ptr(vmcs, field)) = val; }
497
499void
500l4_vm_vmx_write_16(void *vmcs, unsigned field, l4_uint16_t val) L4_NOTHROW
501{ *(l4_uint16_t*)(l4_vm_vmx_field_ptr(vmcs, field)) = val; }
502
504void
505l4_vm_vmx_write_32(void *vmcs, unsigned field, l4_uint32_t val) L4_NOTHROW
506{ *(l4_uint32_t*)(l4_vm_vmx_field_ptr(vmcs, field)) = val; }
507
509void
510l4_vm_vmx_write_64(void *vmcs, unsigned field, l4_uint64_t val) L4_NOTHROW
511{ *(l4_uint64_t*)(l4_vm_vmx_field_ptr(vmcs, field)) = val; }
512
513
515void
516l4_vm_vmx_write(void *vmcs, unsigned field, l4_uint64_t val) L4_NOTHROW
517{
518 switch(field >> 13)
519 {
520 case 0: l4_vm_vmx_write_16(vmcs, field, val); break;
521 case 1: l4_vm_vmx_write_64(vmcs, field, val); break;
522 case 2: l4_vm_vmx_write_32(vmcs, field, val); break;
523 case 3: l4_vm_vmx_write_nat(vmcs, field, val); break;
524 }
525}
526
529l4_vm_vmx_get_caps(void const *vcpu_state, unsigned cap_msr) L4_NOTHROW
530{
531 l4_uint64_t const *caps = (l4_uint64_t const *)((char const *)(vcpu_state) + L4_VCPU_OFFSET_EXT_INFOS);
532 return caps[cap_msr & 0xf];
533}
534
537l4_vm_vmx_get_caps_default1(void const *vcpu_state, unsigned cap_msr) L4_NOTHROW
538{
539 l4_uint32_t const *caps = (l4_uint32_t const *)((char const *)(vcpu_state) + L4_VCPU_OFFSET_EXT_INFOS);
540 return caps[L4_VM_VMX_NUM_CAPS_REGS * 2 + ((cap_msr & 0xf) - L4_VM_VMX_PINBASED_CTLS_DFL1_REG)];
541}
542
546{
547 l4_uint32_t const *infos = (l4_uint32_t const *)vmcs;
548 return infos[3];
549}
unsigned long l4_umword_t
Unsigned machine word.
Definition l4int.h:51
unsigned char l4_uint8_t
Unsigned 8bit value.
Definition l4int.h:36
unsigned int l4_uint32_t
Unsigned 32bit value.
Definition l4int.h:40
unsigned short int l4_uint16_t
Unsigned 16bit value.
Definition l4int.h:38
unsigned long long l4_uint64_t
Unsigned 64bit value.
Definition l4int.h:42
@ L4_VCPU_OFFSET_EXT_INFOS
Offset where extended infos begin.
Definition vcpu.h:192
void l4_vm_vmx_write_nat(void *vmcs, unsigned field, l4_umword_t val) L4_NOTHROW
Write to a natural width VMCS field.
Definition __vm-vmx.h:495
void l4_vm_vmx_ptr_load(void *vmcs, void *user_vmcs) L4_NOTHROW
Loads the user_vmcs as the current VMCS.
Definition __vm-vmx.h:445
l4_uint16_t l4_vm_vmx_read_16(void *vmcs, unsigned field) L4_NOTHROW
Read a 16bit VMCS field.
Definition __vm-vmx.h:466
unsigned l4_vm_vmx_field_order(unsigned field) L4_NOTHROW
Return length in power of two (bytes) of a VMCS field.
Definition __vm-vmx.h:342
void l4_vm_vmx_write_32(void *vmcs, unsigned field, l4_uint32_t val) L4_NOTHROW
Write to a 32bit VMCS field.
Definition __vm-vmx.h:505
l4_uint32_t l4_vm_vmx_get_cr2_index(void const *vmcs) L4_NOTHROW
Get the VMCS field index of the virtual CR2 register.
Definition __vm-vmx.h:545
void l4_vm_vmx_clear(void *vmcs, void *user_vmcs) L4_NOTHROW
Saves cached state from the kernel VMCS to the user VMCS.
Definition __vm-vmx.h:433
l4_uint64_t l4_vm_vmx_read(void *vmcs, unsigned field) L4_NOTHROW
Read any VMCS field.
Definition __vm-vmx.h:481
l4_uint32_t l4_vm_vmx_read_32(void *vmcs, unsigned field) L4_NOTHROW
Read a 32bit VMCS field.
Definition __vm-vmx.h:471
unsigned l4_vm_vmx_field_len(unsigned field) L4_NOTHROW
Return length in bytes of a VMCS field.
Definition __vm-vmx.h:357
L4_vm_vmx_caps_regs
Exported VMX capability registers.
Definition __vm-vmx.h:40
l4_uint32_t l4_vm_vmx_get_caps_default1(void const *vcpu_state, unsigned cap_msr) L4_NOTHROW
Get a default to one capability register for VMX.
Definition __vm-vmx.h:537
void l4_vm_vmx_write(void *vmcs, unsigned field, l4_uint64_t val) L4_NOTHROW
Write to an arbitrary VMCS field.
Definition __vm-vmx.h:516
void l4_vm_vmx_write_64(void *vmcs, unsigned field, l4_uint64_t val) L4_NOTHROW
Write to a 64bit VMCS field.
Definition __vm-vmx.h:510
l4_umword_t l4_vm_vmx_read_nat(void *vmcs, unsigned field) L4_NOTHROW
Read a natural width VMCS field.
Definition __vm-vmx.h:461
l4_uint64_t l4_vm_vmx_read_64(void *vmcs, unsigned field) L4_NOTHROW
Read a 64bit VMCS field.
Definition __vm-vmx.h:476
L4_vm_vmx_dfl1_regs
Exported VMX capability registers (default to 1 bits).
Definition __vm-vmx.h:63
l4_uint64_t l4_vm_vmx_get_caps(void const *vcpu_state, unsigned cap_msr) L4_NOTHROW
Get a capability register for VMX.
Definition __vm-vmx.h:529
void l4_vm_vmx_write_16(void *vmcs, unsigned field, l4_uint16_t val) L4_NOTHROW
Write to a 16bit VMCS field.
Definition __vm-vmx.h:500
@ L4_VM_VMX_VMCS_MSR_LSTAR
VMCS offset of IA32e mode system call target address MSR.
Definition __vm-vmx.h:120
@ L4_VM_VMX_VMCS_MSR_STAR
VMCS offset of system call target address MSR.
Definition __vm-vmx.h:126
@ L4_VM_VMX_VMCS_CR2
VMCS offset for CR2.
Definition __vm-vmx.h:114
@ L4_VM_VMX_VMCS_XCR0
VMCS offset of extended control register XCR0.
Definition __vm-vmx.h:116
@ L4_VM_VMX_VMCS_MSR_TSC_AUX
VMCS offset of auxiliary TSC signature MSR.
Definition __vm-vmx.h:124
@ L4_VM_VMX_VMCS_MSR_KERNEL_GS_BASE
VMCS offset of GS base address swap target MSR.
Definition __vm-vmx.h:128
@ L4_VM_VMX_VMCS_MSR_SYSCALL_MASK
VMCS offset of system call flag mask MSR.
Definition __vm-vmx.h:118
@ L4_VM_VMX_VMCS_MSR_CSTAR
VMCS offset of IA32 mode system call target address MSR.
Definition __vm-vmx.h:122
@ L4_VM_VMX_TRUE_PROCBASED_CTLS_REG
True processor based control caps.
Definition __vm-vmx.h:43
@ L4_VM_VMX_MISC_REG
Misc caps.
Definition __vm-vmx.h:46
@ L4_VM_VMX_PROCBASED_CTLS2_REG
Processor based control 2 caps.
Definition __vm-vmx.h:52
@ L4_VM_VMX_EPT_VPID_CAP_REG
EPT and VPID caps.
Definition __vm-vmx.h:53
@ L4_VM_VMX_CR4_FIXED1_REG
Fixed to 1 bits of CR4.
Definition __vm-vmx.h:50
@ L4_VM_VMX_NUM_CAPS_REGS
Total number of VMX capability registers.
Definition __vm-vmx.h:54
@ L4_VM_VMX_CR4_FIXED0_REG
Fixed to 0 bits of CR4.
Definition __vm-vmx.h:49
@ L4_VM_VMX_TRUE_ENTRY_CTLS_REG
True entry control caps.
Definition __vm-vmx.h:45
@ L4_VM_VMX_CR0_FIXED1_REG
Fixed to 1 bits of CR0.
Definition __vm-vmx.h:48
@ L4_VM_VMX_CR0_FIXED0_REG
Fixed to 0 bits of CR0.
Definition __vm-vmx.h:47
@ L4_VM_VMX_VMCS_ENUM_REG
VMCS enumeration info.
Definition __vm-vmx.h:51
@ L4_VM_VMX_TRUE_EXIT_CTLS_REG
True exit control caps.
Definition __vm-vmx.h:44
@ L4_VM_VMX_TRUE_PINBASED_CTLS_REG
True pin-based control caps.
Definition __vm-vmx.h:42
@ L4_VM_VMX_BASIC_REG
Basic VMX capabilities.
Definition __vm-vmx.h:41
@ L4_VM_VMX_ENTRY_CTLS_DFL1_REG
Default 1 bits in entry controls.
Definition __vm-vmx.h:67
@ L4_VM_VMX_EXIT_CTLS_DFL1_REG
Default 1 bits in exit controls.
Definition __vm-vmx.h:66
@ L4_VM_VMX_PINBASED_CTLS_DFL1_REG
Default 1 bits in pin-based controls.
Definition __vm-vmx.h:64
@ L4_VM_VMX_NUM_DFL1_REGS
Total number of default on registers.
Definition __vm-vmx.h:68
@ L4_VM_VMX_PROCBASED_CTLS_DFL1_REG
Default 1 bits in processor-based controls.
Definition __vm-vmx.h:65
#define L4_NOTHROW
Mark a function declaration and definition as never throwing an exception.
Definition compiler.h:188
#define L4_INLINE
L4 Inline function attribute.
Definition compiler.h:62
vCPU API