1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2017 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker
5*bb4ee6a4SAndroid Build Coastguard Worker // For GDT details see arch/x86/include/asm/segment.h
6*bb4ee6a4SAndroid Build Coastguard Worker
7*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::Segment;
8*bb4ee6a4SAndroid Build Coastguard Worker
9*bb4ee6a4SAndroid Build Coastguard Worker /// Constructor for a conventional segment GDT (or LDT) entry. Derived from the kernel's segment.h.
gdt_entry(flags: u16, base: u32, limit: u32) -> u6410*bb4ee6a4SAndroid Build Coastguard Worker pub fn gdt_entry(flags: u16, base: u32, limit: u32) -> u64 {
11*bb4ee6a4SAndroid Build Coastguard Worker (((base as u64) & 0xff000000u64) << (56 - 24))
12*bb4ee6a4SAndroid Build Coastguard Worker | (((flags as u64) & 0x0000f0ffu64) << 40)
13*bb4ee6a4SAndroid Build Coastguard Worker | (((limit as u64) & 0x000f0000u64) << (48 - 16))
14*bb4ee6a4SAndroid Build Coastguard Worker | (((base as u64) & 0x00ffffffu64) << 16)
15*bb4ee6a4SAndroid Build Coastguard Worker | ((limit as u64) & 0x0000ffffu64)
16*bb4ee6a4SAndroid Build Coastguard Worker }
17*bb4ee6a4SAndroid Build Coastguard Worker
get_base(entry: u64) -> u6418*bb4ee6a4SAndroid Build Coastguard Worker fn get_base(entry: u64) -> u64 {
19*bb4ee6a4SAndroid Build Coastguard Worker (((entry) & 0xFF00000000000000) >> 32)
20*bb4ee6a4SAndroid Build Coastguard Worker | (((entry) & 0x000000FF00000000) >> 16)
21*bb4ee6a4SAndroid Build Coastguard Worker | (((entry) & 0x00000000FFFF0000) >> 16)
22*bb4ee6a4SAndroid Build Coastguard Worker }
23*bb4ee6a4SAndroid Build Coastguard Worker
get_limit(entry: u64) -> u3224*bb4ee6a4SAndroid Build Coastguard Worker fn get_limit(entry: u64) -> u32 {
25*bb4ee6a4SAndroid Build Coastguard Worker ((((entry) & 0x000F000000000000) >> 32) | ((entry) & 0x000000000000FFFF)) as u32
26*bb4ee6a4SAndroid Build Coastguard Worker }
27*bb4ee6a4SAndroid Build Coastguard Worker
get_g(entry: u64) -> u828*bb4ee6a4SAndroid Build Coastguard Worker fn get_g(entry: u64) -> u8 {
29*bb4ee6a4SAndroid Build Coastguard Worker ((entry & 0x0080000000000000) >> 55) as u8
30*bb4ee6a4SAndroid Build Coastguard Worker }
31*bb4ee6a4SAndroid Build Coastguard Worker
get_db(entry: u64) -> u832*bb4ee6a4SAndroid Build Coastguard Worker fn get_db(entry: u64) -> u8 {
33*bb4ee6a4SAndroid Build Coastguard Worker ((entry & 0x0040000000000000) >> 54) as u8
34*bb4ee6a4SAndroid Build Coastguard Worker }
35*bb4ee6a4SAndroid Build Coastguard Worker
get_l(entry: u64) -> u836*bb4ee6a4SAndroid Build Coastguard Worker fn get_l(entry: u64) -> u8 {
37*bb4ee6a4SAndroid Build Coastguard Worker ((entry & 0x0020000000000000) >> 53) as u8
38*bb4ee6a4SAndroid Build Coastguard Worker }
39*bb4ee6a4SAndroid Build Coastguard Worker
get_avl(entry: u64) -> u840*bb4ee6a4SAndroid Build Coastguard Worker fn get_avl(entry: u64) -> u8 {
41*bb4ee6a4SAndroid Build Coastguard Worker ((entry & 0x0010000000000000) >> 52) as u8
42*bb4ee6a4SAndroid Build Coastguard Worker }
43*bb4ee6a4SAndroid Build Coastguard Worker
get_p(entry: u64) -> u844*bb4ee6a4SAndroid Build Coastguard Worker fn get_p(entry: u64) -> u8 {
45*bb4ee6a4SAndroid Build Coastguard Worker ((entry & 0x0000800000000000) >> 47) as u8
46*bb4ee6a4SAndroid Build Coastguard Worker }
47*bb4ee6a4SAndroid Build Coastguard Worker
get_dpl(entry: u64) -> u848*bb4ee6a4SAndroid Build Coastguard Worker fn get_dpl(entry: u64) -> u8 {
49*bb4ee6a4SAndroid Build Coastguard Worker ((entry & 0x0000600000000000) >> 45) as u8
50*bb4ee6a4SAndroid Build Coastguard Worker }
51*bb4ee6a4SAndroid Build Coastguard Worker
get_s(entry: u64) -> u852*bb4ee6a4SAndroid Build Coastguard Worker fn get_s(entry: u64) -> u8 {
53*bb4ee6a4SAndroid Build Coastguard Worker ((entry & 0x0000100000000000) >> 44) as u8
54*bb4ee6a4SAndroid Build Coastguard Worker }
55*bb4ee6a4SAndroid Build Coastguard Worker
get_type(entry: u64) -> u856*bb4ee6a4SAndroid Build Coastguard Worker fn get_type(entry: u64) -> u8 {
57*bb4ee6a4SAndroid Build Coastguard Worker ((entry & 0x00000F0000000000) >> 40) as u8
58*bb4ee6a4SAndroid Build Coastguard Worker }
59*bb4ee6a4SAndroid Build Coastguard Worker
60*bb4ee6a4SAndroid Build Coastguard Worker /// Automatically build the hypervisor Segment struct for set_sregs from the kernel bit fields.
61*bb4ee6a4SAndroid Build Coastguard Worker ///
62*bb4ee6a4SAndroid Build Coastguard Worker /// # Arguments
63*bb4ee6a4SAndroid Build Coastguard Worker ///
64*bb4ee6a4SAndroid Build Coastguard Worker /// * `entry` - The gdt entry.
65*bb4ee6a4SAndroid Build Coastguard Worker /// * `table_index` - Index of the entry in the gdt table.
segment_from_gdt(entry: u64, table_index: u8) -> Segment66*bb4ee6a4SAndroid Build Coastguard Worker pub fn segment_from_gdt(entry: u64, table_index: u8) -> Segment {
67*bb4ee6a4SAndroid Build Coastguard Worker let g = get_g(entry);
68*bb4ee6a4SAndroid Build Coastguard Worker let limit = get_limit(entry);
69*bb4ee6a4SAndroid Build Coastguard Worker let limit_bytes = if g == 0 {
70*bb4ee6a4SAndroid Build Coastguard Worker // 1-byte granularity
71*bb4ee6a4SAndroid Build Coastguard Worker limit
72*bb4ee6a4SAndroid Build Coastguard Worker } else {
73*bb4ee6a4SAndroid Build Coastguard Worker // 4096-byte granularity
74*bb4ee6a4SAndroid Build Coastguard Worker (limit * 4096) + 4095
75*bb4ee6a4SAndroid Build Coastguard Worker };
76*bb4ee6a4SAndroid Build Coastguard Worker
77*bb4ee6a4SAndroid Build Coastguard Worker Segment {
78*bb4ee6a4SAndroid Build Coastguard Worker base: get_base(entry),
79*bb4ee6a4SAndroid Build Coastguard Worker limit_bytes,
80*bb4ee6a4SAndroid Build Coastguard Worker selector: (table_index * 8) as u16,
81*bb4ee6a4SAndroid Build Coastguard Worker type_: get_type(entry),
82*bb4ee6a4SAndroid Build Coastguard Worker present: get_p(entry),
83*bb4ee6a4SAndroid Build Coastguard Worker dpl: get_dpl(entry),
84*bb4ee6a4SAndroid Build Coastguard Worker db: get_db(entry),
85*bb4ee6a4SAndroid Build Coastguard Worker s: get_s(entry),
86*bb4ee6a4SAndroid Build Coastguard Worker l: get_l(entry),
87*bb4ee6a4SAndroid Build Coastguard Worker g,
88*bb4ee6a4SAndroid Build Coastguard Worker avl: get_avl(entry),
89*bb4ee6a4SAndroid Build Coastguard Worker }
90*bb4ee6a4SAndroid Build Coastguard Worker }
91*bb4ee6a4SAndroid Build Coastguard Worker
92*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(test)]
93*bb4ee6a4SAndroid Build Coastguard Worker mod test {
94*bb4ee6a4SAndroid Build Coastguard Worker use super::*;
95*bb4ee6a4SAndroid Build Coastguard Worker
96*bb4ee6a4SAndroid Build Coastguard Worker #[test]
field_parse()97*bb4ee6a4SAndroid Build Coastguard Worker fn field_parse() {
98*bb4ee6a4SAndroid Build Coastguard Worker let gdt = gdt_entry(0xA09B, 0x100000, 0xfffff);
99*bb4ee6a4SAndroid Build Coastguard Worker let seg = segment_from_gdt(gdt, 0);
100*bb4ee6a4SAndroid Build Coastguard Worker // 0xA09B
101*bb4ee6a4SAndroid Build Coastguard Worker // 'A'
102*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(0x1, seg.g);
103*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(0x0, seg.db);
104*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(0x1, seg.l);
105*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(0x0, seg.avl);
106*bb4ee6a4SAndroid Build Coastguard Worker // '9'
107*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(0x1, seg.present);
108*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(0x0, seg.dpl);
109*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(0x1, seg.s);
110*bb4ee6a4SAndroid Build Coastguard Worker // 'B'
111*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(0xB, seg.type_);
112*bb4ee6a4SAndroid Build Coastguard Worker // base and limit
113*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(0x100000, seg.base);
114*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(0xffffffff, seg.limit_bytes);
115*bb4ee6a4SAndroid Build Coastguard Worker }
116*bb4ee6a4SAndroid Build Coastguard Worker }
117