You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I want to use the I/O Permission Bitmap (IOBP) to allow a user space program to access COM1 only. But the current TSS and GDT code doesn't make it easy. This is what I did to get it to work:
/// `N` is the size of the IOBP in **bytes**/// Do not change `iomap_base`. It is set to the correct value by the `default` function./// By default, the IOPB is set to all 1s, so that no port access is allowed#[derive(Debug,Clone,Copy)]#[repr(C, packed(4))]pubstructTssWithIoBitMap<constN:usize>{pubabove_iobp:TaskStateSegment,pubactual_io_bitmap:[u8;N],/// According to Section 20.5.2 in *Intel® 64 and IA-32 Architectures Software Developer’s Manual*/// > Last byte of bitmap must be followed by a byte with all bits set.io_bit_map_last_byte:u8,}impl<constN:usize>DefaultforTssWithIoBitMap<N>{fndefault() -> Self{Self{above_iobp:{letmut tss = TaskStateSegment::default();
tss.iomap_base = (offset_of!(Self, actual_io_bitmap)).try_into().unwrap();
tss
},// If a bit is 0 it means the port is allowed, 1 is not allowedactual_io_bitmap:[u8::MAX;N],io_bit_map_last_byte: u8::MAX,}}}
and
implDescriptor{/// Similar to [`Descriptor::tss_segment`], but unsafe since it does not enforce a lifetime/// constraint on the provided TSS.////// # Safety/// The caller must ensure that the passed pointer is valid for as long as the descriptor is/// being used.#[inline]pubunsafefntss_segment_unchecked_with_size(tss:*constTaskStateSegment,size:u64,) -> Descriptor{useself::DescriptorFlagsasFlags;use core::mem::size_of;let ptr = tss asu64;letmut low = Flags::PRESENT.bits();// base
low.set_bits(16..40, ptr.get_bits(0..24));
low.set_bits(56..64, ptr.get_bits(24..32));// limit (the `-1` in needed since the bound is inclusive)
low.set_bits(0..16, size - 1);// type (0b1001 = available 64-bit tss)
low.set_bits(40..44,0b1001);letmut high = 0;
high.set_bits(0..32, ptr.get_bits(32..64));Descriptor::SystemSegment(low, high)}}
and then in my GDT code:
let tss_selector = gdt.append(unsafe{Descriptor::tss_segment_unchecked_with_size(
tss as*const_as*constTaskStateSegment,size_of::<TssWithIoBitMap<N>>()asu64,)});
I only did this to test out using the IOPB. Ideally this library would make it easier and safer.
I can make a PR for this feature, but there are some things to decide first:
The IOPB can be variable length, which would make TSS variable length
Should we have a <const N: usize> generic for the IOPB in the TSS? Would this make it too inconvenient for the majority of people who don't want a IOPB?
IMO the iomap_base in TaskStateSegment should not be public or modifyable outside of this library because it should always be 104
The IOPB can be changed at any time by the kernel after initializing the tss and gdt, without needing to reload anything (I think). How can there be a safe way of doing this without unsafe when pub fn tss_segment(tss: &'static TaskStateSegment) -> Descriptor takes an immutable reference to the tss? Perhaps the function could be changed to Pin<&TaskStateSegment>? Idk much about pin though.
I want to use the I/O Permission Bitmap (IOBP) to allow a user space program to access COM1 only. But the current TSS and GDT code doesn't make it easy. This is what I did to get it to work:
and
and then in my GDT code:
I only did this to test out using the IOPB. Ideally this library would make it easier and safer.
I can make a PR for this feature, but there are some things to decide first:
<const N: usize>
generic for the IOPB in the TSS? Would this make it too inconvenient for the majority of people who don't want a IOPB?iomap_base
inTaskStateSegment
should not be public or modifyable outside of this library because it should always be104
unsafe
whenpub fn tss_segment(tss: &'static TaskStateSegment) -> Descriptor
takes an immutable reference to the tss? Perhaps the function could be changed toPin<&TaskStateSegment>
? Idk much about pin though.Also I just realized #194 exists
I actually implemented this at https://github.com/ChocolateLoverRaj/x86_64/tree/develop, I think it's a good API.
The text was updated successfully, but these errors were encountered: