Skip to content

Commit 8b43e40

Browse files
committed
[feat] support construct_guest64 for LinuxContext
1 parent 16164ee commit 8b43e40

File tree

2 files changed

+89
-7
lines changed

2 files changed

+89
-7
lines changed

src/context.rs

+88-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
use x86::{segmentation, task};
1+
use x86::segmentation::SegmentSelector;
2+
use x86::{Ring, segmentation, task};
23
use x86_64::VirtAddr;
34
use x86_64::instructions::tables::{lgdt, lidt, sidt};
4-
use x86_64::registers::control::{Cr0, Cr0Flags, Cr3, Cr3Flags, Cr4, Cr4Flags};
5+
use x86_64::registers::control::{Cr0, Cr0Flags, Cr3, Cr3Flags, Cr4, Cr4Flags, Efer, EferFlags};
56
use x86_64::structures::DescriptorTablePointer;
67
use x86_64::{addr::PhysAddr, structures::paging::PhysFrame};
78

@@ -38,7 +39,7 @@ pub struct LinuxContext {
3839
pub cr3: u64,
3940
pub cr4: Cr4Flags,
4041

41-
pub efer: u64,
42+
pub efer: EferFlags,
4243
pub star: u64,
4344
pub lstar: u64,
4445
pub cstar: u64,
@@ -87,7 +88,7 @@ impl Default for LinuxContext {
8788
cr0: Cr0Flags::empty(),
8889
cr3: 0,
8990
cr4: Cr4Flags::empty(),
90-
efer: 0,
91+
efer: EferFlags::empty(),
9192
star: 0,
9293
lstar: 0,
9394
cstar: 0,
@@ -146,7 +147,7 @@ impl LinuxContext {
146147
cr0: Cr0::read(),
147148
cr3: Cr3::read().0.start_address().as_u64(),
148149
cr4: Cr4::read(),
149-
efer: Msr::IA32_EFER.read(),
150+
efer: Efer::read(),
150151
star: Msr::IA32_STAR.read(),
151152
lstar: Msr::IA32_LSTAR.read(),
152153
cstar: Msr::IA32_CSTAR.read(),
@@ -161,14 +162,95 @@ impl LinuxContext {
161162
}
162163
}
163164

165+
pub fn construct_guest64(rip: u64, cr3: u64) -> Self {
166+
Self {
167+
rsp: 0,
168+
rip,
169+
r15: 0,
170+
r14: 0,
171+
r13: 0,
172+
r12: 0,
173+
rbx: 0,
174+
rbp: 0,
175+
es: Segment::invalid(),
176+
cs: Segment {
177+
selector: SegmentSelector::new(1, Ring::Ring0),
178+
base: 0,
179+
limit: 0xffff,
180+
access_rights: SegmentAccessRights::ACCESSED
181+
| SegmentAccessRights::WRITABLE
182+
| SegmentAccessRights::EXECUTABLE
183+
| SegmentAccessRights::CODE_DATA
184+
| SegmentAccessRights::PRESENT
185+
| SegmentAccessRights::LONG_MODE
186+
| SegmentAccessRights::GRANULARITY,
187+
},
188+
ss: Segment {
189+
selector: SegmentSelector::new(2, Ring::Ring0),
190+
base: 0,
191+
limit: 0xffff,
192+
access_rights: SegmentAccessRights::ACCESSED
193+
| SegmentAccessRights::WRITABLE
194+
| SegmentAccessRights::CODE_DATA
195+
| SegmentAccessRights::PRESENT
196+
| SegmentAccessRights::DB
197+
| SegmentAccessRights::GRANULARITY,
198+
},
199+
ds: Segment::invalid(),
200+
fs: Segment::invalid(),
201+
gs: Segment::invalid(),
202+
tss: Segment {
203+
selector: SegmentSelector::new(2, Ring::Ring0),
204+
base: 0,
205+
limit: 0,
206+
access_rights: SegmentAccessRights::ACCESSED
207+
| SegmentAccessRights::WRITABLE
208+
| SegmentAccessRights::EXECUTABLE
209+
| SegmentAccessRights::PRESENT,
210+
},
211+
gdt: DescriptorTablePointer {
212+
limit: 0,
213+
base: VirtAddr::zero(),
214+
},
215+
idt: DescriptorTablePointer {
216+
limit: 0,
217+
base: VirtAddr::zero(),
218+
},
219+
cr0: Cr0Flags::PROTECTED_MODE_ENABLE
220+
| Cr0Flags::MONITOR_COPROCESSOR
221+
| Cr0Flags::EXTENSION_TYPE
222+
| Cr0Flags::NUMERIC_ERROR
223+
| Cr0Flags::WRITE_PROTECT
224+
| Cr0Flags::ALIGNMENT_MASK
225+
| Cr0Flags::PAGING,
226+
cr3,
227+
cr4: Cr4Flags::PHYSICAL_ADDRESS_EXTENSION | Cr4Flags::PAGE_GLOBAL,
228+
efer: EferFlags::LONG_MODE_ENABLE
229+
| EferFlags::LONG_MODE_ACTIVE
230+
| EferFlags::NO_EXECUTE_ENABLE
231+
| EferFlags::SYSTEM_CALL_EXTENSIONS,
232+
star: 0,
233+
lstar: 0,
234+
cstar: 0,
235+
fmask: 0,
236+
ia32_sysenter_cs: 0,
237+
ia32_sysenter_esp: 0,
238+
ia32_sysenter_eip: 0,
239+
kernel_gsbase: 0,
240+
pat: 0,
241+
mtrr_def_type: 0,
242+
xstate: XState::default(),
243+
}
244+
}
245+
164246
/// Restore system registers.
165247
pub fn restore(&self) {
166248
unsafe {
167249
Msr::IA32_SYSENTER_CS.write(self.ia32_sysenter_cs);
168250
Msr::IA32_SYSENTER_ESP.write(self.ia32_sysenter_esp);
169251
Msr::IA32_SYSENTER_EIP.write(self.ia32_sysenter_eip);
170252

171-
Msr::IA32_EFER.write(self.efer);
253+
Efer::write(self.efer);
172254
Msr::IA32_STAR.write(self.star);
173255
Msr::IA32_LSTAR.write(self.lstar);
174256
Msr::IA32_CSTAR.write(self.cstar);

src/vmx/vcpu.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ impl<H: AxVCpuHal> VmxVcpu<H> {
570570
VmcsGuest32::VMX_PREEMPTION_TIMER_VALUE.write(0)?;
571571

572572
VmcsGuest64::IA32_PAT.write(linux.pat)?;
573-
VmcsGuest64::IA32_EFER.write(linux.efer)?;
573+
VmcsGuest64::IA32_EFER.write(linux.efer.bits())?;
574574

575575
Ok(())
576576
}

0 commit comments

Comments
 (0)