Bug #13085

fast_syscall state should be tracked

Added by Patrick Mooney 8 months ago. Updated 8 months ago.

Start date:
Due date:
% Done:


Estimated time:
Gerrit CR:


Upstreaming OS-7084 from SmartOS:

The i86pc platform disables fast syscalls on a CPU (SYSENTER/SYSCALL) via cpu_fast_syscall_disable when an LDT is configured in a 32-bit process. Process-wide ctxops will re-enable that functionality when its threads are departing the CPU. This disabled state is kept only in the relevant MSRs, not tracked in a structure that's easily accessible from mdb (on a live system or a dump).

It would be nice to track that in the struct machcpu for inspection.

To test, I booted a machine up on a PI with the fix. In its normal state, all CPUs reported having SYSCALL/SYSENTER enabled:

> ::walk cpu | ::print cpu_t cpu_m.mcpu_fast_syscall_state ! uniq -c
40 cpu_m.mcpu_fast_syscall_state = 0x3 (FSS_{ASYSC_ENABLED|SEP_ENABLED})

I modified a copy of ldt.c from the in-gate tests to busy-spin in its worker threads (rather than sleeping like the original test). With 10 threads active in a 32-bit process utilizing a custom LDT, the OS reported SYSCALL/SYSENTER as disabled for the CPUs in question:

> ::walk cpu | ::print cpu_t cpu_m.mcpu_fast_syscall_state ! sort | uniq -c
10 cpu_m.mcpu_fast_syscall_state = 0 (0)
30 cpu_m.mcpu_fast_syscall_state = 0x3 (FSS_{ASYSC_ENABLED|SEP_ENABLED})

The updated donothing function in ldt.c which definitely does something now:

static void *
donothing(void *nothing)
        timespec_t start, ts;

        clock_gettime(CLOCK_REALTIME, &start);

        for (;;) {
                clock_gettime(CLOCK_REALTIME, &ts);
                if ((ts.tv_sec - start.tv_sec) > 10)
        return (NULL);

Updated by Electric Monk 8 months ago

  • Gerrit CR set to 880

Updated by Patrick Mooney 8 months ago

I repeated the above test, using the modified ldt.c on an illumos-gate BE featuring the change. Before running the resulting binary, all CPUs reported FSS_ASYSC_ENABLED (as this was an AMD machine without sysenter enabled). With the test binary running threads featuring an ldt, those 10 CPUs reported syscall as disabled.


Updated by Electric Monk 8 months ago

  • Status changed from In Progress to Closed

git commit 8515d723262b57176aeeda8734edbe79fe1e7a5a

commit  8515d723262b57176aeeda8734edbe79fe1e7a5a
Author: Patrick Mooney <>
Date:   2020-09-01T19:00:14.000Z

    13085 fast_syscall state should be tracked
    Reviewed by: John Levon <>
    Reviewed by: Robert Mustacchi <>
    Reviewed by: Toomas Soome <>
    Approved by: Dan McDonald <>

Also available in: Atom PDF