1 use crate::arch::kvm::VmcsFields::{
2 GUEST_CS_ACCESS_RIGHTS, GUEST_CS_BASE, GUEST_CS_LIMIT, GUEST_CS_SELECTOR,
3 };
4 use crate::arch::kvm::VmcsFields::{
5 GUEST_DS_ACCESS_RIGHTS, GUEST_DS_BASE, GUEST_DS_LIMIT, GUEST_DS_SELECTOR,
6 };
7 use crate::arch::kvm::VmcsFields::{
8 GUEST_ES_ACCESS_RIGHTS, GUEST_ES_BASE, GUEST_ES_LIMIT, GUEST_ES_SELECTOR,
9 };
10 use crate::arch::kvm::VmcsFields::{
11 GUEST_FS_ACCESS_RIGHTS, GUEST_FS_BASE, GUEST_FS_LIMIT, GUEST_FS_SELECTOR,
12 };
13 use crate::arch::kvm::VmcsFields::{
14 GUEST_GS_ACCESS_RIGHTS, GUEST_GS_BASE, GUEST_GS_LIMIT, GUEST_GS_SELECTOR,
15 };
16 use crate::arch::kvm::VmcsFields::{
17 GUEST_LDTR_ACCESS_RIGHTS, GUEST_LDTR_BASE, GUEST_LDTR_LIMIT, GUEST_LDTR_SELECTOR,
18 };
19 use crate::arch::kvm::VmcsFields::{
20 GUEST_SS_ACCESS_RIGHTS, GUEST_SS_BASE, GUEST_SS_LIMIT, GUEST_SS_SELECTOR,
21 };
22 use crate::arch::kvm::VmcsFields::{
23 GUEST_TR_ACCESS_RIGHTS, GUEST_TR_BASE, GUEST_TR_LIMIT, GUEST_TR_SELECTOR,
24 };
25 use system_error::SystemError;
26
27 use super::vmx_asm_wrapper::vmx_vmwrite;
28
29 // pub const TSS_IOPB_BASE_OFFSET: usize = 0x66;
30 // pub const TSS_BASE_SIZE: usize = 0x68;
31 // pub const TSS_IOPB_SIZE: usize = 65536 / 8;
32 // pub const TSS_REDIRECTION_SIZE: usize = 256 / 8;
33 // pub const RMODE_TSS_SIZE: usize = TSS_BASE_SIZE + TSS_REDIRECTION_SIZE + TSS_IOPB_SIZE + 1;
34
35 #[derive(Debug)]
36 pub struct KvmVmxSegmentField {
37 selector: u32,
38 base: u32,
39 limit: u32,
40 access_rights: u32,
41 }
42
43 macro_rules! VMX_SEGMENT_FIELD {
44 ($struct_name: ident) => {
45 KvmVmxSegmentField {
46 selector: concat_idents!(GUEST_, $struct_name, _SELECTOR) as u32,
47 base: concat_idents!(GUEST_, $struct_name, _BASE) as u32,
48 limit: concat_idents!(GUEST_, $struct_name, _LIMIT) as u32,
49 access_rights: concat_idents!(GUEST_, $struct_name, _ACCESS_RIGHTS) as u32,
50 }
51 };
52 }
53 #[derive(FromPrimitive)]
54 pub enum Sreg {
55 ES = 0,
56 CS = 1,
57 SS = 2,
58 DS = 3,
59 FS = 4,
60 GS = 5,
61 TR = 6,
62 LDTR = 7,
63 }
64
65 static KVM_VMX_SEGMENT_FIELDS: [KvmVmxSegmentField; 8] = [
66 VMX_SEGMENT_FIELD!(ES),
67 VMX_SEGMENT_FIELD!(CS),
68 VMX_SEGMENT_FIELD!(SS),
69 VMX_SEGMENT_FIELD!(DS),
70 VMX_SEGMENT_FIELD!(FS),
71 VMX_SEGMENT_FIELD!(GS),
72 VMX_SEGMENT_FIELD!(TR),
73 VMX_SEGMENT_FIELD!(LDTR),
74 ];
75
seg_setup(seg: usize) -> Result<(), SystemError>76 pub fn seg_setup(seg: usize) -> Result<(), SystemError> {
77 let seg_field = &KVM_VMX_SEGMENT_FIELDS[seg];
78 let mut access_rigt = 0x0093;
79 if seg == Sreg::CS as usize {
80 access_rigt |= 0x08;
81 }
82 // setup segment fields
83 vmx_vmwrite(seg_field.selector, 0)?;
84 vmx_vmwrite(seg_field.base, 0)?;
85 vmx_vmwrite(seg_field.limit, 0x0000_FFFF)?;
86 vmx_vmwrite(seg_field.access_rights, access_rigt)?;
87
88 Ok(())
89 }
90