1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| fn main(cpu_data: &mut PerCpu, linux_sp: usize) -> HvResult { cpu_data.init(linux_sp, cell::root_cell())?; INITED_CPUS.fetch_add(1, Ordering::SeqCst); wait_for_counter(&INITED_CPUS, online_cpus)?; ...... } impl PerCpu { pub fn init(&mut self, linux_sp: usize, cell: &Cell) -> HvResult { self.state = CpuState::HvDisabled; self.linux = LinuxContext::load_from(linux_sp); self.arch.init();
unsafe { crate::memory::hv_page_table().read().activate() };
unsafe { core::ptr::write(&mut self.vcpu, Vcpu::new(&self.linux, cell)?) };
self.state = CpuState::HvEnabled; Ok(()) } } impl LinuxContext { pub fn load_from(linux_sp: usize) -> Self { let regs = unsafe { core::slice::from_raw_parts(linux_sp as *const u64, SAVED_LINUX_REGS) }; let gdt = GdtStruct::sgdt(); let mut fs = Segment::from_selector(segmentation::fs(), &gdt); let mut gs = Segment::from_selector(segmentation::gs(), &gdt); fs.base = Msr::IA32_FS_BASE.read(); gs.base = regs[0];
Self { rsp: regs.as_ptr_range().end as _, r15: regs[1], r14: regs[2], r13: regs[3], r12: regs[4], rbx: regs[5], rbp: regs[6], rip: regs[7], es: Segment::from_selector(segmentation::es(), &gdt), cs: Segment::from_selector(segmentation::cs(), &gdt), ss: Segment::from_selector(segmentation::ss(), &gdt), ds: Segment::from_selector(segmentation::ds(), &gdt), fs, gs, tss: Segment::from_selector(unsafe { task::tr() }, &gdt), gdt, idt: IdtStruct::sidt(), cr0: Cr0::read(), cr3: Cr3::read().0.start_address().as_u64(), cr4: Cr4::read(), efer: Msr::IA32_EFER.read(), star: Msr::IA32_STAR.read(), lstar: Msr::IA32_LSTAR.read(), cstar: Msr::IA32_CSTAR.read(), fmask: Msr::IA32_FMASK.read(), kernel_gsbase: Msr::IA32_KERNEL_GSBASE.read(), pat: Msr::IA32_PAT.read(), mtrr_def_type: Msr::IA32_MTRR_DEF_TYPE.read(), } } }
|