mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
Add the BSD and Apache license. Make all crosvm references point to the BSD license. Add the right copyrights and identifier to our VMM code. Add Intel copyright to the vm-virtio and pci crates. Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
116 lines
3.1 KiB
Rust
116 lines
3.1 KiB
Rust
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE-BSD-3-Clause file.
|
|
|
|
// For GDT details see arch/x86/include/asm/segment.h
|
|
|
|
use kvm_bindings::kvm_segment;
|
|
|
|
/// Constructor for a conventional segment GDT (or LDT) entry. Derived from the kernel's segment.h.
|
|
pub fn gdt_entry(flags: u16, base: u32, limit: u32) -> u64 {
|
|
((((base as u64) & 0xff000000u64) << (56 - 24))
|
|
| (((flags as u64) & 0x0000f0ffu64) << 40)
|
|
| (((limit as u64) & 0x000f0000u64) << (48 - 16))
|
|
| (((base as u64) & 0x00ffffffu64) << 16)
|
|
| ((limit as u64) & 0x0000ffffu64))
|
|
}
|
|
|
|
fn get_base(entry: u64) -> u64 {
|
|
((((entry) & 0xFF00000000000000) >> 32)
|
|
| (((entry) & 0x000000FF00000000) >> 16)
|
|
| (((entry) & 0x00000000FFFF0000) >> 16))
|
|
}
|
|
|
|
fn get_limit(entry: u64) -> u32 {
|
|
((((entry) & 0x000F000000000000) >> 32) | ((entry) & 0x000000000000FFFF)) as u32
|
|
}
|
|
|
|
fn get_g(entry: u64) -> u8 {
|
|
((entry & 0x0080000000000000) >> 55) as u8
|
|
}
|
|
|
|
fn get_db(entry: u64) -> u8 {
|
|
((entry & 0x0040000000000000) >> 54) as u8
|
|
}
|
|
|
|
fn get_l(entry: u64) -> u8 {
|
|
((entry & 0x0020000000000000) >> 53) as u8
|
|
}
|
|
|
|
fn get_avl(entry: u64) -> u8 {
|
|
((entry & 0x0010000000000000) >> 52) as u8
|
|
}
|
|
|
|
fn get_p(entry: u64) -> u8 {
|
|
((entry & 0x0000800000000000) >> 47) as u8
|
|
}
|
|
|
|
fn get_dpl(entry: u64) -> u8 {
|
|
((entry & 0x0000600000000000) >> 45) as u8
|
|
}
|
|
|
|
fn get_s(entry: u64) -> u8 {
|
|
((entry & 0x0000100000000000) >> 44) as u8
|
|
}
|
|
|
|
fn get_type(entry: u64) -> u8 {
|
|
((entry & 0x00000F0000000000) >> 40) as u8
|
|
}
|
|
|
|
/// Automatically build the kvm struct for SET_SREGS from the kernel bit fields.
|
|
///
|
|
/// # Arguments
|
|
///
|
|
/// * `entry` - The gdt entry.
|
|
/// * `table_index` - Index of the entry in the gdt table.
|
|
pub fn kvm_segment_from_gdt(entry: u64, table_index: u8) -> kvm_segment {
|
|
kvm_segment {
|
|
base: get_base(entry),
|
|
limit: get_limit(entry),
|
|
selector: (table_index * 8) as u16,
|
|
type_: get_type(entry),
|
|
present: get_p(entry),
|
|
dpl: get_dpl(entry),
|
|
db: get_db(entry),
|
|
s: get_s(entry),
|
|
l: get_l(entry),
|
|
g: get_g(entry),
|
|
avl: get_avl(entry),
|
|
padding: 0,
|
|
unusable: match get_p(entry) {
|
|
0 => 1,
|
|
_ => 0,
|
|
},
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn field_parse() {
|
|
let gdt = gdt_entry(0xA09B, 0x100000, 0xfffff);
|
|
let seg = kvm_segment_from_gdt(gdt, 0);
|
|
// 0xA09B
|
|
// 'A'
|
|
assert_eq!(0x1, seg.g);
|
|
assert_eq!(0x0, seg.db);
|
|
assert_eq!(0x1, seg.l);
|
|
assert_eq!(0x0, seg.avl);
|
|
// '9'
|
|
assert_eq!(0x1, seg.present);
|
|
assert_eq!(0x0, seg.dpl);
|
|
assert_eq!(0x1, seg.s);
|
|
// 'B'
|
|
assert_eq!(0xB, seg.type_);
|
|
// base and limit
|
|
assert_eq!(0x100000, seg.base);
|
|
assert_eq!(0xfffff, seg.limit);
|
|
assert_eq!(0x0, seg.unusable);
|
|
}
|
|
}
|