2015-12-17 20:56:48 +03:00
/*
* Copyright ( c ) 2014 - 2015 Dmitry V . Levin < ldv @ altlinux . org >
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
* 1. Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* 2. Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ` ` AS IS ' ' AND ANY EXPRESS OR
* IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED .
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT , INDIRECT ,
* INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT
* NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
2014-02-05 17:48:26 +04:00
# include "defs.h"
2015-02-20 00:16:45 +03:00
# include "xlat/kexec_load_flags.h"
2014-04-26 03:30:54 +04:00
# include "xlat/kexec_arch_values.h"
2015-02-20 00:16:45 +03:00
# ifndef KEXEC_ARCH_MASK
# define KEXEC_ARCH_MASK 0xffff0000
# endif
# ifndef KEXEC_SEGMENT_MAX
# define KEXEC_SEGMENT_MAX 16
# endif
2014-02-05 17:48:26 +04:00
2016-05-08 01:59:05 +03:00
static bool
print_seg ( struct tcb * tcp , void * elem_buf , size_t elem_size , void * data )
2015-07-20 04:20:44 +03:00
{
2016-05-08 01:59:05 +03:00
const unsigned long * seg ;
unsigned long seg_buf [ 4 ] ;
if ( elem_size < sizeof ( seg_buf ) ) {
unsigned int i ;
for ( i = 0 ; i < ARRAY_SIZE ( seg_buf ) ; + + i )
seg_buf [ i ] = ( ( unsigned int * ) elem_buf ) [ i ] ;
seg = seg_buf ;
} else {
seg = elem_buf ;
}
2015-07-20 04:20:44 +03:00
tprints ( " { " ) ;
2015-09-15 05:17:32 +03:00
printaddr ( seg [ 0 ] ) ;
tprintf ( " , %lu, " , seg [ 1 ] ) ;
printaddr ( seg [ 2 ] ) ;
tprintf ( " , %lu} " , seg [ 3 ] ) ;
2016-05-08 01:59:05 +03:00
return true ;
2015-07-20 04:20:44 +03:00
}
static void
print_kexec_segments ( struct tcb * tcp , const unsigned long addr ,
const unsigned long len )
2014-02-05 17:48:26 +04:00
{
if ( len > KEXEC_SEGMENT_MAX ) {
2015-07-20 04:20:44 +03:00
printaddr ( addr ) ;
2014-02-05 17:48:26 +04:00
return ;
}
2016-05-08 01:59:05 +03:00
unsigned long seg [ 4 ] ;
const size_t sizeof_seg = ARRAY_SIZE ( seg ) * current_wordsize ;
2015-07-20 04:20:44 +03:00
2016-05-08 01:59:05 +03:00
print_array ( tcp , addr , len , seg , sizeof_seg ,
umoven_or_printaddr , print_seg , 0 ) ;
2014-02-05 17:48:26 +04:00
}
2015-04-07 04:36:50 +03:00
SYS_FUNC ( kexec_load )
2014-02-05 17:48:26 +04:00
{
unsigned long n ;
/* entry, nr_segments */
2015-07-20 04:20:44 +03:00
printaddr ( tcp - > u_arg [ 0 ] ) ;
tprintf ( " , %lu, " , tcp - > u_arg [ 1 ] ) ;
2014-02-05 17:48:26 +04:00
/* segments */
print_kexec_segments ( tcp , tcp - > u_arg [ 2 ] , tcp - > u_arg [ 1 ] ) ;
tprints ( " , " ) ;
/* flags */
n = tcp - > u_arg [ 3 ] ;
printxval ( kexec_arch_values , n & KEXEC_ARCH_MASK , " KEXEC_ARCH_??? " ) ;
n & = ~ KEXEC_ARCH_MASK ;
if ( n ) {
tprints ( " | " ) ;
2015-02-20 00:16:45 +03:00
printflags ( kexec_load_flags , n , " KEXEC_??? " ) ;
2014-02-05 17:48:26 +04:00
}
2015-07-20 04:20:44 +03:00
return RVAL_DECODED ;
2014-02-05 17:48:26 +04:00
}
2015-11-22 21:51:05 +03:00
# include "xlat/kexec_file_load_flags.h"
SYS_FUNC ( kexec_file_load )
{
/* kernel_fd */
printfd ( tcp , tcp - > u_arg [ 0 ] ) ;
tprints ( " , " ) ;
/* initrd_fd */
printfd ( tcp , tcp - > u_arg [ 1 ] ) ;
tprints ( " , " ) ;
/* cmdline_len */
tprintf ( " %lu, " , tcp - > u_arg [ 2 ] ) ;
/* cmdline */
printstr ( tcp , tcp - > u_arg [ 3 ] , tcp - > u_arg [ 2 ] ) ;
tprints ( " , " ) ;
/* flags */
printflags ( kexec_file_load_flags , tcp - > u_arg [ 4 ] , " KEXEC_FILE_??? " ) ;
return RVAL_DECODED ;
}