Patch "selftests/x86/fsgsbase: Test selectors 1, 2, and 3" has been added to the 4.13-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
selftests/x86/fsgsbase: Test selectors 1, 2, and 3
to the 4.13-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
selftests-x86-fsgsbase-test-selectors-1-2-and-3.patch
and it can be found in the queue-4.13 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
23d98c204386a98d9ef9f9e744f41443ece4929fMon Sep 17 00:00:00 2001
From: Andy Lutomirski <[email protected]>
Date: Tue, 1 Aug 2017 07:11:36 -0700
Subject: selftests/x86/fsgsbase: Test selectors 1, 2, and 3
From: Andy Lutomirski <[email protected]>
commit 23d98c204386a98d9ef9f9e744f41443ece4929f upstream.
Those are funny cases. Make sure they work.
(Something is screwy with signal handling if a selector is 1, 2, or 3. Anyone who wants to dive into that rabbit hole is welcome to do so.)
--- tools/testing/selftests/x86/fsgsbase.c | 41 ++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 6 deletions(-)
tools/testing/selftests/x86/fsgsbase.c +35 -6
@@ -285,9 +285,12 @@ static void *threadproc(void *ctx) } } -static void set_gs_and_switch_to (unsigned long local,unsigned long remote) +static void set_gs_and_switch_to (unsigned long local, +unsigned short force_sel, +unsigned long remote) {unsigned long base; +unsigned short sel_pre_sched, sel_post_sched;bool hard_zero = false;if (local ==HARD_ZERO ) {
@@ -297,6 +300,8 @@ static void set_gs_and_switch_to(unsigneprintf ("[RUN]\tARCH_SET_GS(0x%lx)%s, then schedule to 0x%lx\n" , local, hard_zero ?" and clear gs" :"" , remote); +if (force_sel) +printf ("\tBefore schedule, set selector to 0x%hx\n" , force_sel);if (syscall (SYS_arch_prctl,ARCH_SET_GS , local) !=0 )err (1 ,"ARCH_SET_GS" );if (hard_zero)
@@ -307,18 +312,35 @@ static void set_gs_and_switch_to(unsigneprintf ("[FAIL]\tGSBASE wasn't set as expected\n" ); } +if (force_sel) { + asmvolatile ("mov %0, %%gs" : :"rm" (force_sel)); + sel_pre_sched = force_sel; + local =read_base (GS ); + +/* +* Signal delivery seems to mess up weird selectors. Put it +* back. +*/ + asmvolatile ("mov %0, %%gs" : :"rm" (force_sel)); + }else { + asmvolatile ("mov %%gs, %0" :"=rm" (sel_pre_sched)); + } + remote_base = remote; ftx =1 ;syscall (SYS_futex, &ftx,FUTEX_WAKE ,0 ,NULL ,NULL ,0 );while (ftx !=0 )syscall (SYS_futex, &ftx,FUTEX_WAIT ,1 ,NULL ,NULL ,0 ); + asmvolatile ("mov %%gs, %0" :"=rm" (sel_post_sched)); base =read_base (GS ); -if (base == local) { -printf ("[OK]\tGSBASE remained 0x%lx\n" , local); +if (base == local && sel_pre_sched == sel_post_sched) { +printf ("[OK]\tGS/BASE remained 0x%hx/0x%lx\n" , + sel_pre_sched, local); }else { nerrs++; -printf ("[FAIL]\tGSBASE changed to 0x%lx\n" , base); +printf ("[FAIL]\tGS/BASE changed from 0x%hx/0x%lx to 0x%hx/0x%lx\n" , + sel_pre_sched, local, sel_post_sched, base); } }
@@ -381,8 +403,15 @@ int main()for (int local =0 ; local <4 ; local++) {for (int remote =0 ; remote <4 ; remote++) { -set_gs_and_switch_to (bases_with_hard_zero[local], - bases_with_hard_zero[remote]); +for (unsigned short s =0 ; s <5 ; s++) { +unsigned short sel = s; +if (s ==4 ) + asm ("mov %%ss, %0" :"=rm" (sel)); +set_gs_and_switch_to ( + bases_with_hard_zero[local], + sel, + bases_with_hard_zero[remote]); + } } }
Patches currently in stable-queue which might be from [email protected] are
queue-4.13/selftests-x86-fsgsbase-test-selectors-1-2-and-3.patch