cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

masklog.h (6898B)


      1/* SPDX-License-Identifier: GPL-2.0-or-later */
      2/*
      3 * Copyright (C) 2005 Oracle.  All rights reserved.
      4 */
      5
      6#ifndef O2CLUSTER_MASKLOG_H
      7#define O2CLUSTER_MASKLOG_H
      8
      9/*
     10 * For now this is a trivial wrapper around printk() that gives the critical
     11 * ability to enable sets of debugging output at run-time.  In the future this
     12 * will almost certainly be redirected to relayfs so that it can pay a
     13 * substantially lower heisenberg tax.
     14 *
     15 * Callers associate the message with a bitmask and a global bitmask is
     16 * maintained with help from /proc.  If any of the bits match the message is
     17 * output.
     18 *
     19 * We must have efficient bit tests on i386 and it seems gcc still emits crazy
     20 * code for the 64bit compare.  It emits very good code for the dual unsigned
     21 * long tests, though, completely avoiding tests that can never pass if the
     22 * caller gives a constant bitmask that fills one of the longs with all 0s.  So
     23 * the desire is to have almost all of the calls decided on by comparing just
     24 * one of the longs.  This leads to having infrequently given bits that are
     25 * frequently matched in the high bits.
     26 *
     27 * _ERROR and _NOTICE are used for messages that always go to the console and
     28 * have appropriate KERN_ prefixes.  We wrap these in our function instead of
     29 * just calling printk() so that this can eventually make its way through
     30 * relayfs along with the debugging messages.  Everything else gets KERN_DEBUG.
     31 * The inline tests and macro dance give GCC the opportunity to quite cleverly
     32 * only emit the appropriage printk() when the caller passes in a constant
     33 * mask, as is almost always the case.
     34 *
     35 * All this bitmask nonsense is managed from the files under
     36 * /sys/fs/o2cb/logmask/.  Reading the files gives a straightforward
     37 * indication of which bits are allowed (allow) or denied (off/deny).
     38 * 	ENTRY deny
     39 * 	EXIT deny
     40 * 	TCP off
     41 * 	MSG off
     42 * 	SOCKET off
     43 * 	ERROR allow
     44 * 	NOTICE allow
     45 *
     46 * Writing changes the state of a given bit and requires a strictly formatted
     47 * single write() call:
     48 *
     49 * 	write(fd, "allow", 5);
     50 *
     51 * Echoing allow/deny/off string into the logmask files can flip the bits
     52 * on or off as expected; here is the bash script for example:
     53 *
     54 * log_mask="/sys/fs/o2cb/log_mask"
     55 * for node in ENTRY EXIT TCP MSG SOCKET ERROR NOTICE; do
     56 *	echo allow >"$log_mask"/"$node"
     57 * done
     58 *
     59 * The debugfs.ocfs2 tool can also flip the bits with the -l option:
     60 *
     61 * debugfs.ocfs2 -l TCP allow
     62 */
     63
     64/* for task_struct */
     65#include <linux/sched.h>
     66
     67/* bits that are frequently given and infrequently matched in the low word */
     68/* NOTE: If you add a flag, you need to also update masklog.c! */
     69#define ML_TCP		0x0000000000000001ULL /* net cluster/tcp.c */
     70#define ML_MSG		0x0000000000000002ULL /* net network messages */
     71#define ML_SOCKET	0x0000000000000004ULL /* net socket lifetime */
     72#define ML_HEARTBEAT	0x0000000000000008ULL /* hb all heartbeat tracking */
     73#define ML_HB_BIO	0x0000000000000010ULL /* hb io tracing */
     74#define ML_DLMFS	0x0000000000000020ULL /* dlm user dlmfs */
     75#define ML_DLM		0x0000000000000040ULL /* dlm general debugging */
     76#define ML_DLM_DOMAIN	0x0000000000000080ULL /* dlm domain debugging */
     77#define ML_DLM_THREAD	0x0000000000000100ULL /* dlm domain thread */
     78#define ML_DLM_MASTER	0x0000000000000200ULL /* dlm master functions */
     79#define ML_DLM_RECOVERY	0x0000000000000400ULL /* dlm master functions */
     80#define ML_DLM_GLUE	0x0000000000000800ULL /* ocfs2 dlm glue layer */
     81#define ML_VOTE		0x0000000000001000ULL /* ocfs2 node messaging  */
     82#define ML_CONN		0x0000000000002000ULL /* net connection management */
     83#define ML_QUORUM	0x0000000000004000ULL /* net connection quorum */
     84#define ML_BASTS	0x0000000000008000ULL /* dlmglue asts and basts */
     85#define ML_CLUSTER	0x0000000000010000ULL /* cluster stack */
     86
     87/* bits that are infrequently given and frequently matched in the high word */
     88#define ML_ERROR	0x1000000000000000ULL /* sent to KERN_ERR */
     89#define ML_NOTICE	0x2000000000000000ULL /* setn to KERN_NOTICE */
     90#define ML_KTHREAD	0x4000000000000000ULL /* kernel thread activity */
     91
     92#define MLOG_INITIAL_AND_MASK (ML_ERROR|ML_NOTICE)
     93#ifndef MLOG_MASK_PREFIX
     94#define MLOG_MASK_PREFIX 0
     95#endif
     96
     97/*
     98 * When logging is disabled, force the bit test to 0 for anything other
     99 * than errors and notices, allowing gcc to remove the code completely.
    100 * When enabled, allow all masks.
    101 */
    102#if defined(CONFIG_OCFS2_DEBUG_MASKLOG)
    103#define ML_ALLOWED_BITS ~0
    104#else
    105#define ML_ALLOWED_BITS (ML_ERROR|ML_NOTICE)
    106#endif
    107
    108#define MLOG_MAX_BITS 64
    109
    110struct mlog_bits {
    111	unsigned long words[MLOG_MAX_BITS / BITS_PER_LONG];
    112};
    113
    114extern struct mlog_bits mlog_and_bits, mlog_not_bits;
    115
    116#if BITS_PER_LONG == 32
    117
    118#define __mlog_test_u64(mask, bits)			\
    119	( (u32)(mask & 0xffffffff) & bits.words[0] || 	\
    120	  ((u64)(mask) >> 32) & bits.words[1] )
    121#define __mlog_set_u64(mask, bits) do {			\
    122	bits.words[0] |= (u32)(mask & 0xffffffff);	\
    123       	bits.words[1] |= (u64)(mask) >> 32;		\
    124} while (0)
    125#define __mlog_clear_u64(mask, bits) do {		\
    126	bits.words[0] &= ~((u32)(mask & 0xffffffff));	\
    127       	bits.words[1] &= ~((u64)(mask) >> 32);		\
    128} while (0)
    129#define MLOG_BITS_RHS(mask) {				\
    130	{						\
    131		[0] = (u32)(mask & 0xffffffff),		\
    132		[1] = (u64)(mask) >> 32,		\
    133	}						\
    134}
    135
    136#else /* 32bit long above, 64bit long below */
    137
    138#define __mlog_test_u64(mask, bits)	((mask) & bits.words[0])
    139#define __mlog_set_u64(mask, bits) do {		\
    140	bits.words[0] |= (mask);		\
    141} while (0)
    142#define __mlog_clear_u64(mask, bits) do {	\
    143	bits.words[0] &= ~(mask);		\
    144} while (0)
    145#define MLOG_BITS_RHS(mask) { { (mask) } }
    146
    147#endif
    148
    149__printf(4, 5)
    150void __mlog_printk(const u64 *m, const char *func, int line,
    151		   const char *fmt, ...);
    152
    153/*
    154 * Testing before the __mlog_printk call lets the compiler eliminate the
    155 * call completely when (m & ML_ALLOWED_BITS) is 0.
    156 */
    157#define mlog(mask, fmt, ...)						\
    158do {									\
    159	u64 _m = MLOG_MASK_PREFIX | (mask);				\
    160	if (_m & ML_ALLOWED_BITS)					\
    161		__mlog_printk(&_m, __func__, __LINE__, fmt,		\
    162			      ##__VA_ARGS__);				\
    163} while (0)
    164
    165#define mlog_ratelimited(mask, fmt, ...)				\
    166do {									\
    167	static DEFINE_RATELIMIT_STATE(_rs,				\
    168				      DEFAULT_RATELIMIT_INTERVAL,	\
    169				      DEFAULT_RATELIMIT_BURST);		\
    170	if (__ratelimit(&_rs))						\
    171		mlog(mask, fmt, ##__VA_ARGS__);				\
    172} while (0)
    173
    174#define mlog_errno(st) ({						\
    175	int _st = (st);							\
    176	if (_st != -ERESTARTSYS && _st != -EINTR &&			\
    177	    _st != AOP_TRUNCATED_PAGE && _st != -ENOSPC &&		\
    178	    _st != -EDQUOT)						\
    179		mlog(ML_ERROR, "status = %lld\n", (long long)_st);	\
    180	_st;								\
    181})
    182
    183#define mlog_bug_on_msg(cond, fmt, args...) do {			\
    184	if (cond) {							\
    185		mlog(ML_ERROR, "bug expression: " #cond "\n");		\
    186		mlog(ML_ERROR, fmt, ##args);				\
    187		BUG();							\
    188	}								\
    189} while (0)
    190
    191#include <linux/kobject.h>
    192#include <linux/sysfs.h>
    193int mlog_sys_init(struct kset *o2cb_subsys);
    194void mlog_sys_shutdown(void);
    195
    196#endif /* O2CLUSTER_MASKLOG_H */