From e33cabc4e1009052ebf44e8617e20655c01a4746 Mon Sep 17 00:00:00 2001 From: Michael Jenny Date: Sat, 9 Apr 2022 12:55:11 +0200 Subject: [PATCH 1/2] Correct wrong comment. Unlike the comment suggests, more descriptors fields than mentioned in the comment are recognized by the CPU --- src/registers/segmentation.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/registers/segmentation.rs b/src/registers/segmentation.rs index be497d075..ccc6b4690 100644 --- a/src/registers/segmentation.rs +++ b/src/registers/segmentation.rs @@ -107,10 +107,12 @@ impl fmt::Debug for SegmentSelector { /// Code Segment /// -/// The segment base and limit are unused in 64-bit mode. Only the L (long), D -/// (default operation size), and DPL (descriptor privilege-level) fields of the -/// descriptor are recognized. So changing the segment register can be used to -/// change privilege level or enable/disable long mode. +/// Most fields like the segment base and limit are unused in 64-bit mode. +/// Only the LONG_MODE, PRESENT, USER_SEGMENT, EXECUTABLE, DEFAULT_SIZE (default operand size) +/// and DPL_RING_3 (descriptor privilege-level) fields of the +/// descriptor are recognized by the CPU. Some of them (e.g. DEFAULT_SIZE) are required to hold +/// a specific value and can't be changed. Others like the DPL_RING_3 and LONG_MODE +/// can be used to change privilege level or enable/disable long mode. #[derive(Debug)] pub struct CS; From 77a152f221d748e3708440abb04bfd7c534a0fb9 Mon Sep 17 00:00:00 2001 From: Joe Richey Date: Thu, 14 Apr 2022 00:34:08 -0700 Subject: [PATCH 2/2] Update comment and cleanup doc links Signed-off-by: Joe Richey --- src/registers/segmentation.rs | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/registers/segmentation.rs b/src/registers/segmentation.rs index ccc6b4690..0ef55d3ae 100644 --- a/src/registers/segmentation.rs +++ b/src/registers/segmentation.rs @@ -6,13 +6,15 @@ use bit_field::BitField; use core::fmt; // imports for intra doc links #[cfg(doc)] -use crate::registers::control::Cr4Flags; +use crate::{ + registers::control::Cr4Flags, + structures::gdt::{Descriptor, DescriptorFlags, GlobalDescriptorTable}, +}; /// An x86 segment /// /// Segment registers on x86 are 16-bit [`SegmentSelector`]s, which index into -/// the [`GlobalDescriptorTable`](crate::structures::gdt::GlobalDescriptorTable). The -/// corresponding GDT entry is used to +/// the [`GlobalDescriptorTable`]. The corresponding GDT entry is used to /// configure the segment itself. Note that most segmentation functionality is /// disabled in 64-bit mode. See the individual segments for more information. pub trait Segment { @@ -107,12 +109,19 @@ impl fmt::Debug for SegmentSelector { /// Code Segment /// -/// Most fields like the segment base and limit are unused in 64-bit mode. -/// Only the LONG_MODE, PRESENT, USER_SEGMENT, EXECUTABLE, DEFAULT_SIZE (default operand size) -/// and DPL_RING_3 (descriptor privilege-level) fields of the -/// descriptor are recognized by the CPU. Some of them (e.g. DEFAULT_SIZE) are required to hold -/// a specific value and can't be changed. Others like the DPL_RING_3 and LONG_MODE -/// can be used to change privilege level or enable/disable long mode. +/// While most fields in the Code-Segment [`Descriptor`] are unused in 64-bit +/// long mode, some of them must be set to a specific value. The +/// [`EXECUTABLE`](DescriptorFlags::EXECUTABLE), +/// [`USER_SEGMENT`](DescriptorFlags::USER_SEGMENT), and +/// [`LONG_MODE`](DescriptorFlags::LONG_MODE) bits must be set, while the +/// [`DEFAULT_SIZE`](DescriptorFlags::DEFAULT_SIZE) bit must be unset. +/// +/// The [`DPL_RING_3`](DescriptorFlags::DPL_RING_3) field can be used to change +/// privilege level. The [`PRESENT`](DescriptorFlags::PRESENT) bit can be used +/// to make a segment present or not present. +/// +/// All other fields (like the segment base and limit) are ignored by the +/// processor and setting them has no effect. #[derive(Debug)] pub struct CS; @@ -120,7 +129,7 @@ pub struct CS; /// /// Entirely unused in 64-bit mode; setting the segment register does nothing. /// However, in ring 3, the SS register still has to point to a valid -/// [`Descriptor`](crate::structures::gdt::Descriptor) (it cannot be zero). This +/// [`Descriptor`] (it cannot be zero). This /// means a user-mode read/write segment descriptor must be present in the GDT. /// /// This register is also set by the `syscall`/`sysret` and