linux-headers/arch/e2k/include/asm/protected_syscalls.h

248 lines
6.4 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
/*
* arch/e2k/include/asm/protected_syscalls.h, v 1.0 25/12/2019.
*
* Copyright (C) 2019 MCST
*/
/****************** PROTECTED SYSTEM CALL DEBUG DEFINES *******************/
#ifndef _E2K_PROTECTED_SYSCALLS_H_
#define _E2K_PROTECTED_SYSCALLS_H_
#ifdef CONFIG_PROTECTED_MODE
#include <asm/mmu.h>
#include <asm/e2k_ptypes.h>
#undef DYNAMIC_DEBUG_SYSCALLP_ENABLED
#define DYNAMIC_DEBUG_SYSCALLP_ENABLED 1 /* Dynamic prot. syscalls control */
#if (!DYNAMIC_DEBUG_SYSCALLP_ENABLED)
/* Static debug defines (old style): */
#undef DEBUG_SYSCALLP
#define DEBUG_SYSCALLP 0 /* System Calls trace */
#undef DEBUG_SYSCALLP_CHECK
#define DEBUG_SYSCALLP_CHECK 1 /* Protected System Call args checks/warnings */
#define PM_SYSCALL_WARN_ONLY 1
#if DEBUG_SYSCALLP
#define DbgSCP printk
#else
#define DbgSCP(...)
#endif /* DEBUG_SYSCALLP */
#if DEBUG_SYSCALLP_CHECK
#define DbgSCP_ERR(fmt, ...) pr_err(fmt, ##__VA_ARGS__)
#define DbgSCP_WARN(fmt, ...) pr_warn(fmt, ##__VA_ARGS__)
#define DbgSCP_ALERT(fmt, ...) pr_alert(fmt, ##__VA_ARGS__)
#else
#define DbgSC_ERR(...)
#define DbgSC_WARN(...)
#define DbgSC_ALERT(...)
#endif /* DEBUG_SYSCALLP_CHECK */
#else /* DYNAMIC_DEBUG_SYSCALLP_ENABLED */
/* Dynamic debug defines (new style):
* When enabled, environment variables control syscall
* debug/diagnostic output.
* To enable particular control: export <env.var.>=1
* To disnable particular control: export <env.var.>=0
*
* The options are as follows:
*
* PM_SC_DBG_MODE_DEBUG - Output basic debug info on system calls to journal;
*
* PM_SC_DBG_MODE_COMPLEX_WRAPPERS - Output debug info on protected
* complex syscall wrappers to journal;
* PM_SC_DBG_MODE_CHECK - Report issue to journal if syscall arg
* mismatch expected format;
* PM_SC_DBG_MODE_WARN_ONLY - If error in arg format detected,
* don't block syscall but run it anyway;
* PM_SC_DBG_MODE_CONV_STRUCT - Output to journal debug info on converting
* structures in syscall args;
* PM_SC_DBG_MODE_SIGNALS - Output to system journal debug info related
* to signal manipulation;
* PM_SC_DBG_MODE_NO_ERR_MESSAGES - Blocks diagnostic messages to journal
* (may be useful when running latency-sensitive tests/applications);
*
* PM_MM_CHECK_4_DANGLING_POINTERS - Enable check for dangling descriptors
* allocated with 'malloc' (libc specific);
*
* PM_SC_DBG_MODE_ALL - Enable all debug/diagnostic output to system journal;
*
* PM_SC_DBG_MODE_DISABLED - Disable debug/diagnostic output to system journal.
*/
#include "asm/syscalls.h"
#define DbgSCP(fmt, ...) \
do { \
if (arch_init_pm_sc_debug_mode(PM_SC_DBG_MODE_DEBUG)) \
pr_info("%s: " fmt, __func__, ##__VA_ARGS__); \
} while (0)
#define DbgSCP_ERR(fmt, ...) \
do { \
if (arch_init_pm_sc_debug_mode(PM_SC_DBG_MODE_CHECK) \
&& !(current->mm->context.pm_sc_debug_mode \
& PM_SC_DBG_MODE_NO_ERR_MESSAGES)) \
pr_err("%s: " fmt, __func__, ##__VA_ARGS__); \
} while (0)
#define DbgSCP_ALERT(fmt, ...) \
do { \
if (arch_init_pm_sc_debug_mode(PM_SC_DBG_MODE_CHECK) \
&& !(current->mm->context.pm_sc_debug_mode \
& PM_SC_DBG_MODE_NO_ERR_MESSAGES)) \
pr_alert("%s: " fmt, __func__, ##__VA_ARGS__); \
} while (0)
#define DbgSCP_WARN(fmt, ...) \
do { \
if (arch_init_pm_sc_debug_mode(PM_SC_DBG_MODE_CHECK) \
&& !(current->mm->context.pm_sc_debug_mode \
& PM_SC_DBG_MODE_NO_ERR_MESSAGES)) \
pr_warn("%s: " fmt, __func__, ##__VA_ARGS__); \
} while (0)
#define PM_SYSCALL_WARN_ONLY \
(arch_init_pm_sc_debug_mode(PM_SC_DBG_MODE_WARN_ONLY))
/* Backward compatibility with syscalls */
/* NB> It may happen legacy s/w written incompatible with
* context protection principles.
* For example, tests for syscalls may be of that kind
* to intentionally pass bad arguments to syscalls to check
* if behavior is correct in that case.
* This define, being activated, eases argument check control
* when doing system calls in the protected execution mode:
* - a warning still gets reported to the journal, but
* - system call is not blocked at it is normally done.
*/
#define DEBUG_SYSCALLP_CHECK 1 /* protected syscall args checks enabled */
#endif /* DYNAMIC_DEBUG_SYSCALLP_ENABLED */
/**************************** END of DEBUG DEFINES ***********************/
static inline
long make_ap_lo(e2k_addr_t base, long size, long offset, int access)
{
return MAKE_AP_LO(base, size, offset, access);
}
static inline
long make_ap_hi(e2k_addr_t base, long size, long offset, int access)
{
return MAKE_AP_HI(base, size, offset, access);
}
static inline
int e2k_ptr_itag(long low)
{
e2k_ptr_t ptr;
AW(ptr).lo = low;
return AS(ptr).itag;
}
static inline
int e2k_ptr_rw(long low)
{
e2k_ptr_t ptr;
AW(ptr).lo = low;
return AS(ptr).rw;
}
static inline
unsigned long e2k_ptr_ptr(long low, long hiw, unsigned int min_size)
{
e2k_ptr_t ptr;
unsigned int ptr_size;
AW(ptr).lo = low;
AW(ptr).hi = hiw;
ptr_size = AS(ptr).size - AS(ptr).curptr;
if (ptr_size < min_size) {
DbgSCP_ALERT(" Pointer is too small: %d < %d\n",
ptr_size, min_size);
return 0;
} else {
return E2K_PTR_PTR(ptr, GET_SBR_HI());
}
}
static inline
unsigned long e2k_ptr_curptr(long low, long hiw)
{
e2k_ptr_t ptr;
AW(ptr).lo = low;
AW(ptr).hi = hiw;
return AS(ptr).curptr;
}
static inline
unsigned int e2k_ptr_size(long low, long hiw, unsigned int min_size)
{
e2k_ptr_hi_t hi;
unsigned int ptr_size;
AW(hi) = hiw;
ptr_size = AS(hi).size - AS(hi).curptr;
if (ptr_size < min_size) {
DbgSCP_ALERT(" Pointer is too small: %d < %d\n",
ptr_size, min_size);
return 0;
} else {
return ptr_size;
}
}
static inline int e2k_ptr_str_check(char __user *str, u64 max_size)
{
long slen;
slen = strnlen_user(str, max_size);
if (unlikely(!slen || slen > max_size))
return 1;
return 0;
}
static inline char __user *e2k_ptr_str(long low, long hiw, u64 sbr_hi)
{
char __user *str;
e2k_ptr_hi_t hi = { .word = hiw };
str = (char __user *) __E2K_PTR_PTR(low, hiw, sbr_hi);
if (!e2k_ptr_str_check(str, AS(hi).size - AS(hi).curptr))
return str;
return NULL;
}
#else /* #ifndef CONFIG_PROTECTED_MODE */
#define DbgSCP(...)
#define DbgSC_ERR(...)
#define DbgSC_WARN(...)
#define DbgSC_ALERT(...)
#endif /* CONFIG_PROTECTED_MODE */
#endif /* _E2K_PROTECTED_SYSCALLS_H_ */