Skip to content

feat(instructions): Add lldt and sldt - #621

Merged
Freax13 merged 2 commits into
rust-osdev:masterfrom
llp42:feat/lldt-sldt
Oct 11, 2026
Merged

Freax13 merged 2 commits into
rust-osdev:masterfrom
llp42:feat/lldt-sldt

Conversation

@llp42

@llp42 llp42 commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Closes #620.

This adds lldt and sldt to instructions::tables, next to load_tss. #620 has the use case: a GNU Mach-compatible kernel in Rust loads each thread's own LDT (i386_set_ldt) on every context switch, and reads the LDT register to skip a redundant load.

pub unsafe fn lldt(sel: SegmentSelector);
pub fn sldt() -> SegmentSelector;

lldt is unsafe like load_tss: the selector must be null or name an LDT descriptor in the GDT, and that LDT has to stay valid while it is loaded, since every segment load through an LDT selector reads it. Unlike ltr, lldt writes nothing back to the descriptor (an LDT descriptor has no busy or accessed bit), so its asm! is readonly like lgdt's, and the same LDT can be loaded on several CPUs. sldt is safe like sgdt; it only copies the LDTR selector into a register.

The tests in testing/tests/ldt.rs load an LDT through the GDT and check what the docs promise:

  • lldt_and_sldt — lldt loads a selector, sldt reads it back.
  • lldt_does_not_modify_gdt — the GDT entry is unchanged afterwards.
  • lldt_null — SegmentSelector::NULL invalidates the LDTR.
  • ldt_segment_load — a segment load through an LDT selector picks up the base from the LDT entry.

That last one is the one that matters: the others only look at the LDTR and would still pass if the table were never consulted. All four pass under QEMU's emulator and under KVM on an Intel i7-11800H.

I also ran cargo build, doc and test with the default features, with no default features, with memory_encryption and with nightly, plus cargo clippy and cargo fmt --check, on stable 1.99 and on nightly with RUSTFLAGS=-Dwarnings and RUSTDOCFLAGS=-Dwarnings.

Both functions are additive, so nothing existing changes except the tables module doc line.

llp42 added 2 commits October 10, 2026 15:55
Kernels that give threads their own LDT, as Mach's `i386_set_ldt` and
Linux's `modify_ldt` do, load the LDT register on context switches and
read it to skip redundant loads.
Load an LDT through the GDT and check that `lldt` loads its selector,
that `sldt` reads it back, and that a null selector invalidates the
LDTR. `lldt` must leave the GDT entry alone, unlike `ltr`, which is why
one LDT may be loaded on several CPUs. A segment load through the LDT
shows that the table is really live.

@Freax13 Freax13 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution!

The lldt and sldt wrappers looks good to me, but I'm wondering if we should also some more function and types to actually build and use an LDT (see ldt.rs for what's necessary to do that). Would you be interested in working on that? If not, I'm also fine with merging this as is.

@llp42

llp42 commented Oct 11, 2026

Copy link
Copy Markdown
Contributor Author

Thank you! It’s an honor to contribute to the project.

I'm fine with merging this as is for now. I do plan to open other PRs, but I'm preferring to keep my contributions atomic (small PRs) rather than giant ones.

Right now, I'm adding features step-by-step according to the real demands of my own project, so I'll definitely look into the LDT building functions as soon as I need them.

Feel free to merge this one when you're ready!

@Freax13

Freax13 commented Oct 11, 2026

Copy link
Copy Markdown
Member

I'm fine with merging this as is for now. I do plan to open other PRs, but I'm preferring to keep my contributions atomic (small PRs) rather than giant ones.

Right now, I'm adding features step-by-step according to the real demands of my own project, so I'll definitely look into the LDT building functions as soon as I need them.

Sounds good, thanks!

@Freax13
Freax13 merged commit abfad76 into rust-osdev:master Oct 11, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add lldt and sldt instructions

2 participants