14
14
#include <sys/auxv.h>
15
15
#include <sys/mman.h>
16
16
#include <sys/shm.h>
17
+ #include <sys/ptrace.h>
17
18
#include <sys/syscall.h>
18
19
#include <sys/wait.h>
20
+ #include <sys/uio.h>
19
21
20
22
#include "../kselftest.h" /* For __cpuid_count() */
21
23
@@ -583,6 +585,13 @@ static void test_dynamic_state(void)
583
585
_exit (0 );
584
586
}
585
587
588
+ static inline int __compare_tiledata_state (struct xsave_buffer * xbuf1 , struct xsave_buffer * xbuf2 )
589
+ {
590
+ return memcmp (& xbuf1 -> bytes [xtiledata .xbuf_offset ],
591
+ & xbuf2 -> bytes [xtiledata .xbuf_offset ],
592
+ xtiledata .size );
593
+ }
594
+
586
595
/*
587
596
* Save current register state and compare it to @xbuf1.'
588
597
*
@@ -599,9 +608,7 @@ static inline bool __validate_tiledata_regs(struct xsave_buffer *xbuf1)
599
608
fatal_error ("failed to allocate XSAVE buffer\n" );
600
609
601
610
xsave (xbuf2 , XFEATURE_MASK_XTILEDATA );
602
- ret = memcmp (& xbuf1 -> bytes [xtiledata .xbuf_offset ],
603
- & xbuf2 -> bytes [xtiledata .xbuf_offset ],
604
- xtiledata .size );
611
+ ret = __compare_tiledata_state (xbuf1 , xbuf2 );
605
612
606
613
free (xbuf2 );
607
614
@@ -826,6 +833,99 @@ static void test_context_switch(void)
826
833
free (finfo );
827
834
}
828
835
836
+ /* Ptrace test */
837
+
838
+ /*
839
+ * Make sure the ptracee has the expanded kernel buffer on the first
840
+ * use. Then, initialize the state before performing the state
841
+ * injection from the ptracer.
842
+ */
843
+ static inline void ptracee_firstuse_tiledata (void )
844
+ {
845
+ load_rand_tiledata (stashed_xsave );
846
+ init_xtiledata ();
847
+ }
848
+
849
+ /*
850
+ * Ptracer injects the randomized tile data state. It also reads
851
+ * before and after that, which will execute the kernel's state copy
852
+ * functions. So, the tester is advised to double-check any emitted
853
+ * kernel messages.
854
+ */
855
+ static void ptracer_inject_tiledata (pid_t target )
856
+ {
857
+ struct xsave_buffer * xbuf ;
858
+ struct iovec iov ;
859
+
860
+ xbuf = alloc_xbuf ();
861
+ if (!xbuf )
862
+ fatal_error ("unable to allocate XSAVE buffer" );
863
+
864
+ printf ("\tRead the init'ed tiledata via ptrace().\n" );
865
+
866
+ iov .iov_base = xbuf ;
867
+ iov .iov_len = xbuf_size ;
868
+
869
+ memset (stashed_xsave , 0 , xbuf_size );
870
+
871
+ if (ptrace (PTRACE_GETREGSET , target , (uint32_t )NT_X86_XSTATE , & iov ))
872
+ fatal_error ("PTRACE_GETREGSET" );
873
+
874
+ if (!__compare_tiledata_state (stashed_xsave , xbuf ))
875
+ printf ("[OK]\tThe init'ed tiledata was read from ptracee.\n" );
876
+ else
877
+ printf ("[FAIL]\tThe init'ed tiledata was not read from ptracee.\n" );
878
+
879
+ printf ("\tInject tiledata via ptrace().\n" );
880
+
881
+ load_rand_tiledata (xbuf );
882
+
883
+ memcpy (& stashed_xsave -> bytes [xtiledata .xbuf_offset ],
884
+ & xbuf -> bytes [xtiledata .xbuf_offset ],
885
+ xtiledata .size );
886
+
887
+ if (ptrace (PTRACE_SETREGSET , target , (uint32_t )NT_X86_XSTATE , & iov ))
888
+ fatal_error ("PTRACE_SETREGSET" );
889
+
890
+ if (ptrace (PTRACE_GETREGSET , target , (uint32_t )NT_X86_XSTATE , & iov ))
891
+ fatal_error ("PTRACE_GETREGSET" );
892
+
893
+ if (!__compare_tiledata_state (stashed_xsave , xbuf ))
894
+ printf ("[OK]\tTiledata was correctly written to ptracee.\n" );
895
+ else
896
+ printf ("[FAIL]\tTiledata was not correctly written to ptracee.\n" );
897
+ }
898
+
899
+ static void test_ptrace (void )
900
+ {
901
+ pid_t child ;
902
+ int status ;
903
+
904
+ child = fork ();
905
+ if (child < 0 ) {
906
+ err (1 , "fork" );
907
+ } else if (!child ) {
908
+ if (ptrace (PTRACE_TRACEME , 0 , NULL , NULL ))
909
+ err (1 , "PTRACE_TRACEME" );
910
+
911
+ ptracee_firstuse_tiledata ();
912
+
913
+ raise (SIGTRAP );
914
+ _exit (0 );
915
+ }
916
+
917
+ do {
918
+ wait (& status );
919
+ } while (WSTOPSIG (status ) != SIGTRAP );
920
+
921
+ ptracer_inject_tiledata (child );
922
+
923
+ ptrace (PTRACE_DETACH , child , NULL , NULL );
924
+ wait (& status );
925
+ if (!WIFEXITED (status ) || WEXITSTATUS (status ))
926
+ err (1 , "ptrace test" );
927
+ }
928
+
829
929
int main (void )
830
930
{
831
931
/* Check hardware availability at first */
@@ -846,6 +946,8 @@ int main(void)
846
946
ctxtswtest_config .num_threads = 5 ;
847
947
test_context_switch ();
848
948
949
+ test_ptrace ();
950
+
849
951
clearhandler (SIGILL );
850
952
free_stashed_xsave ();
851
953
0 commit comments