@@ -439,17 +439,33 @@ impl Descriptor {
439
439
/// being used.
440
440
#[ inline]
441
441
pub unsafe fn tss_segment_unchecked ( tss : * const TaskStateSegment ) -> Descriptor {
442
+ // TODO: Remove this with a call to a function that takes a method
443
+ // instead of a static reference.
444
+ // SAFETY: if iomap_size is zero, there are no requirements to uphold.
445
+ unsafe { Self :: tss_segment_with_iomap ( & * tss, 0 ) }
446
+ }
447
+
448
+ /// Creates a TSS system descriptor for the given TSS, setting up the IO permissions bitmap.
449
+ ///
450
+ /// # Safety
451
+ ///
452
+ /// If `iomap_size` is greater than zero, there **must** be a valid IO map at `tss_ptr + iomap_base`.
453
+ /// The size of the IO map must correspond with the given `iomap_size`.
454
+ pub unsafe fn tss_segment_with_iomap ( tss : & ' static TaskStateSegment , iomap_size : u16 ) -> Descriptor {
442
455
use self :: DescriptorFlags as Flags ;
443
456
use core:: mem:: size_of;
444
457
445
- let ptr = tss as u64 ;
458
+ let ptr = tss as * const _ as u64 ;
446
459
447
460
let mut low = Flags :: PRESENT . bits ( ) ;
448
461
// base
449
462
low. set_bits ( 16 ..40 , ptr. get_bits ( 0 ..24 ) ) ;
450
463
low. set_bits ( 56 ..64 , ptr. get_bits ( 24 ..32 ) ) ;
451
- // limit (the `-1` in needed since the bound is inclusive)
452
- low. set_bits ( 0 ..16 , ( size_of :: < TaskStateSegment > ( ) - 1 ) as u64 ) ;
464
+ // limit (the `-1` is needed since the bound is inclusive)
465
+ low. set_bits (
466
+ 0 ..16 ,
467
+ ( size_of :: < TaskStateSegment > ( ) + ( tss. iomap_base + iomap_size) as usize - 1 ) as u64
468
+ ) ;
453
469
// type (0b1001 = available 64-bit tss)
454
470
low. set_bits ( 40 ..44 , 0b1001 ) ;
455
471
0 commit comments