From 0e0cd2943a0fc3261fc05464a709d5196345ba32 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Sun, 1 Sep 2019 21:49:10 +0530 Subject: [PATCH] Processor features are not checked Fixes https://github.com/manticoreos/manticore/issues/6. --- arch/x86_64/cpu.c | 29 +++++++ include/kernel/cpu.h | 6 +- include/kernel/cpuid.h | 188 +++++++++++++++++++++++++++++++++++++++++ include/kernel/ia32.h | 81 ++++++++++++++++++ 4 files changed, 303 insertions(+), 1 deletion(-) create mode 100644 include/kernel/cpuid.h create mode 100644 include/kernel/ia32.h diff --git a/arch/x86_64/cpu.c b/arch/x86_64/cpu.c index d1906919..b08e78e9 100644 --- a/arch/x86_64/cpu.c +++ b/arch/x86_64/cpu.c @@ -1,4 +1,33 @@ #include +#include + +static cpuid_cache_t cache = { + .initialized = 0 +}; + +static int cpu_emt64_enable(void) +{ + uint32_t efer; + + efer = ia32_rdmsr(IA32_EFER); + return efer & 0x400; +} + +static int cpu_nx_enable(void) +{ + uint32_t efer; + + efer = ia32_rdmsr(IA32_EFER); + return efer & 0x800; +} + +bool cpu_has_feature(uint32_t feature) +{ + if (!cache.initialized) { + cpuid_host_init(&cache); + } + return cpuid_host_has_feature(&cache, feature); +} void arch_halt_cpu(void) { diff --git a/include/kernel/cpu.h b/include/kernel/cpu.h index 70f1f516..bed45000 100644 --- a/include/kernel/cpu.h +++ b/include/kernel/cpu.h @@ -1,6 +1,10 @@ #ifndef KERNEL_CPU_H #define KERNEL_CPU_H -void arch_halt_cpu(void); +enum cpu_feature { + CPU_FEATURE_NX, +}; +void arch_halt_cpu(void); +bool cpu_has_feature(enum cpu_feature feature); #endif diff --git a/include/kernel/cpuid.h b/include/kernel/cpuid.h new file mode 100644 index 00000000..5b7148a7 --- /dev/null +++ b/include/kernel/cpuid.h @@ -0,0 +1,188 @@ +#ifndef HAX_CORE_CPUID_H_ +#define HAX_CORE_CPUID_H_ + +#define FEATURE_KEY(index, leaf_lo, leaf_hi, subleaf_key, subleaf_used, reg, bit) ( \ + (((index) & 0x1F) << 0) | \ + (((leaf_lo) & 0x1F) << 5) | \ + (((leaf_hi) & 0x03) << 10) | \ + (((subleaf_key) & 0x1F) << 12) | \ + (((subleaf_used) & 0x01) << 17) | \ + (((reg) & 0x03) << 18) | \ + (((bit) & 0x1F) << 20)) + +#define FEATURE_KEY_LEAF(index, leaf, reg, bit) \ + FEATURE_KEY(index, leaf, (leaf >> 30), 0, 0, reg, bit) +#define FEATURE_KEY_SUBLEAF(index, leaf, subleaf, reg, bit) \ + FEATURE_KEY(index, leaf, (leaf >> 30), subleaf, 1, reg, bit) + +#define FEATURE(name) \ + (1 << ((X86_FEATURE_##name >> 20) & 0x1F)) + +/* Intel SDM Vol. 2A: Table 3-8. + * Information Returned by CPUID Instruction */ +enum { + /* + * Intel SDM Vol. 2A: Table 3-10. + * Feature Information Returned in the ECX Register + * Features for CPUID with EAX=01h stored in ECX + */ +#define FEAT(bit) \ + FEATURE_KEY_LEAF(0, 0x01, CPUID_REG_ECX, bit) + X86_FEATURE_SSE3 = FEAT(0), /* 0x00000001 Streaming SIMD Extensions 3 */ + X86_FEATURE_PCLMULQDQ = FEAT(1), /* 0x00000002 PCLMULQDQ Instruction */ + X86_FEATURE_DTES64 = FEAT(2), /* 0x00000004 64-bit DS Area */ + X86_FEATURE_MONITOR = FEAT(3), /* 0x00000008 MONITOR/MWAIT Instructions */ + X86_FEATURE_DS_CPL = FEAT(4), /* 0x00000010 CPL Qualified Debug Store */ + X86_FEATURE_VMX = FEAT(5), /* 0x00000020 Virtual Machine Extensions */ + X86_FEATURE_SMX = FEAT(6), /* 0x00000040 Safer Mode Extensions */ + X86_FEATURE_EIST = FEAT(7), /* 0x00000080 Enhanced Intel SpeedStep technology */ + X86_FEATURE_TM2 = FEAT(8), /* 0x00000100 Thermal Monitor 2 */ + X86_FEATURE_SSSE3 = FEAT(9), /* 0x00000200 Supplemental Streaming SIMD Extensions 3 */ + X86_FEATURE_CNXT_ID = FEAT(10), /* 0x00000400 L1 Context ID */ + X86_FEATURE_SDBG = FEAT(11), /* 0x00000800 Silicon Debug Interface */ + X86_FEATURE_FMA = FEAT(12), /* 0x00001000 Fused Multiply-Add */ + X86_FEATURE_CMPXCHG16B = FEAT(13), /* 0x00002000 CMPXCHG16B Instruction */ + X86_FEATURE_XTPR_UPDATE = FEAT(14), /* 0x00004000 xTPR Update Control */ + X86_FEATURE_PDCM = FEAT(15), /* 0x00008000 Perfmon and Debug Capability */ + X86_FEATURE_PCID = FEAT(17), /* 0x00020000 Process-context identifiers */ + X86_FEATURE_DCA = FEAT(18), /* 0x00040000 Direct cache access for DMA writes */ + X86_FEATURE_SSE41 = FEAT(19), /* 0x00080000 Streaming SIMD Extensions 4.1 */ + X86_FEATURE_SSE42 = FEAT(20), /* 0x00100000 Streaming SIMD Extensions 4.2 */ + X86_FEATURE_X2APIC = FEAT(21), /* 0x00200000 x2APIC support */ + X86_FEATURE_MOVBE = FEAT(22), /* 0x00400000 MOVBE Instruction */ + X86_FEATURE_POPCNT = FEAT(23), /* 0x00800000 POPCNT Instruction */ + X86_FEATURE_TSC_DEADLINE = FEAT(24), /* 0x01000000 APIC supports one-shot operation using TSC deadline */ + X86_FEATURE_AESNI = FEAT(25), /* 0x02000000 AESNI Extension */ + X86_FEATURE_XSAVE = FEAT(26), /* 0x04000000 XSAVE/XRSTOR/XSETBV/XGETBV Instructions and XCR0 */ + X86_FEATURE_OSXSAVE = FEAT(27), /* 0x08000000 XSAVE enabled by OS */ + X86_FEATURE_AVX = FEAT(28), /* 0x10000000 Advanced Vector Extensions */ + X86_FEATURE_F16C = FEAT(29), /* 0x20000000 16-bit Floating-Point Instructions */ + X86_FEATURE_RDRAND = FEAT(30), /* 0x40000000 RDRAND Instruction */ + X86_FEATURE_HYPERVISOR = FEAT(31), /* 0x80000000 Hypervisor Running */ +#undef FEAT + + /* + * Intel SDM Vol. 2A: Table 3-11. + * More on Feature Information Returned in the EDX Register + * Features for CPUID with EAX=01h stored in EDX + */ +#define FEAT(bit) \ + FEATURE_KEY_LEAF(1, 0x01, CPUID_REG_EDX, bit) + X86_FEATURE_FPU = FEAT(0), /* 0x00000001 Floating Point Unit On-Chip */ + X86_FEATURE_VME = FEAT(1), /* 0x00000002 Virtual 8086 Mode Enhancements */ + X86_FEATURE_DE = FEAT(2), /* 0x00000004 Debugging Extensions */ + X86_FEATURE_PSE = FEAT(3), /* 0x00000008 Page Size Extension */ + X86_FEATURE_TSC = FEAT(4), /* 0x00000010 Time Stamp Counter */ + X86_FEATURE_MSR = FEAT(5), /* 0x00000020 RDMSR/WRMSR Instructions */ + X86_FEATURE_PAE = FEAT(6), /* 0x00000040 Physical Address Extension */ + X86_FEATURE_MCE = FEAT(7), /* 0x00000080 Machine Check Exception */ + X86_FEATURE_CX8 = FEAT(8), /* 0x00000100 CMPXCHG8B Instruction */ + X86_FEATURE_APIC = FEAT(9), /* 0x00000200 APIC On-Chip */ + X86_FEATURE_SEP = FEAT(11), /* 0x00000800 SYSENTER/SYSEXIT Instructions */ + X86_FEATURE_MTRR = FEAT(12), /* 0x00001000 Memory Type Range Registers */ + X86_FEATURE_PGE = FEAT(13), /* 0x00002000 Page Global Bit */ + X86_FEATURE_MCA = FEAT(14), /* 0x00004000 Machine Check Architecture */ + X86_FEATURE_CMOV = FEAT(15), /* 0x00008000 Conditional Move Instructions */ + X86_FEATURE_PAT = FEAT(16), /* 0x00010000 Page Attribute Table */ + X86_FEATURE_PSE36 = FEAT(17), /* 0x00020000 36-Bit Page Size Extension */ + X86_FEATURE_PSN = FEAT(18), /* 0x00040000 Processor Serial Number */ + X86_FEATURE_CLFSH = FEAT(19), /* 0x00080000 CLFLUSH Instruction */ + X86_FEATURE_DS = FEAT(21), /* 0x00200000 Debug Store */ + X86_FEATURE_ACPI = FEAT(22), /* 0x00400000 Thermal Monitor and Software Controlled Clock Facilities */ + X86_FEATURE_MMX = FEAT(23), /* 0x00800000 Intel MMX Technology */ + X86_FEATURE_FXSR = FEAT(24), /* 0x01000000 FXSAVE and FXRSTOR Instructions */ + X86_FEATURE_SSE = FEAT(25), /* 0x02000000 Streaming SIMD Extensions */ + X86_FEATURE_SSE2 = FEAT(26), /* 0x04000000 Streaming SIMD Extensions 2 */ + X86_FEATURE_SS = FEAT(27), /* 0x08000000 Self Snoop */ + X86_FEATURE_HTT = FEAT(28), /* 0x10000000 Max APIC IDs reserved field is Valid */ + X86_FEATURE_TM = FEAT(29), /* 0x20000000 Thermal Monitor */ + X86_FEATURE_PBE = FEAT(31), /* 0x80000000 Pending Break Enable */ +#undef FEAT + + /* + * Intel SDM Vol. 2A: Table 3-8. Information Returned by CPUID Instruction + * Structured Extended Feature Flags Enumeration Leaf + * Features for CPUID with EAX=07h, ECX=00h stored in ECX + */ +#define FEAT(bit) \ + FEATURE_KEY_SUBLEAF(2, 0x07, 0x00, CPUID_REG_ECX, bit) + X86_FEATURE_PREFETCHWT1 = FEAT(0), /* 0x00000001 PREFETCHWT1 Instruction */ + X86_FEATURE_AVX512_VBMI = FEAT(1), /* 0x00000002 AVX-512 Vector Bit Manipulation Instructions */ + X86_FEATURE_UMIP = FEAT(2), /* 0x00000004 User-Mode Instruction Prevention */ + X86_FEATURE_PKU = FEAT(3), /* 0x00000008 Protection Keys for User-mode pages */ + X86_FEATURE_OSPKE = FEAT(4), /* 0x00000010 PKU enabled by OS */ + X86_FEATURE_RDPID = FEAT(22), /* 0x00400000 RDPID Instruction and IA32_TSC_AUX MSR */ +#undef FEAT + + /* + * Intel SDM Vol. 2A: Table 3-8. Information Returned by CPUID Instruction + * Structured Extended Feature Flags Enumeration Leaf + * Features for CPUID with EAX=07h, ECX=00h stored in EBX + */ +#define FEAT(bit) \ + FEATURE_KEY_SUBLEAF(3, 0x07, 0x00, CPUID_REG_EBX, bit) + X86_FEATURE_FSGSBASE = FEAT(0), /* 0x00000001 RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE supported */ + X86_FEATURE_TSC_ADJUST = FEAT(1), /* 0x00000002 MSR IA32_TSC_ADJUST supported */ + X86_FEATURE_SGX = FEAT(2), /* 0x00000004 Software Guard Extensions */ + X86_FEATURE_BMI1 = FEAT(3), /* 0x00000008 Bit Manipulation Instruction Set 1 */ + X86_FEATURE_HLE = FEAT(4), /* 0x00000010 Transactional Synchronization Extensions */ + X86_FEATURE_AVX2 = FEAT(5), /* 0x00000020 Advanced Vector Extensions 2 */ + X86_FEATURE_SMEP = FEAT(7), /* 0x00000080 Supervisor-Mode Execution Prevention */ + X86_FEATURE_BMI2 = FEAT(8), /* 0x00000100 Bit Manipulation Instruction Set 2 */ + X86_FEATURE_INVPCID = FEAT(10), /* 0x00000400 INVPCID instruction */ + X86_FEATURE_RTM = FEAT(11), /* 0x00000800 Transactional Synchronization Extensions */ + X86_FEATURE_RDT_M = FEAT(12), /* 0x00001000 Resource Director Technology Monitoring */ + X86_FEATURE_MPX = FEAT(14), /* 0x00004000 Memory Protection Extensions */ + X86_FEATURE_RDT_A = FEAT(15), /* 0x00008000 Resource Director Technology Allocation */ + X86_FEATURE_AVX512F = FEAT(16), /* 0x00010000 AVX-512 Foundation */ + X86_FEATURE_AVX512DQ = FEAT(17), /* 0x00020000 AVX-512 Doubleword and Quadword Instructions */ + X86_FEATURE_RDSEED = FEAT(18), /* 0x00040000 RDSEED Instruction */ + X86_FEATURE_ADX = FEAT(19), /* 0x00080000 Multi-Precision Add-Carry Instruction Extensions */ + X86_FEATURE_SMAP = FEAT(20), /* 0x00100000 Supervisor Mode Access Prevention */ + X86_FEATURE_AVX512_IFMA = FEAT(21), /* 0x00200000 AVX-512 Integer Fused Multiply-Add Instructions */ + X86_FEATURE_CLFLUSHOPT = FEAT(23), /* 0x00800000 CLFLUSHOPT Instruction */ + X86_FEATURE_CLWB = FEAT(24), /* 0x01000000 CLWB Instruction */ + X86_FEATURE_AVX512PF = FEAT(26), /* 0x04000000 AVX-512 Prefetch Instructions */ + X86_FEATURE_AVX512ER = FEAT(27), /* 0x08000000 AVX-512 Exponential and Reciprocal Instructions */ + X86_FEATURE_AVX512CD = FEAT(28), /* 0x10000000 AVX-512 Conflict Detection Instructions*/ + X86_FEATURE_SHA = FEAT(29), /* 0x20000000 SHA Extension */ + X86_FEATURE_AVX512BW = FEAT(30), /* 0x40000000 AVX-512 Byte and Word Instructions */ + X86_FEATURE_AVX512VL = FEAT(31), /* 0x80000000 AVX-512 Vector Length Extensions */ +#undef FEAT + + /* + * Intel SDM Vol. 2A: Table 3-8. Information Returned by CPUID Instruction + * Extended Function CPUID Information + * Features for CPUID with EAX=80000001h stored in ECX + */ +#define FEAT(bit) \ + FEATURE_KEY_LEAF(4, 0x80000001, CPUID_REG_ECX, bit) + X86_FEATURE_LAHF = FEAT(0), /* 0x00000001 LAHF/SAHF Instructions */ + X86_FEATURE_PREFETCHW = FEAT(8), /* 0x00000100 PREFETCH/PREFETCHW instructions */ +#undef FEAT + + /* + * Intel SDM Vol. 2A: Table 3-8. Information Returned by CPUID Instruction + * Extended Function CPUID Information + * Features for CPUID with EAX=80000001h stored in EDX + */ +#define FEAT(bit) \ + FEATURE_KEY_LEAF(5, 0x80000001, CPUID_REG_EDX, bit) + X86_FEATURE_SYSCALL = FEAT(11), /* 0x00000800 SYSCALL/SYSRET Instructions */ + X86_FEATURE_NX = FEAT(20), /* 0x00100000 No-Execute Bit */ + X86_FEATURE_PDPE1GB = FEAT(26), /* 0x04000000 Gibibyte pages */ + X86_FEATURE_RDTSCP = FEAT(27), /* 0x08000000 RDTSCP Instruction */ + X86_FEATURE_EM64T = FEAT(29), /* 0x20000000 Long Mode */ +#undef FEAT +}; + +// Functions +void cpuid_query_leaf(cpuid_args_t *args, uint32_t leaf); +void cpuid_query_subleaf(cpuid_args_t *args, uint32_t leaf, uint32_t subleaf); + +void cpuid_host_init(cpuid_cache_t *cache); +bool cpuid_host_has_feature(cpuid_cache_t *cache, uint32_t feature_key); +bool cpuid_host_has_feature_uncached(uint32_t feature_key); + +#endif /* HAX_CORE_CPUID_H_ */ + diff --git a/include/kernel/ia32.h b/include/kernel/ia32.h new file mode 100644 index 00000000..7a96f194 --- /dev/null +++ b/include/kernel/ia32.h @@ -0,0 +1,81 @@ +#ifndef HAX_CORE_IA32_H_ +#define HAX_CORE_IA32_H_ + +#include "../../include/hax_types.h" + +union cpuid_args_t; +struct system_desc_t; + +mword ASMCALL get_cr0(void); +mword ASMCALL get_cr2(void); +mword ASMCALL get_cr3(void); +mword ASMCALL get_cr4(void); +mword ASMCALL get_dr0(void); +mword ASMCALL get_dr1(void); +mword ASMCALL get_dr2(void); +mword ASMCALL get_dr3(void); +mword ASMCALL get_dr6(void); +mword ASMCALL get_dr7(void); + +void ASMCALL set_cr0(mword val); +void ASMCALL set_cr2(mword val); +void ASMCALL set_cr3(mword val); +void ASMCALL set_cr4(mword val); +void ASMCALL set_dr0(mword val); +void ASMCALL set_dr1(mword val); +void ASMCALL set_dr2(mword val); +void ASMCALL set_dr3(mword val); +void ASMCALL set_dr6(mword val); +void ASMCALL set_dr7(mword val); + +uint16_t ASMCALL get_kernel_cs(void); +uint16_t ASMCALL get_kernel_ds(void); +uint16_t ASMCALL get_kernel_es(void); +uint16_t ASMCALL get_kernel_ss(void); +uint16_t ASMCALL get_kernel_gs(void); +uint16_t ASMCALL get_kernel_fs(void); + +void ASMCALL set_kernel_ds(uint16_t val); +void ASMCALL set_kernel_es(uint16_t val); +void ASMCALL set_kernel_gs(uint16_t val); +void ASMCALL set_kernel_fs(uint16_t val); + +void ASMCALL asm_btr(uint8_t *addr, uint bit); +void ASMCALL asm_bts(uint8_t *addr, uint bit); +void ASMCALL asm_clts(void); +void ASMCALL asm_fxinit(void); +void ASMCALL asm_fxsave(mword *addr); +void ASMCALL asm_fxrstor(mword *addr); +void ASMCALL asm_cpuid(union cpuid_args_t *state); + +void ASMCALL __nmi(void); +uint32_t ASMCALL asm_fls(uint32_t bit32); + +uint64_t ia32_rdmsr(uint32_t reg); +void ia32_wrmsr(uint32_t reg, uint64_t val); + +uint64_t ia32_rdtsc(void); + +void hax_clts(void); + +void hax_fxinit(void); +void hax_fxsave(mword *addr); +void hax_fxrstor(mword *addr); + +void btr(uint8_t *addr, uint bit); +void bts(uint8_t *addr, uint bit); + +void ASMCALL asm_enable_irq(void); +void ASMCALL asm_disable_irq(void); + +uint64_t ASMCALL get_kernel_rflags(void); +uint16_t ASMCALL get_kernel_tr_selector(void); + +void ASMCALL set_kernel_gdt(struct system_desc_t *sys_desc); +void ASMCALL set_kernel_idt(struct system_desc_t *sys_desc); +void ASMCALL set_kernel_ldt(uint16_t sel); +void ASMCALL get_kernel_gdt(struct system_desc_t *sys_desc); +void ASMCALL get_kernel_idt(struct system_desc_t *sys_desc); +uint16_t ASMCALL get_kernel_ldt(void); + +#endif // HAX_CORE_IA32_H_