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,
|
||||
# preferentially in alphabetical order.
|
||||
VISOR_SOURCES_x86_64 := \
|
||||
src/vintel.c \
|
||||
# end of x86_64 specific sources list
|
||||
|
||||
# Architecture-agnostic kernel sources.
|
||||
# Add new source files (C or Assembler) here,
|
||||
# preferentially in alphabetical order.
|
||||
VISOR_SOURCES := \
|
||||
efi.c \
|
||||
VISOR_SOURCES := \
|
||||
src/alloc.c \
|
||||
src/efi.c \
|
||||
src/strlcpy.c \
|
||||
$(VISOR_SOURCES_$(ARCH)) \
|
||||
# end of sources list
|
||||
|
||||
|
|
@ -34,11 +37,7 @@ clean:
|
|||
rm -f build/visor.so
|
||||
rm -f $(VISOR_TARGET)
|
||||
|
||||
build/%.o: %.[cS] | build
|
||||
@printf "CC %s\n" $@
|
||||
@"$(CC)" $(CFLAGS) -MMD -MP -c -o $@ $< $(CPPFLAGS)
|
||||
|
||||
build/$(ARCH)/%.o: $(ARCH)/%.[cS] | build/$(ARCH)
|
||||
build/src/%.o: src/%.[cS] | build/src
|
||||
@printf "CC %s\n" $@
|
||||
@"$(CC)" $(CFLAGS) -MMD -MP -c -o $@ $< $(CPPFLAGS)
|
||||
|
||||
|
|
@ -53,7 +52,7 @@ $(VISOR_TARGET): build/visor.so | build
|
|||
build:
|
||||
mkdir -p $@
|
||||
|
||||
build/$(ARCH):
|
||||
build/src:
|
||||
mkdir -p $@
|
||||
|
||||
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
|
||||
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
|
||||
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 <efilib.h>
|
||||
|
||||
#include "virt.h"
|
||||
|
||||
struct virt_vtable *virt = &virt_vtable_intel;
|
||||
|
||||
static char virt_err[100];
|
||||
|
||||
EFIAPI
|
||||
EFI_STATUS
|
||||
efi_main(EFI_HANDLE imageHandle, EFI_SYSTEM_TABLE *systemTable)
|
||||
{
|
||||
InitializeLib(imageHandle, systemTable);
|
||||
Print(L"Hello, World!\n");
|
||||
|
||||
if (!virt->has_support(virt_err, sizeof virt_err)) {
|
||||
AsciiPrint(virt_err);
|
||||
}
|
||||
|
||||
for (;;) {}
|
||||
|
||||
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