@@ -306,6 +306,17 @@ impl Descriptor {
306
306
/// Creates a TSS system descriptor for the given TSS.
307
307
#[ inline]
308
308
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 {
309
320
use self :: DescriptorFlags as Flags ;
310
321
use core:: mem:: size_of;
311
322
@@ -315,8 +326,11 @@ impl Descriptor {
315
326
// base
316
327
low. set_bits ( 16 ..40 , ptr. get_bits ( 0 ..24 ) ) ;
317
328
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
+ ) ;
320
334
// type (0b1001 = available 64-bit tss)
321
335
low. set_bits ( 40 ..44 , 0b1001 ) ;
322
336
0 commit comments