Project

General

Profile

Bug #13085

fast_syscall state should be tracked

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

Status:
Closed
Priority:
Normal
Category:
kernel
Start date:
Due date:
% Done:

100%

Estimated time:
Difficulty:
Medium
Tags:
Gerrit CR:

Description

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)
                        break;
        }
        return (NULL);
}
#1

Updated by Electric Monk 6 months ago

  • Gerrit CR set to 880
#2

Updated by Patrick Mooney 6 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.

#3

Updated by Electric Monk 6 months ago

  • Status changed from In Progress to Closed

git commit 8515d723262b57176aeeda8734edbe79fe1e7a5a

commit  8515d723262b57176aeeda8734edbe79fe1e7a5a
Author: Patrick Mooney <pmooney@pfmooney.com>
Date:   2020-09-01T19:00:14.000Z

    13085 fast_syscall state should be tracked
    Reviewed by: John Levon <john.levon@joyent.com>
    Reviewed by: Robert Mustacchi <rm@joyent.com>
    Reviewed by: Toomas Soome <tsoome@me.com>
    Approved by: Dan McDonald <danmcd@joyent.com>

Also available in: Atom PDF