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 crate::syscall::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 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