Detect VT-x
This commit is contained in:
parent
f0b9af28fc
commit
ec58283e42
12 changed files with 317 additions and 9 deletions
15
Makefile
15
Makefile
|
|
@ -8,13 +8,16 @@ CFLAGS += -ggdb
|
||||||
# Add new source files (C or Assembler) here,
|
# Add new source files (C or Assembler) here,
|
||||||
# preferentially in alphabetical order.
|
# preferentially in alphabetical order.
|
||||||
VISOR_SOURCES_x86_64 := \
|
VISOR_SOURCES_x86_64 := \
|
||||||
|
src/vintel.c \
|
||||||
# end of x86_64 specific sources list
|
# end of x86_64 specific sources list
|
||||||
|
|
||||||
# Architecture-agnostic kernel sources.
|
# Architecture-agnostic kernel sources.
|
||||||
# Add new source files (C or Assembler) here,
|
# Add new source files (C or Assembler) here,
|
||||||
# preferentially in alphabetical order.
|
# preferentially in alphabetical order.
|
||||||
VISOR_SOURCES := \
|
VISOR_SOURCES := \
|
||||||
efi.c \
|
src/alloc.c \
|
||||||
|
src/efi.c \
|
||||||
|
src/strlcpy.c \
|
||||||
$(VISOR_SOURCES_$(ARCH)) \
|
$(VISOR_SOURCES_$(ARCH)) \
|
||||||
# end of sources list
|
# end of sources list
|
||||||
|
|
||||||
|
|
@ -34,11 +37,7 @@ clean:
|
||||||
rm -f build/visor.so
|
rm -f build/visor.so
|
||||||
rm -f $(VISOR_TARGET)
|
rm -f $(VISOR_TARGET)
|
||||||
|
|
||||||
build/%.o: %.[cS] | build
|
build/src/%.o: src/%.[cS] | build/src
|
||||||
@printf "CC %s\n" $@
|
|
||||||
@"$(CC)" $(CFLAGS) -MMD -MP -c -o $@ $< $(CPPFLAGS)
|
|
||||||
|
|
||||||
build/$(ARCH)/%.o: $(ARCH)/%.[cS] | build/$(ARCH)
|
|
||||||
@printf "CC %s\n" $@
|
@printf "CC %s\n" $@
|
||||||
@"$(CC)" $(CFLAGS) -MMD -MP -c -o $@ $< $(CPPFLAGS)
|
@"$(CC)" $(CFLAGS) -MMD -MP -c -o $@ $< $(CPPFLAGS)
|
||||||
|
|
||||||
|
|
@ -53,7 +52,7 @@ $(VISOR_TARGET): build/visor.so | build
|
||||||
build:
|
build:
|
||||||
mkdir -p $@
|
mkdir -p $@
|
||||||
|
|
||||||
build/$(ARCH):
|
build/src:
|
||||||
mkdir -p $@
|
mkdir -p $@
|
||||||
|
|
||||||
config.mk: | config.default.mk
|
config.mk: | config.default.mk
|
||||||
|
|
|
||||||
37
bochsrc
Normal file
37
bochsrc
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
# configuration file generated by Bochs
|
||||||
|
plugin_ctrl: unmapped=1, biosdev=1, speaker=1, extfpuirq=1, parallel=1, serial=1
|
||||||
|
memory: host=64, guest=64
|
||||||
|
romimage: file="/usr/share/OVMF/x64/MICROVM.fd", address=0x0, options=none
|
||||||
|
vgaromimage: file="/usr/share/bochs/VGABIOS-lgpl-latest-cirrus"
|
||||||
|
boot: floppy
|
||||||
|
floppy_bootsig_check: disabled=0
|
||||||
|
# no floppya
|
||||||
|
# no floppyb
|
||||||
|
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
|
||||||
|
ata0-master: type=none
|
||||||
|
ata0-slave: type=none
|
||||||
|
ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15
|
||||||
|
ata1-master: type=none
|
||||||
|
ata1-slave: type=none
|
||||||
|
pci: enabled=1, chipset=i440fx, slot1=cirrus
|
||||||
|
vga: extension=cirrus, update_freq=5, realtime=1
|
||||||
|
cpu: count=1, ips=4000000, model=bx_generic, reset_on_triple_fault=1, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0
|
||||||
|
cpuid: level=6, stepping=3, model=3, family=6, vendor_string="GenuineIntel", brand_string=" Intel(R) Pentium(R) 4 CPU "
|
||||||
|
cpuid: mmx=1, apic=xapic, simd=sse2, sse4a=0, misaligned_sse=0, sep=1, movbe=0, adx=0
|
||||||
|
cpuid: aes=0, sha=0, xsave=0, xsaveopt=0, x86_64=1, 1g_pages=0, pcid=0, fsgsbase=0
|
||||||
|
#cpuid: smep=0, smap=0, mwait=1, vmx=1
|
||||||
|
print_timestamps: enabled=0
|
||||||
|
port_e9_hack: enabled=0
|
||||||
|
private_colormap: enabled=0
|
||||||
|
clock: sync=none, time0=local, rtc_sync=0
|
||||||
|
# no cmosimage
|
||||||
|
# no loader
|
||||||
|
log: -
|
||||||
|
logprefix: %t%e%d
|
||||||
|
debug: action=ignore
|
||||||
|
info: action=report
|
||||||
|
error: action=report
|
||||||
|
panic: action=ask
|
||||||
|
keyboard: type=mf, serial_delay=250, paste_delay=100000, user_shortcut=none
|
||||||
|
mouse: type=ps2, enabled=0, toggle=ctrl+mbutton
|
||||||
|
com1: enabled=1, mode=null
|
||||||
|
|
@ -10,6 +10,6 @@ LD = ld
|
||||||
|
|
||||||
# Compilation flags
|
# Compilation flags
|
||||||
CFLAGS = -std=c17 -Wall -ffreestanding -fpic -nostdlib -fno-stack-protector -fno-stack-check -fshort-wchar -mno-red-zone -maccumulate-outgoing-args -mno-sse -mno-mmx -mno-80387
|
CFLAGS = -std=c17 -Wall -ffreestanding -fpic -nostdlib -fno-stack-protector -fno-stack-check -fshort-wchar -mno-red-zone -maccumulate-outgoing-args -mno-sse -mno-mmx -mno-80387
|
||||||
CPPFLAGS = -Ignuefi/inc
|
CPPFLAGS = -Ignuefi/inc -Iinclude
|
||||||
LDFLAGS = -shared -Bsymbolic -Lgnuefi -Tgnuefi/elf_$(ARCH)_efi.lds -nostdlib
|
LDFLAGS = -shared -Bsymbolic -Lgnuefi -Tgnuefi/elf_$(ARCH)_efi.lds -nostdlib
|
||||||
LIBS = -lgnuefi -lefi
|
LIBS = -lgnuefi -lefi
|
||||||
|
|
|
||||||
30
include/x86/cr.h
Normal file
30
include/x86/cr.h
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
#ifndef _VISOR_CR_H_
|
||||||
|
#define _VISOR_CR_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
static inline uint64_t
|
||||||
|
readcr0(void)
|
||||||
|
{
|
||||||
|
uint64_t v;
|
||||||
|
__asm__ ("mov %%cr0, %0\n\t" : "=a"(v));
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint64_t
|
||||||
|
readcr3(void)
|
||||||
|
{
|
||||||
|
uint64_t v;
|
||||||
|
__asm__ ("mov %%cr3, %0\n\t" : "=a"(v));
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint64_t
|
||||||
|
readcr4(void)
|
||||||
|
{
|
||||||
|
uint64_t v;
|
||||||
|
__asm__ ("mov %%cr4, %0\n\t" : "=a"(v));
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
49
include/x86/msr.h
Normal file
49
include/x86/msr.h
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
#ifndef _VISOR_MSR_H_
|
||||||
|
#define _VISOR_MSR_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define IA32_FEATURE_CONTROL 0x3A
|
||||||
|
|
||||||
|
#define IA32_VMX_BASIC 0x480
|
||||||
|
#define IA32_VMX_PINBASED_CTLS 0x481
|
||||||
|
#define IA32_VMX_PROCBASED_CTLS 0x482
|
||||||
|
#define IA32_VMX_EXIT_CTLS 0x483
|
||||||
|
#define IA32_VMX_ENTRY_CTLS 0x484
|
||||||
|
#define IA32_VMX_MISC 0x485
|
||||||
|
#define IA32_VMX_CR0_FIXED0 0x486
|
||||||
|
#define IA32_VMX_CR0_FIXED1 0x487
|
||||||
|
#define IA32_VMX_CR4_FIXED0 0x488
|
||||||
|
#define IA32_VMX_CR4_FIXED1 0x489
|
||||||
|
#define IA32_VMX_VMCS_ENUM 0x48A
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
rdmsr32(uint32_t msr)
|
||||||
|
{
|
||||||
|
uint32_t value;
|
||||||
|
__asm__ ("rdmsr\n\t" : "=a"(value) : "c"(msr) : "d");
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint64_t
|
||||||
|
rdmsr64(uint32_t msr)
|
||||||
|
{
|
||||||
|
uint64_t value;
|
||||||
|
__asm__ ("rdmsr\n\t" : "=A"(value) : "c"(msr));
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
wrmsr32(uint32_t msr, uint32_t value)
|
||||||
|
{
|
||||||
|
uint32_t high = 0;
|
||||||
|
__asm__ ("wrmsr\n\t" :: "c"(msr), "a"(value), "d"(high));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
wrmsr64(uint32_t msr, uint64_t value)
|
||||||
|
{
|
||||||
|
__asm__ ("wrmsr\n\t" :: "c"(msr), "A"(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
78
include/x86/vmx.h
Normal file
78
include/x86/vmx.h
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
#ifndef _VISOR_VMX_H_
|
||||||
|
#define _VISOR_VMX_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct VMCS {
|
||||||
|
/* VMCS Header */
|
||||||
|
uint32_t revisionID;
|
||||||
|
uint32_t abortIndicator;
|
||||||
|
/* Guest-state area */
|
||||||
|
/* Host-state area */
|
||||||
|
/* VM-execution control fields */
|
||||||
|
/* VM-exit control fields */
|
||||||
|
/* VM-entry control fields */
|
||||||
|
/* VM-exit information fields */
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
vmxon(void *region)
|
||||||
|
{
|
||||||
|
__asm__ volatile ("vmxon %0\n\t" :: "r"(region));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
vmxoff(void)
|
||||||
|
{
|
||||||
|
__asm__ volatile ("vmxoff\n\t" ::);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
vmptrld(void *region)
|
||||||
|
{
|
||||||
|
__asm__ volatile ("vmptrld %0\n\t" :: "r"(region));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
vmptrst(void *arg)
|
||||||
|
{
|
||||||
|
__asm__ volatile ("vmptrst\n\t" ::);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
vmclear(void *region)
|
||||||
|
{
|
||||||
|
__asm__ volatile ("vmclear %0\n\t" :: "r"(region));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
vmlaunch(void)
|
||||||
|
{
|
||||||
|
__asm__ volatile ("vmlaunch\n\t" ::);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
vmresume(void)
|
||||||
|
{
|
||||||
|
__asm__ volatile ("vmresume\n\t" ::);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
vmread()
|
||||||
|
{
|
||||||
|
__asm__ volatile ("vmread\n\t" ::);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
vmwrite()
|
||||||
|
{
|
||||||
|
__asm__ volatile ("vmwrite\n\t" ::);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
vmcall()
|
||||||
|
{
|
||||||
|
__asm__ volatile ("vmcall\n\t" ::);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
6
src/alloc.c
Normal file
6
src/alloc.c
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
void *
|
||||||
|
allocate_aligned()
|
||||||
|
{
|
||||||
|
return (void *)0;
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,26 @@
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include <efi.h>
|
#include <efi.h>
|
||||||
#include <efilib.h>
|
#include <efilib.h>
|
||||||
|
|
||||||
|
#include "virt.h"
|
||||||
|
|
||||||
|
struct virt_vtable *virt = &virt_vtable_intel;
|
||||||
|
|
||||||
|
static char virt_err[100];
|
||||||
|
|
||||||
EFIAPI
|
EFIAPI
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
efi_main(EFI_HANDLE imageHandle, EFI_SYSTEM_TABLE *systemTable)
|
efi_main(EFI_HANDLE imageHandle, EFI_SYSTEM_TABLE *systemTable)
|
||||||
{
|
{
|
||||||
InitializeLib(imageHandle, systemTable);
|
InitializeLib(imageHandle, systemTable);
|
||||||
Print(L"Hello, World!\n");
|
Print(L"Hello, World!\n");
|
||||||
|
|
||||||
|
if (!virt->has_support(virt_err, sizeof virt_err)) {
|
||||||
|
AsciiPrint(virt_err);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;) {}
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
8
src/std.h
Normal file
8
src/std.h
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef _VISOR_STD_H_
|
||||||
|
#define _VISOR_STD_H_
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
size_t strlcpy(char *restrict dest, const char *restrict src, size_t size);
|
||||||
|
|
||||||
|
#endif
|
||||||
18
src/strlcpy.c
Normal file
18
src/strlcpy.c
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
#include "std.h"
|
||||||
|
|
||||||
|
size_t
|
||||||
|
strlcpy(char *restrict dest, const char *restrict src, size_t size)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
while (i + 1 < size && src[i]) {
|
||||||
|
dest[i] = src[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (size) {
|
||||||
|
dest[i] = 0;
|
||||||
|
}
|
||||||
|
while (src[i]) {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
53
src/vintel.c
Normal file
53
src/vintel.c
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
#include <cpuid.h>
|
||||||
|
#include <x86/msr.h>
|
||||||
|
#include <x86/cr.h>
|
||||||
|
|
||||||
|
#include "virt.h"
|
||||||
|
#include "std.h"
|
||||||
|
|
||||||
|
static bool
|
||||||
|
vintel_has_bios_support(void)
|
||||||
|
{
|
||||||
|
uint64_t value = rdmsr64(IA32_FEATURE_CONTROL);
|
||||||
|
return (value & 0x5) == 0x5;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
vintel_has_cpu_support(void)
|
||||||
|
{
|
||||||
|
unsigned info[4];
|
||||||
|
__get_cpuid(0x1, &info[0], &info[1], &info[2], &info[3]);
|
||||||
|
return (info[2] & (1 << 5)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
vintel_has_cr4_support(void)
|
||||||
|
{
|
||||||
|
uint64_t value = readcr4();
|
||||||
|
return (value & (1 << 13)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
vintel_has_support(char *err, size_t errmax)
|
||||||
|
{
|
||||||
|
if (!vintel_has_cpu_support()) {
|
||||||
|
strlcpy(err, "CPU does not support VT-x.", errmax);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vintel_has_bios_support()) {
|
||||||
|
strlcpy(err, "VT-x support is not enabled in BIOS.", errmax);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vintel_has_cr4_support()) {
|
||||||
|
strlcpy(err, "VT-x enable bit is not set in CR4.", errmax);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct virt_vtable virt_vtable_intel = {
|
||||||
|
.has_support = vintel_has_support,
|
||||||
|
};
|
||||||
15
src/virt.h
Normal file
15
src/virt.h
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef _VISOR_VIRT_H_
|
||||||
|
#define _VISOR_VIRT_H_
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
struct virt_vtable {
|
||||||
|
bool (*has_support)(char *err, size_t errmax);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct virt_vtable virt_vtable_intel;
|
||||||
|
|
||||||
|
extern struct virt_vtable *virt;
|
||||||
|
|
||||||
|
#endif
|
||||||
Loading…
Add table
Reference in a new issue