@@ -2,9 +2,10 @@ use core::{
22 fmt:: { self , Debug , Display } ,
33 ops:: Deref ,
44} ;
5+ use std:: os:: arceos:: modules:: axalloc;
56
67use axvm_types:: addr:: * ;
7- use x86_vcpu :: * ;
8+ use memory_addr :: { PAGE_SIZE_4K , PhysAddr , VirtAddr } ;
89
910use crate :: {
1011 RunError ,
@@ -16,34 +17,76 @@ use crate::{
1617 } ,
1718} ;
1819
20+ // ==================== x86 VCPU HAL 实现 ====================
21+ // x86_vcpu 现在使用自己的 Hal trait,不需要 AxVCpuHal
22+
23+ /// x86 VCPU 的 HAL 实现 - 实现 x86_vcpu::Hal trait
24+ pub ( super ) struct X86VcpuHal ;
25+
26+ impl x86_vcpu:: Hal for X86VcpuHal {
27+ fn alloc_frame ( ) -> Option < usize > {
28+ axalloc:: global_allocator ( )
29+ . alloc_pages ( 1 , PAGE_SIZE_4K , axalloc:: UsageKind :: Global )
30+ . ok ( )
31+ }
32+
33+ fn dealloc_frame ( paddr : usize ) {
34+ axalloc:: global_allocator ( ) . dealloc_pages ( paddr, 1 , axalloc:: UsageKind :: Global ) ;
35+ }
36+
37+ fn phys_to_virt ( paddr : usize ) -> usize {
38+ axhal:: mem:: phys_to_virt ( PhysAddr :: from ( paddr) ) . into ( )
39+ }
40+
41+ fn virt_to_phys ( vaddr : usize ) -> usize {
42+ axhal:: mem:: virt_to_phys ( VirtAddr :: from ( vaddr) ) . into ( )
43+ }
44+ }
45+
46+ // 使用具体的泛型类型
47+ type VmxPerCpuState = x86_vcpu:: VmxArchPerCpuState < X86VcpuHal > ;
48+ type VmxVcpu = x86_vcpu:: VmxArchVCpu < X86VcpuHal > ;
49+
1950pub struct HCpu {
2051 pub id : CpuId ,
2152 pub hard_id : CpuHardId ,
22- vpercpu : VmxArchVCpu ,
53+ vpercpu : VmxPerCpuState ,
2354 max_guest_page_table_levels : usize ,
2455 pub pa_range : core:: ops:: Range < usize > ,
56+ pub pa_bits : usize ,
2557}
2658
2759impl HCpu {
2860 pub fn new ( id : CpuId ) -> Self {
29- let mpidr = MPIDR_EL1 . get ( ) as usize ;
30- let hard_id = mpidr & 0xff_ff_ff ;
61+ // 使用 raw_cpuid 获取 x86 APIC ID
62+ let apic_id = raw_cpuid:: CpuId :: new ( )
63+ . get_feature_info ( )
64+ . map ( |f| f. initial_local_apic_id ( ) as usize )
65+ . unwrap_or ( 0 ) ;
66+ let hard_id = CpuHardId :: new ( apic_id) ;
3167
32- let vpercpu = Aarch64PerCpu :: new ( ) ;
68+ // 创建 x86 PerCpu 状态
69+ let vpercpu = VmxPerCpuState :: new ( id. raw ( ) ) . expect ( "Failed to create VmxPerCpuState" ) ;
3370
3471 HCpu {
3572 id,
36- hard_id : CpuHardId :: new ( hard_id ) ,
73+ hard_id,
3774 vpercpu,
3875 max_guest_page_table_levels : 0 ,
3976 pa_range : 0 ..0 ,
77+ pa_bits : 0 ,
4078 }
4179 }
4280
4381 pub fn init ( & mut self ) -> anyhow:: Result < ( ) > {
44- self . vpercpu . hardware_enable ( ) ;
45- self . max_guest_page_table_levels = self . vpercpu . max_guest_page_table_levels ( ) ;
46- self . pa_range = self . vpercpu . pa_range ( ) ;
82+ // 启用 VMX 硬件虚拟化
83+ self . vpercpu . hardware_enable ( ) ?;
84+
85+ // x86_64 平台的固定配置
86+ self . max_guest_page_table_levels = 4 ; // 4-level page tables (PML4)
87+ self . pa_bits = 48 ; // 典型的 x86_64 物理地址宽度
88+ self . pa_range = 0 ..( 1 << self . pa_bits ) ;
89+
4790 Ok ( ( ) )
4891 }
4992
@@ -65,46 +108,54 @@ impl Display for HCpu {
65108 "
66109CPU {}:
67110 Hard ID: {}
68- PT Levels: {}" ,
69- self . id, self . hard_id, self . max_guest_page_table_levels
111+ PT Levels: {}
112+ PA Bits: {}" ,
113+ self . id, self . hard_id, self . max_guest_page_table_levels, self . pa_bits
70114 )
71115 }
72116}
73117
74- pub ( super ) struct VCpuHal ;
75-
76- impl arm_vcpu:: CpuHal for VCpuHal {
77- fn irq_hanlder ( & self ) {
78- axhal:: irq:: irq_handler ( 0 ) ;
79- }
80-
81- fn inject_interrupt ( & self , irq : usize ) {
82- todo ! ( )
83- }
84- }
85-
118+ // x86 特定的 VCPU
86119pub struct VCpu {
87- pub vcpu : arm_vcpu :: Aarch64VCpu ,
120+ pub vcpu : VmxVcpu ,
88121 common : VCpuCommon ,
89122}
90123
91124impl VCpu {
92125 pub fn new (
93126 host_cpuid : Option < CpuId > ,
94- dtb_addr : GuestPhysAddr ,
127+ _dtb_addr : GuestPhysAddr , // 参数保留以保持接口兼容性,x86 不使用设备树
95128 vm : VmDataWeak ,
96129 ) -> anyhow:: Result < Self > {
97130 let common = VCpuCommon :: new_exclusive ( host_cpuid, vm) ?;
98131
99132 let hard_id = common. hard_id ( ) ;
133+ let vm_id = common. vm_id ( ) . into ( ) ;
134+ let vcpu_id = common. bind_id ( ) . raw ( ) ;
135+
136+ // 使用 x86_vcpu 的新方法创建 VCPU
137+ let vcpu = VmxVcpu :: new ( vm_id, vcpu_id)
138+ . map_err ( |e| anyhow:: anyhow!( "Failed to create VmxVcpu: {:?}" , e) ) ?;
139+
140+ info ! (
141+ "Created x86 VCPU: vm_id={}, vcpu_id={}, hard_id={}" ,
142+ vm_id,
143+ vcpu_id,
144+ hard_id. raw( )
145+ ) ;
100146
101- let vcpu = arm_vcpu:: Aarch64VCpu :: new ( Aarch64VCpuCreateConfig {
102- mpidr_el1 : hard_id. raw ( ) as u64 ,
103- dtb_addr : dtb_addr. as_usize ( ) ,
104- } )
105- . unwrap ( ) ;
106147 Ok ( VCpu { vcpu, common } )
107148 }
149+
150+ pub fn set_pt_level ( & mut self , level : usize ) {
151+ // x86 通过 EPT 配置,此方法预留以保持接口兼容性
152+ debug ! ( "Setting page table level to {} (no-op on x86)" , level) ;
153+ }
154+
155+ pub fn set_pa_bits ( & mut self , pa_bits : usize ) {
156+ // x86 通过 EPT 配置,此方法预留以保持接口兼容性
157+ debug ! ( "Setting PA bits to {} (no-op on x86)" , pa_bits) ;
158+ }
108159}
109160
110161impl VCpuOp for VCpu {
@@ -117,62 +168,119 @@ impl VCpuOp for VCpu {
117168 }
118169
119170 fn run ( & mut self ) -> Result < ( ) , RunError > {
120- info ! ( "Starting vCPU {}" , self . bind_id( ) ) ;
121- self . vcpu
122- . setup_current_cpu ( self . vm_id ( ) . into ( ) )
123- . map_err ( |e| anyhow ! ( "{e}" ) ) ?;
171+ info ! ( "Starting x86 vCPU {}" , self . bind_id( ) ) ;
172+
173+ // 绑定到当前 CPU - 使用 x86_vcpu 的新方法
174+ self . vcpu . bind ( ) . map_err ( |e| {
175+ RunError :: ExitWithError ( anyhow:: anyhow!( "Failed to bind VCPU: {:?}" , e) )
176+ } ) ?;
177+
124178 while self . is_active ( ) {
125- debug ! ( "vCPU {} entering guest" , self . bind_id( ) ) ;
126- let exit_reason = self . vcpu . run ( ) . map_err ( |e| anyhow ! ( "{e}" ) ) ?;
179+ debug ! ( "x86 vCPU {} entering guest" , self . bind_id( ) ) ;
180+
181+ // 使用 x86_vcpu 的 run_arch 方法,返回自己的 VmxExitReason
182+ let exit_reason = self . vcpu . run ( ) . map_err ( |e| {
183+ RunError :: ExitWithError ( anyhow:: anyhow!( "VCPU run failed: {:?}" , e) )
184+ } ) ?;
185+
127186 debug ! (
128- "vCPU {} exited with reason: {:?}" ,
187+ "x86 vCPU {} exited with reason: {:?}" ,
129188 self . bind_id( ) ,
130189 exit_reason
131190 ) ;
191+
192+ // 根据用户优先级处理退出原因 - 使用 x86_vcpu 的 VmxExitReason
132193 match exit_reason {
133- arm_vcpu:: AxVCpuExitReason :: Hypercall { nr, args } => todo ! ( ) ,
134- arm_vcpu:: AxVCpuExitReason :: MmioRead {
135- addr,
136- width,
137- reg,
138- reg_width,
139- signed_ext,
140- } => todo ! ( ) ,
141- arm_vcpu:: AxVCpuExitReason :: MmioWrite { addr, width, data } => todo ! ( ) ,
142- arm_vcpu:: AxVCpuExitReason :: SysRegRead { addr, reg } => todo ! ( ) ,
143- arm_vcpu:: AxVCpuExitReason :: SysRegWrite { addr, value } => todo ! ( ) ,
144- arm_vcpu:: AxVCpuExitReason :: ExternalInterrupt => {
145- axhal:: irq:: irq_handler ( 0 ) ;
194+ // 高优先级:外部中断(必须实现)
195+ x86_vcpu:: VmxExitReason :: ExternalInterrupt { vector } => {
196+ debug ! ( "Handling external interrupt, vector={}" , vector) ;
197+ axhal:: irq:: irq_handler ( vector) ;
198+ }
199+
200+ // 高优先级:系统寄存器访问 (MSR)
201+ x86_vcpu:: VmxExitReason :: SysRegRead { addr, reg } => {
202+ // TODO: 实现 MSR 读取处理
203+ // x86_vcpu 的 VmxVcpu 已经处理了 x2APIC MSR 访问
204+ // 这里需要处理其他 MSR 的读取
205+ todo ! ( "MSR read: addr={:?}, reg={}" , addr, reg) ;
206+ }
207+ x86_vcpu:: VmxExitReason :: SysRegWrite { addr, value } => {
208+ // TODO: 实现 MSR 写入处理
209+ todo ! ( "MSR write: addr={:?}, value={:#x}" , addr, value) ;
210+ }
211+
212+ // 高优先级:IO 指令
213+ x86_vcpu:: VmxExitReason :: IoRead { port, width } => {
214+ // TODO: 实现端口 IO 读取
215+ // 需要连接到设备模拟层
216+ todo ! ( "IO read: port={:?}, width={:?}" , port, width) ;
217+ }
218+ x86_vcpu:: VmxExitReason :: IoWrite { port, width, data } => {
219+ // TODO: 实现端口 IO 写入
220+ // 需要连接到设备模拟层
221+ todo ! (
222+ "IO write: port={:?}, width={:?}, data={:#x}" ,
223+ port,
224+ width,
225+ data
226+ ) ;
146227 }
147- arm_vcpu:: AxVCpuExitReason :: CpuUp {
228+
229+ // 中优先级:超级调用
230+ x86_vcpu:: VmxExitReason :: Hypercall { nr, args } => {
231+ // TODO: 实现超级调用接口
232+ todo ! ( "Hypercall: nr={:#x}, args={:?}" , nr, args) ;
233+ }
234+
235+ // 低优先级:CPU 启动
236+ x86_vcpu:: VmxExitReason :: CpuUp {
148237 target_cpu,
149238 entry_point,
150239 arg,
151240 } => {
152- debug ! ( "vCPU {} requested CPU {} up" , self . bind_id( ) , target_cpu) ;
241+ debug ! (
242+ "x86 vCPU {} requested CPU {} up" ,
243+ self . bind_id( ) ,
244+ target_cpu
245+ ) ;
153246 self . vm ( ) ?. with_machine_running_mut ( |running| {
154247 debug ! ( "vCPU {} is bringing up CPU {}" , self . bind_id( ) , target_cpu) ;
155- running. cpu_up ( CpuHardId :: new ( target_cpu as _ ) , entry_point, arg)
248+ // 将 axaddrspace::GuestPhysAddr 转换为 axvm_types::addr::GuestPhysAddr
249+ // 先转为 usize,再转为目标类型
250+ let entry: GuestPhysAddr = entry_point. as_usize ( ) . into ( ) ;
251+ running. cpu_up ( CpuHardId :: new ( target_cpu) , entry, arg)
156252 } ) ??;
253+ // x86 使用 SIPI (Startup IPI) 启动 AP,返回值在 RAX 中
157254 self . vcpu . set_gpr ( 0 , 0 ) ;
158255 }
159- arm_vcpu:: AxVCpuExitReason :: CpuDown { _state } => todo ! ( ) ,
160- arm_vcpu:: AxVCpuExitReason :: SystemDown => {
161- info ! ( "vCPU {} requested system shutdown" , self . bind_id( ) ) ;
256+
257+ x86_vcpu:: VmxExitReason :: CpuDown { state } => {
258+ // TODO: 实现 CPU 关闭
259+ todo ! ( "CPU down: state={:?}" , state) ;
260+ }
261+
262+ // 系统关闭
263+ x86_vcpu:: VmxExitReason :: SystemDown => {
264+ info ! ( "x86 vCPU {} requested system shutdown" , self . bind_id( ) ) ;
162265 self . vm ( ) ?. stop ( ) ?;
266+ break ;
267+ }
268+
269+ x86_vcpu:: VmxExitReason :: Nothing => {
270+ // 无操作,继续运行
271+ }
272+
273+ _ => {
274+ warn ! ( "Unhandled x86 VCPU exit reason: {:?}" , exit_reason) ;
163275 }
164- arm_vcpu:: AxVCpuExitReason :: Nothing => { }
165- arm_vcpu:: AxVCpuExitReason :: SendIPI {
166- target_cpu,
167- target_cpu_aux,
168- send_to_all,
169- send_to_self,
170- vector,
171- } => todo ! ( ) ,
172- _ => todo ! ( ) ,
173276 }
174277 }
175278
279+ // 解绑 VCPU - 使用 x86_vcpu 的新方法
280+ self . vcpu . unbind ( ) . map_err ( |e| {
281+ RunError :: ExitWithError ( anyhow:: anyhow!( "Failed to unbind VCPU: {:?}" , e) )
282+ } ) ?;
283+
176284 Ok ( ( ) )
177285 }
178286}
@@ -187,7 +295,7 @@ impl Deref for VCpu {
187295
188296impl Debug for VCpu {
189297 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
190- f. debug_struct ( "VCpu" )
298+ f. debug_struct ( "x86:: VCpu" )
191299 . field ( "bind_id" , & self . bind_id ( ) )
192300 . field ( "hard_id" , & self . hard_id ( ) )
193301 . field ( "vcpu" , & self . vcpu )
0 commit comments