L4Re Operating System Framework
Interface and Usage Documentation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
__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 * License: see LICENSE.spdx (in this directory or the directories above)
12 */
13
14#pragma once
15
16#include <l4/sys/vcpu.h>
17
46
59
102
156{
157 l4_uint8_t offsets[4][4];
158 l4_uint8_t limits[4][4];
159 l4_uint8_t index_shifts[4];
160 l4_uint8_t base_offset;
161 l4_uint8_t size;
162
163 l4_uint8_t reserved[2];
165
177
206{
207 l4_uint64_t reserved0;
208
209 l4_uint64_t user_data;
210 l4_uint32_t cr2_index;
211 l4_uint8_t reserved1[4];
212
213 l4_cap_idx_t vmcs;
214
215 /*
216 * Since the capability type size depends on the platform, we add a 32-bit
217 * padding if necessary.
218 */
219
220#if L4_MWORD_BITS == 32
221 l4_uint32_t padding0;
222#elif L4_MWORD_BITS == 64
223 /* No padding needed. */
224#else
225 #error Unsupported machine word size.
226#endif
227
228 l4_vmx_offset_table_t offset_table;
229 l4_uint8_t reserved2[120];
230
234
248
278
291 enum L4_vm_vmx_caps_regs caps_reg) L4_NOTHROW;
292
306 enum L4_vm_vmx_dfl1_regs dfl1_reg) L4_NOTHROW;
307
316unsigned
317l4_vm_vmx_field_len(unsigned field) L4_NOTHROW;
318
327unsigned
328l4_vm_vmx_field_order(unsigned field) L4_NOTHROW;
329
345void *
346l4_vm_vmx_field_ptr(l4_vm_vmx_vcpu_vmcs_t *vmcs, unsigned field) L4_NOTHROW;
347
358void
361
372void
375
394
407
420
433
446
458l4_vm_vmx_read(l4_vm_vmx_vcpu_vmcs_t *vmcs, unsigned field) L4_NOTHROW;
459
469void
470l4_vm_vmx_write_nat(l4_vm_vmx_vcpu_vmcs_t *vmcs, unsigned field,
472
482void
483l4_vm_vmx_write_16(l4_vm_vmx_vcpu_vmcs_t *vmcs, unsigned field,
485
495void
496l4_vm_vmx_write_32(l4_vm_vmx_vcpu_vmcs_t *vmcs, unsigned field,
498
508void
509l4_vm_vmx_write_64(l4_vm_vmx_vcpu_vmcs_t *vmcs, unsigned field,
511
521void
522l4_vm_vmx_write(l4_vm_vmx_vcpu_vmcs_t *vmcs, unsigned field,
524
572void
574 l4_cap_idx_t vmcs_cap) L4_NOTHROW;
575
588
589/* Implementations */
590
592unsigned
594{
595 return 1 << l4_vm_vmx_field_order(field);
596}
597
599unsigned
601{
602 unsigned size = (field >> 13) & 0x03U;
603
604 switch (size)
605 {
606 case 0: return 1; /* 16 bits */
607 case 1: return 3; /* 64 bits */
608 case 2: return 2; /* 32 bits */
609 case 3: return (sizeof(l4_umword_t) == 8) ? 3 : 2; /* Natural width */
610 }
611
612 __builtin_trap();
613}
614
621unsigned
622l4_vm_vmx_field_offset(l4_vm_vmx_vcpu_vmcs_t const *vmcs,
623 unsigned field) L4_NOTHROW
624{
625 unsigned index = field & 0x3feU;
626 unsigned size = (field >> 13) & 0x03U;
627 unsigned group = (field >> 10) & 0x03U;
628
629 unsigned shifted_index = index << vmcs->offset_table.index_shifts[size];
630
631 if (shifted_index >= (unsigned)vmcs->offset_table.limits[size][group] * 64)
632 return ~0U;
633
634 return (unsigned)vmcs->offset_table.offsets[size][group] * 64
635 + shifted_index;
636}
637
639void *
640l4_vm_vmx_field_ptr(l4_vm_vmx_vcpu_vmcs_t *vmcs, unsigned field) L4_NOTHROW
641{
642 unsigned offset = l4_vm_vmx_field_offset(vmcs, field);
643 if (offset == ~0U)
644 return 0;
645
646 return (void *)(vmcs->values + offset);
647}
648
655void *
656l4_vm_vmx_field_ptr_offset(l4_vm_vmx_vcpu_vmcs_t *vmcs, unsigned field,
657 unsigned *offset) L4_NOTHROW
658{
659 *offset = l4_vm_vmx_field_offset(vmcs, field);
660 if (*offset == ~0U)
661 return 0;
662
663 return (void *)(vmcs->values + *offset);
664}
665
672void
673l4_vm_vmx_offset_dirty(l4_vm_vmx_vcpu_vmcs_t *vmcs,
674 unsigned offset) L4_NOTHROW
675{
676 vmcs->dirty_bitmap[offset / 8] |= 1U << (offset % 8);
677}
678
684void
685l4_vm_vmx_copy_values(l4_vm_vmx_vcpu_vmcs_t const *vmcs, l4_uint8_t *_dst,
686 l4_uint8_t const *_src) L4_NOTHROW
687{
688 unsigned base_offset = vmcs->offset_table.base_offset * 64;
689 unsigned size = vmcs->offset_table.size * 64;
690
691 void *dst = _dst + base_offset;
692 void const *src = _src + base_offset;
693 __builtin_memcpy(dst, src, size);
694}
695
697void
700{
701 l4_vm_vmx_vcpu_vmcs_t **current_vmcs_ptr
702 = (l4_vm_vmx_vcpu_vmcs_t **)&vmcs->user_data;
703
704 if (*current_vmcs_ptr != dest_vmcs)
705 return;
706
708 l4_vm_vmx_copy_values(vmcs, dest_vmcs->values, vmcs->values);
709
710 /* Due to its size, the dirty bitmap is always compied in its entirety. */
711 __builtin_memcpy(dest_vmcs->dirty_bitmap, vmcs->dirty_bitmap,
713
714 *current_vmcs_ptr = 0;
715}
716
718void
721{
722 l4_vm_vmx_vcpu_vmcs_t **current_vmcs_ptr
723 = (l4_vm_vmx_vcpu_vmcs_t **)&vmcs->user_data;
724
725 if (*current_vmcs_ptr == src_vmcs)
726 return;
727
728 if (*current_vmcs_ptr && *current_vmcs_ptr != src_vmcs)
729 l4_vm_vmx_clear(vmcs, *current_vmcs_ptr);
730
731 *current_vmcs_ptr = src_vmcs;
732
734 l4_vm_vmx_copy_values(vmcs, vmcs->values, src_vmcs->values);
735
736 /* Due to its size, the dirty bitmap is always compied in its entirety. */
737 __builtin_memcpy(vmcs->dirty_bitmap, src_vmcs->dirty_bitmap,
739}
740
744{
745 l4_umword_t *ptr = (l4_umword_t *)l4_vm_vmx_field_ptr(vmcs, field);
746 if (!ptr)
747 return 0;
748
749 return *ptr;
750}
751
755{
756 l4_uint16_t *ptr = (l4_uint16_t *)l4_vm_vmx_field_ptr(vmcs, field);
757 if (!ptr)
758 return 0;
759
760 return *ptr;
761}
762
766{
767 l4_uint32_t *ptr = (l4_uint32_t *)l4_vm_vmx_field_ptr(vmcs, field);
768 if (!ptr)
769 return 0;
770
771 return *ptr;
772}
773
777{
778 l4_uint64_t *ptr = (l4_uint64_t *)l4_vm_vmx_field_ptr(vmcs, field);
779 if (!ptr)
780 return 0;
781
782 return *ptr;
783}
784
788{
789 unsigned size = (field >> 13) & 0x03U;
790
791 switch (size)
792 {
793 case 0: return l4_vm_vmx_read_16(vmcs, field);
794 case 1: return l4_vm_vmx_read_64(vmcs, field);
795 case 2: return l4_vm_vmx_read_32(vmcs, field);
796 case 3: return l4_vm_vmx_read_nat(vmcs, field);
797 }
798
799 __builtin_trap();
800}
801
803void
806{
807 unsigned offset;
808 l4_umword_t *ptr
809 = (l4_umword_t *)l4_vm_vmx_field_ptr_offset(vmcs, field, &offset);
810
811 if ((ptr) && (*ptr != val))
812 {
813 *ptr = val;
814 l4_vm_vmx_offset_dirty(vmcs, offset);
815 }
816}
817
819void
822{
823 unsigned offset;
824 l4_uint16_t *ptr
825 = (l4_uint16_t *)l4_vm_vmx_field_ptr_offset(vmcs, field, &offset);
826
827 if ((ptr) && (*ptr != val))
828 {
829 *ptr = val;
830 l4_vm_vmx_offset_dirty(vmcs, offset);
831 }
832}
833
835void
838{
839 unsigned offset;
840 l4_uint32_t *ptr
841 = (l4_uint32_t *)l4_vm_vmx_field_ptr_offset(vmcs, field, &offset);
842
843 if ((ptr) && (*ptr != val))
844 {
845 *ptr = val;
846 l4_vm_vmx_offset_dirty(vmcs, offset);
847 }
848}
849
851void
854{
855 unsigned offset;
856 l4_uint64_t *ptr
857 = (l4_uint64_t *)l4_vm_vmx_field_ptr_offset(vmcs, field, &offset);
858
859 if ((ptr) && (*ptr != val))
860 {
861 *ptr = val;
862 l4_vm_vmx_offset_dirty(vmcs, offset);
863 }
864}
865
867void
870{
871 unsigned size = (field >> 13) & 0x03U;
872
873 switch (size)
874 {
875 case 0: l4_vm_vmx_write_16(vmcs, field, val); break;
876 case 1: l4_vm_vmx_write_64(vmcs, field, val); break;
877 case 2: l4_vm_vmx_write_32(vmcs, field, val); break;
878 case 3: l4_vm_vmx_write_nat(vmcs, field, val); break;
879 }
880}
881
885 enum L4_vm_vmx_caps_regs caps_reg) L4_NOTHROW
886{
887 return vcpu_state->infos.caps[caps_reg];
888}
889
893 enum L4_vm_vmx_dfl1_regs dfl1_reg) L4_NOTHROW
894{
895 return vcpu_state->infos.dfl1[dfl1_reg];
896}
897
901{
902 return vmcs->cr2_index;
903}
904
906void
908 l4_cap_idx_t vmcs_cap) L4_NOTHROW
909{
910 vmcs->vmcs = vmcs_cap;
911}
912
916{
917 return vmcs->vmcs & L4_CAP_MASK;
918}
unsigned long l4_umword_t
Unsigned machine word.
Definition l4int.h:40
unsigned char l4_uint8_t
Unsigned 8bit value.
Definition l4int.h:25
unsigned int l4_uint32_t
Unsigned 32bit value.
Definition l4int.h:29
unsigned short int l4_uint16_t
Unsigned 16bit value.
Definition l4int.h:27
unsigned long long l4_uint64_t
Unsigned 64bit value.
Definition l4int.h:31
unsigned long l4_cap_idx_t
Capability selector type.
Definition types.h:335
@ L4_CAP_MASK
Mask to get only the relevant bits of an l4_cap_idx_t.
Definition consts.h:155
@ L4_VCPU_OFFSET_EXT_INFOS
Offset where extended infos begin.
Definition __vcpu-arch.h:38
@ L4_VCPU_OFFSET_EXT_STATE
Offset where extended state begins.
Definition __vcpu-arch.h:37
void l4_vm_vmx_write_nat(l4_vm_vmx_vcpu_vmcs_t *vmcs, unsigned field, l4_umword_t val) L4_NOTHROW
Write to a natural-width software VMCS field.
Definition __vm-vmx.h:804
void l4_vm_vmx_write(l4_vm_vmx_vcpu_vmcs_t *vmcs, unsigned field, l4_uint64_t val) L4_NOTHROW
Write to an arbitrary software VMCS field.
Definition __vm-vmx.h:868
l4_umword_t l4_vm_vmx_read_nat(l4_vm_vmx_vcpu_vmcs_t *vmcs, unsigned field) L4_NOTHROW
Read a natural-width software VMCS field.
Definition __vm-vmx.h:743
L4_vm_vmx_sw_fields
Additional (software-defined) VMCS fields.
Definition __vm-vmx.h:70
l4_uint64_t l4_vm_vmx_read_64(l4_vm_vmx_vcpu_vmcs_t *vmcs, unsigned field) L4_NOTHROW
Read a 64-bit software VMCS field.
Definition __vm-vmx.h:776
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:600
void l4_vm_vmx_ptr_load(l4_vm_vmx_vcpu_vmcs_t *vmcs, l4_vm_vmx_vcpu_vmcs_t *src_vmcs) L4_NOTHROW
Load the content from a different software VMCS to the software VMCS.
Definition __vm-vmx.h:719
l4_cap_idx_t l4_vm_vmx_get_hw_vmcs(l4_vm_vmx_vcpu_vmcs_t *vmcs) L4_NOTHROW
Get the vCPU context (i.e.
Definition __vm-vmx.h:915
l4_uint32_t l4_vm_vmx_get_cr2_index(l4_vm_vmx_vcpu_vmcs_t const *vmcs) L4_NOTHROW
Get the software VMCS field index of the virtual CR2 register.
Definition __vm-vmx.h:900
l4_uint16_t l4_vm_vmx_read_16(l4_vm_vmx_vcpu_vmcs_t *vmcs, unsigned field) L4_NOTHROW
Read a 16-bit software VMCS field.
Definition __vm-vmx.h:754
void l4_vm_vmx_write_64(l4_vm_vmx_vcpu_vmcs_t *vmcs, unsigned field, l4_uint64_t val) L4_NOTHROW
Write to a 64-bit software VMCS field.
Definition __vm-vmx.h:852
void l4_vm_vmx_write_16(l4_vm_vmx_vcpu_vmcs_t *vmcs, unsigned field, l4_uint16_t val) L4_NOTHROW
Write to a 16-bit software VMCS field.
Definition __vm-vmx.h:820
l4_uint64_t l4_vm_vmx_read(l4_vm_vmx_vcpu_vmcs_t *vmcs, unsigned field) L4_NOTHROW
Read any software VMCS field.
Definition __vm-vmx.h:787
void l4_vm_vmx_set_hw_vmcs(l4_vm_vmx_vcpu_vmcs_t *vmcs, l4_cap_idx_t vmcs_cap) L4_NOTHROW
Associate the software VMCS with a vCPU context, i.e.
Definition __vm-vmx.h:907
l4_uint32_t l4_vm_vmx_get_caps_default1(l4_vm_vmx_vcpu_state_t const *vcpu_state, enum L4_vm_vmx_dfl1_regs dfl1_reg) L4_NOTHROW
Get a default to one capability register for VMX.
Definition __vm-vmx.h:892
unsigned l4_vm_vmx_field_len(unsigned field) L4_NOTHROW
Return length in bytes of a VMCS field.
Definition __vm-vmx.h:593
L4_vm_vmx_caps_regs
Exported VMX capability registers.
Definition __vm-vmx.h:29
L4_vm_vmx_vmcs_sizes
Sizes of software VMCS members.
Definition __vm-vmx.h:171
l4_uint64_t l4_vm_vmx_get_caps(l4_vm_vmx_vcpu_state_t const *vcpu_state, enum L4_vm_vmx_caps_regs caps_reg) L4_NOTHROW
Get a capability register for VMX.
Definition __vm-vmx.h:884
l4_uint32_t l4_vm_vmx_read_32(l4_vm_vmx_vcpu_vmcs_t *vmcs, unsigned field) L4_NOTHROW
Read a 32-bit software VMCS field.
Definition __vm-vmx.h:765
void l4_vm_vmx_write_32(l4_vm_vmx_vcpu_vmcs_t *vmcs, unsigned field, l4_uint32_t val) L4_NOTHROW
Write to a 32-bit software VMCS field.
Definition __vm-vmx.h:836
L4_vm_vmx_dfl1_regs
Exported VMX capability registers (default to 1 bits).
Definition __vm-vmx.h:52
void l4_vm_vmx_clear(l4_vm_vmx_vcpu_vmcs_t *vmcs, l4_vm_vmx_vcpu_vmcs_t *dest_vmcs) L4_NOTHROW
Save the content from the software VMCS to a different software VMCS.
Definition __vm-vmx.h:698
@ L4_VM_VMX_VMCS_MSR_LSTAR
VMCS offset of IA32e mode system call target address MSR.
Definition __vm-vmx.h:92
@ L4_VM_VMX_VMCS_NAT_ARG3
Custom argument passed from kernel to user space.
Definition __vm-vmx.h:86
@ L4_VM_VMX_VMCS_MSR_STAR
VMCS offset of system call target address MSR.
Definition __vm-vmx.h:98
@ L4_VM_VMX_VMCS_CR2
Software VMCS offset for CR2.
Definition __vm-vmx.h:78
@ L4_VM_VMX_VMCS_XCR0
VMCS offset of extended control register XCR0.
Definition __vm-vmx.h:88
@ L4_VM_VMX_VMCS_MSR_TSC_AUX
VMCS offset of auxiliary TSC signature MSR.
Definition __vm-vmx.h:96
@ L4_VM_VMX_VMCS_NAT_ARG1
Custom argument passed from kernel to user space.
Definition __vm-vmx.h:82
@ L4_VM_VMX_VMCS_MSR_KERNEL_GS_BASE
VMCS offset of GS base address swap target MSR.
Definition __vm-vmx.h:100
@ L4_VM_VMX_VMCS_NAT_ARG0
Custom argument passed from kernel to user space.
Definition __vm-vmx.h:80
@ L4_VM_VMX_VMCS_NAT_ARG2
Custom argument passed from kernel to user space.
Definition __vm-vmx.h:84
@ L4_VM_VMX_VMCS_MSR_SYSCALL_MASK
VMCS offset of system call flag mask MSR.
Definition __vm-vmx.h:90
@ L4_VM_VMX_VMCS_MSR_CSTAR
VMCS offset of IA32 mode system call target address MSR.
Definition __vm-vmx.h:94
@ L4_VM_VMX_TRUE_PROCBASED_CTLS_REG
True processor based control caps.
Definition __vm-vmx.h:32
@ L4_VM_VMX_MISC_REG
Misc caps.
Definition __vm-vmx.h:35
@ L4_VM_VMX_PROCBASED_CTLS2_REG
Processor based control 2 caps.
Definition __vm-vmx.h:41
@ L4_VM_VMX_EPT_VPID_CAP_REG
EPT and VPID caps.
Definition __vm-vmx.h:42
@ L4_VM_VMX_CR4_FIXED1_REG
Fixed to 1 bits of CR4.
Definition __vm-vmx.h:39
@ L4_VM_VMX_NUM_CAPS_REGS
Total number of VMX capability registers.
Definition __vm-vmx.h:44
@ L4_VM_VMX_CR4_FIXED0_REG
Fixed to 0 bits of CR4.
Definition __vm-vmx.h:38
@ L4_VM_VMX_TRUE_ENTRY_CTLS_REG
True entry control caps.
Definition __vm-vmx.h:34
@ L4_VM_VMX_NESTED_REVISION
Nested VMCS revision.
Definition __vm-vmx.h:43
@ L4_VM_VMX_CR0_FIXED1_REG
Fixed to 1 bits of CR0.
Definition __vm-vmx.h:37
@ L4_VM_VMX_CR0_FIXED0_REG
Fixed to 0 bits of CR0.
Definition __vm-vmx.h:36
@ L4_VM_VMX_VMCS_ENUM_REG
VMCS enumeration info.
Definition __vm-vmx.h:40
@ L4_VM_VMX_TRUE_EXIT_CTLS_REG
True exit control caps.
Definition __vm-vmx.h:33
@ L4_VM_VMX_TRUE_PINBASED_CTLS_REG
True pin-based control caps.
Definition __vm-vmx.h:31
@ L4_VM_VMX_BASIC_REG
Basic VMX capabilities.
Definition __vm-vmx.h:30
@ L4_VM_VMX_VMCS_SIZE_VALUES
Size of the software VMCS values member.
Definition __vm-vmx.h:173
@ L4_VM_VMX_VMCS_SIZE_DIRTY_BITMAP
Size of the software VMCS dirty bitmap member.
Definition __vm-vmx.h:175
@ L4_VM_VMX_ENTRY_CTLS_DFL1_REG
Default 1 bits in entry controls.
Definition __vm-vmx.h:56
@ L4_VM_VMX_EXIT_CTLS_DFL1_REG
Default 1 bits in exit controls.
Definition __vm-vmx.h:55
@ L4_VM_VMX_PINBASED_CTLS_DFL1_REG
Default 1 bits in pin-based controls.
Definition __vm-vmx.h:53
@ L4_VM_VMX_NUM_DFL1_REGS
Total number of default on registers.
Definition __vm-vmx.h:57
@ L4_VM_VMX_PROCBASED_CTLS_DFL1_REG
Default 1 bits in processor-based controls.
Definition __vm-vmx.h:54
#define L4_NOTHROW
Mark a function declaration and definition as never throwing an exception.
Definition compiler.h:159
#define L4_INLINE
L4 Inline function attribute.
Definition compiler.h:51
State of a vCPU.
Definition vcpu.h:76
VMX information members.
Definition __vm-vmx.h:240
l4_uint64_t caps[L4_VM_VMX_NUM_CAPS_REGS]
Exported VMX capability registers. See L4_vm_vmx_caps_regs.
Definition __vm-vmx.h:242
l4_uint32_t dfl1[L4_VM_VMX_NUM_DFL1_REGS]
Exported VMX capability registers (default to 1 bits).
Definition __vm-vmx.h:246
VMX vCPU state.
Definition __vm-vmx.h:268
VMX software VMCS.
Definition __vm-vmx.h:206
Software VMCS field offset table.
Definition __vm-vmx.h:156
vCPU API