xref: /DragonOS/kernel/src/arch/x86_64/kvm/vmx/seg.rs (revision fae6e9ade46a52976ad5d099643d51cc20876448)
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 
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