@@ -5,6 +5,7 @@ use crate::PrivilegeLevel;
5
5
use bit_field:: BitField ;
6
6
use bitflags:: bitflags;
7
7
use core:: { cmp, fmt, mem} ;
8
+ use crate :: structures:: tss:: InvalidIoMap ;
8
9
9
10
/// Specifies which element to load into a segment from
10
11
/// descriptor tables (i.e., is a index to LDT or GDT table
@@ -307,7 +308,30 @@ impl Descriptor {
307
308
#[ inline]
308
309
pub fn tss_segment ( tss : & ' static TaskStateSegment ) -> Descriptor {
309
310
// SAFETY: if iomap_size is zero, there are no requirements to uphold.
310
- unsafe { Self :: tss_segment_with_iomap ( tss, 0 ) }
311
+ unsafe { Self :: tss_segment_raw ( tss, 0 ) }
312
+ }
313
+
314
+ /// Creates a TSS system descriptor for the given TSS, setting up the IO permissions bitmap.
315
+ pub fn tss_segment_with_iomap (
316
+ tss : & ' static TaskStateSegment ,
317
+ iomap : & ' static [ u8 ] ,
318
+ ) -> Result < Descriptor , InvalidIoMap > {
319
+ if iomap. len ( ) > 8193 {
320
+ return Err ( InvalidIoMap :: TooLong { len : iomap. len ( ) } )
321
+ }
322
+
323
+ let distance = iomap. as_ptr ( ) as usize - tss as * const _ as usize ;
324
+ if distance > 0xdfff {
325
+ return Err ( InvalidIoMap :: TooFarFromTss { distance } )
326
+ }
327
+
328
+ let last_byte = * iomap. last ( ) . unwrap_or ( & 0xff ) ;
329
+ if last_byte != 0xff {
330
+ return Err ( InvalidIoMap :: InvalidTerminatingByte { byte : last_byte } )
331
+ }
332
+
333
+ // SAFETY: all invariants checked above
334
+ Ok ( unsafe { Self :: tss_segment_raw ( tss, iomap. len ( ) as u16 ) } )
311
335
}
312
336
313
337
/// Creates a TSS system descriptor for the given TSS, setting up the IO permissions bitmap.
@@ -317,7 +341,7 @@ impl Descriptor {
317
341
/// There must be a valid IO map at `(tss as *const u8).offset(tss.iomap_base)`
318
342
/// of length `iomap_size`, with the terminating `0xFF` byte. Additionally, `iomap_base` must
319
343
/// not exceed `0xDFFF`.
320
- pub unsafe fn tss_segment_with_iomap (
344
+ unsafe fn tss_segment_raw (
321
345
tss : & ' static TaskStateSegment ,
322
346
iomap_size : u16 ,
323
347
) -> Descriptor {
0 commit comments