@@ -4,8 +4,8 @@ use raw_cpuid::CpuIdResult;
44use arrayvec:: ArrayVec ;
55use core:: convert:: TryInto ;
66use bitfield:: bitfield;
7- use bitflags:: _core:: num:: flt2dec:: to_shortest_exp_str;
87use crate :: apic:: get_local_apic;
8+ use crate :: vcpu:: VCpu ;
99
1010//Used https://c9x.me/x86/html/file_module_x86_id_45.html as guid for implementing this.
1111const CPUID_NAME : u32 = 0 ;
@@ -28,25 +28,7 @@ const MAX_CPUID_INPUT: u32 = 0x80000004;
2828//
2929// }
3030
31- bitfield ! {
32- pub struct IntelTypeFamilyModelSteppingIDEaxRes ( u32 ) ;
33- impl Debug ;
34- stepping_id, _: 3 , 0 ;
35- model, _: 7 , 4 ;
36- family_id, _: 11 , 8 ;
37- processor_type, _: 13 , 12 ;
38- extended_model_id, _: 19 , 16 ;
39- extended_family_id, _: 27 , 20 ;
40- }
4131
42- bitfield ! {
43- pub struct BrandCFlushMaxIDsInitialAPIC ( u32 ) ;
44- impl Debug ;
45- brand_idx, _: 7 , 0 ;
46- cflush, _: 15 , 8 ;
47- max_processor_ids, _: 23 , 16 ;
48- apic_id, _: 31 , 24 ;
49- }
5032
5133
5234fn get_cpu_id_result ( vcpu : & vcpu:: VCpu , eax_in : u32 , ecx_in : u32 ) -> CpuIdResult {
@@ -59,33 +41,8 @@ fn get_cpu_id_result(vcpu: &vcpu::VCpu, eax_in: u32, ecx_in: u32) -> CpuIdResult
5941 ) ;
6042
6143 match eax_in {
62- CPUID_NAME => cpuid_name ( vcpu, & mut actual) ,
63- CPUID_MODEL_FAMILY_STEPPING => {
64- let family_model_stepping = IntelTypeFamilyModelSteppingIDEaxRes ( actual. eax ) ;
65- //we can change family_model_stepping, but for now just use actual.
66- let eax = family_model_stepping. 0 ;
67- let mut brand_cflush_max_initial = BrandCFlushMaxIDsInitialAPIC ( actual. ebx ) ;
68- brand_cflush_max_initial. set_apic_id ( get_local_apic ( ) . id ( ) ) ; //in principle this is redundant
69- let ebx = brand_cflush_max_initial. 0 ;
70- let mut ecx = actual. ecx ;
71- let mut edx = actual. edx ;
72- // I would have made type safe bindings for this but then I saw how many fields there where...
73-
74- // Disable MTRR
75- edx &= !( 1 << 12 ) ;
76-
77- // Disable XSAVE
78- ecx &= !( 1 << 26 ) ;
79-
80- // Hide hypervisor feature
81- ecx &= !( 1 << 31 ) ;
82- CpuIdResult {
83- eax,
84- ebx,
85- ecx,
86- edx
87- }
88- }
44+ CPUID_NAME => cpuid_name ( vcpu, actual) ,
45+ CPUID_MODEL_FAMILY_STEPPING => cpuid_model_family_stepping ( actual)
8946 INTEL_CORE_CACHE_TOPOLOGY => {
9047 let core_cpus = vcpu. vm . read ( ) . config . cpus ( ) ;
9148
@@ -103,7 +60,71 @@ fn get_cpu_id_result(vcpu: &vcpu::VCpu, eax_in: u32, ecx_in: u32) -> CpuIdResult
10360 }
10461}
10562
106- fn cpuid_name ( vcpu : & VCpu , actual : & mut CpuIdResult ) -> CpuIdResult {
63+ bitfield ! {
64+ pub struct IntelTypeFamilyModelSteppingIDEaxRes ( u32 ) ;
65+ impl Debug ;
66+ stepping_id, _: 3 , 0 ;
67+ model, _: 7 , 4 ;
68+ family_id, _: 11 , 8 ;
69+ processor_type, _: 13 , 12 ;
70+ extended_model_id, _: 19 , 16 ;
71+ extended_family_id, _: 27 , 20 ;
72+ }
73+
74+ bitfield ! {
75+ pub struct BrandCFlushMaxIDsInitialAPIC ( u32 ) ;
76+ impl Debug ;
77+ brand_idx, _: 7 , 0 ;
78+ cflush, _: 15 , 8 ;
79+ max_processor_ids, _: 23 , 16 ;
80+ apic_id, _: 31 , 24 ;
81+ }
82+
83+ bitfield ! {
84+ pub struct FeatureInformationECX ( u32 ) ;
85+ //there are a lot of features here, so only add the ones we care about for now.
86+ xsave, _: 27 , 26 ;
87+ hypervissor, _: 32 , 31 ;
88+ }
89+
90+ bitfield ! {
91+ pub struct FeatureInformationEDX ( u32 ) ;
92+ //there are a lot of features here, so only add the ones we care about for now.
93+ mtrr, _: 13 , 12 ;
94+ }
95+
96+ fn cpuid_model_family_stepping ( actual : CpuIdResult ) -> CpuIdResult {
97+ let family_model_stepping = IntelTypeFamilyModelSteppingIDEaxRes ( actual. eax ) ;
98+ //we can change family_model_stepping, but for now just use actual.
99+ let eax = family_model_stepping. 0 ;
100+ let mut brand_cflush_max_initial = BrandCFlushMaxIDsInitialAPIC ( actual. ebx ) ;
101+ brand_cflush_max_initial. set_apic_id ( todo ! ( "Waiting on virtual APICs" ) ) ;
102+ brand_cflush_max_initial. set_max_processor_ids ( todo ! ( "Waiting on virtual APICs" ) ) ;
103+ let ebx = brand_cflush_max_initial. 0 ;
104+ let mut features_ecx = FeatureInformationECX ( actual. ecx ) ;
105+ let mut features_edx = FeatureInformationEDX ( actual. edx ) ;
106+ // I would have made type safe bindings for this but then I saw how many fields there where...
107+
108+ // Disable MTRR
109+ features_edx. set_mtrr ( 0 ) ;
110+
111+ // Disable XSAVE
112+ // ecx &= !(1 << 26);
113+ features_ecx. set_xsave ( 0 ) ;
114+
115+ // Hide hypervisor feature
116+ features_ecx. set_hypervisor ( 0 ) ;
117+ let ecx = features_ecx. 0 ;
118+ let edx = features_edx. 0 ;
119+ CpuIdResult {
120+ eax,
121+ ebx,
122+ ecx,
123+ edx
124+ }
125+ }
126+
127+ fn cpuid_name ( vcpu : & VCpu , actual : CpuIdResult ) -> CpuIdResult {
107128 if vcpu. vm . read ( ) . config . override_cpu_name ( ) {
108129 let cpu_name = "MythrilCPU__" ;
109130 let bytes = cpu_name. chars ( ) . map ( |char| char as u8 ) . collect :: < ArrayVec < [ u8 ; 12 ] > > ( ) ;
0 commit comments