@@ -306,6 +306,17 @@ impl Descriptor {
306306 /// Creates a TSS system descriptor for the given TSS.
307307 #[ inline]
308308 pub fn tss_segment ( tss : & ' static TaskStateSegment ) -> Descriptor {
309+ // SAFETY: if iomap_size is zero, there are no requirements to uphold.
310+ unsafe { Self :: tss_segment_with_iomap ( tss, 0 ) }
311+ }
312+
313+ /// Creates a TSS system descriptor for the given TSS, setting up the IO permissions bitmap.
314+ ///
315+ /// # Safety
316+ ///
317+ /// If `iomap_size` is greater than zero, there **must** be a valid IO map at `tss_ptr + iomap_base`.
318+ /// The size of the IO map must correspond with the given `iomap_size`.
319+ pub unsafe fn tss_segment_with_iomap ( tss : & ' static TaskStateSegment , iomap_size : u16 ) -> Descriptor {
309320 use self :: DescriptorFlags as Flags ;
310321 use core:: mem:: size_of;
311322
@@ -315,8 +326,11 @@ impl Descriptor {
315326 // base
316327 low. set_bits ( 16 ..40 , ptr. get_bits ( 0 ..24 ) ) ;
317328 low. set_bits ( 56 ..64 , ptr. get_bits ( 24 ..32 ) ) ;
318- // limit (the `-1` in needed since the bound is inclusive)
319- low. set_bits ( 0 ..16 , ( size_of :: < TaskStateSegment > ( ) - 1 ) as u64 ) ;
329+ // limit (the `-1` is needed since the bound is inclusive)
330+ low. set_bits (
331+ 0 ..16 ,
332+ ( size_of :: < TaskStateSegment > ( ) + ( tss. iomap_base + iomap_size) as usize - 1 ) as u64
333+ ) ;
320334 // type (0b1001 = available 64-bit tss)
321335 low. set_bits ( 40 ..44 , 0b1001 ) ;
322336
0 commit comments