mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 05:32:00 +00:00
There is no particular theme here - mainly quick hits all over the tree.
Most notable is a set of zlib changes from Mikhail Zaslonko which enhances and fixes zlib's use of S390 hardware support: "lib/zlib: Set of s390 DFLTCC related patches for kernel zlib". -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQTTMBEPP41GrTpTJgfdBJ7gKXxAjgUCY/QC4QAKCRDdBJ7gKXxA jtKdAQCbDCBdY8H45d1fONzQW2UDqCPnOi77MpVUxGL33r+1SAEA807C7rvDEmlf yP1Ft+722fFU5jogVU8ZFh+vapv2/gI= =Q9YK -----END PGP SIGNATURE----- Merge tag 'mm-nonmm-stable-2023-02-20-15-29' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm Pull non-MM updates from Andrew Morton: "There is no particular theme here - mainly quick hits all over the tree. Most notable is a set of zlib changes from Mikhail Zaslonko which enhances and fixes zlib's use of S390 hardware support: 'lib/zlib: Set of s390 DFLTCC related patches for kernel zlib'" * tag 'mm-nonmm-stable-2023-02-20-15-29' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: (55 commits) Update CREDITS file entry for Jesper Juhl sparc: allow PM configs for sparc32 COMPILE_TEST hung_task: print message when hung_task_warnings gets down to zero. arch/Kconfig: fix indentation scripts/tags.sh: fix the Kconfig tags generation when using latest ctags nilfs2: prevent WARNING in nilfs_dat_commit_end() lib/zlib: remove redundation assignement of avail_in dfltcc_gdht() lib/Kconfig.debug: do not enable DEBUG_PREEMPT by default lib/zlib: DFLTCC always switch to software inflate for Z_PACKET_FLUSH option lib/zlib: DFLTCC support inflate with small window lib/zlib: Split deflate and inflate states for DFLTCC lib/zlib: DFLTCC not writing header bits when avail_out == 0 lib/zlib: fix DFLTCC ignoring flush modes when avail_in == 0 lib/zlib: fix DFLTCC not flushing EOBS when creating raw streams lib/zlib: implement switching between DFLTCC and software lib/zlib: adjust offset calculation for dfltcc_state nilfs2: replace WARN_ONs for invalid DAT metadata block requests scripts/spelling.txt: add "exsits" pattern and fix typo instances fs: gracefully handle ->get_block not mapping bh in __mpage_writepage cramfs: Kconfig: fix spelling & punctuation ...
This commit is contained in:
commit
d2980d8d82
6
CREDITS
6
CREDITS
@ -1852,11 +1852,11 @@ E: ajoshi@shell.unixbox.com
|
||||
D: fbdev hacking
|
||||
|
||||
N: Jesper Juhl
|
||||
E: jj@chaosbits.net
|
||||
E: jesperjuhl76@gmail.com
|
||||
D: Various fixes, cleanups and minor features all over the tree.
|
||||
D: Wrote initial version of the hdaps driver (since passed on to others).
|
||||
S: Lemnosvej 1, 3.tv
|
||||
S: 2300 Copenhagen S.
|
||||
S: Titangade 5G, 2.tv
|
||||
S: 2200 Copenhagen N.
|
||||
S: Denmark
|
||||
|
||||
N: Jozsef Kadlecsik
|
||||
|
@ -453,9 +453,10 @@ this allows system administrators to override the
|
||||
kexec_load_disabled
|
||||
===================
|
||||
|
||||
A toggle indicating if the ``kexec_load`` syscall has been disabled.
|
||||
This value defaults to 0 (false: ``kexec_load`` enabled), but can be
|
||||
set to 1 (true: ``kexec_load`` disabled).
|
||||
A toggle indicating if the syscalls ``kexec_load`` and
|
||||
``kexec_file_load`` have been disabled.
|
||||
This value defaults to 0 (false: ``kexec_*load`` enabled), but can be
|
||||
set to 1 (true: ``kexec_*load`` disabled).
|
||||
Once true, kexec can no longer be used, and the toggle cannot be set
|
||||
back to false.
|
||||
This allows a kexec image to be loaded before disabling the syscall,
|
||||
@ -463,6 +464,24 @@ allowing a system to set up (and later use) an image without it being
|
||||
altered.
|
||||
Generally used together with the `modules_disabled`_ sysctl.
|
||||
|
||||
kexec_load_limit_panic
|
||||
======================
|
||||
|
||||
This parameter specifies a limit to the number of times the syscalls
|
||||
``kexec_load`` and ``kexec_file_load`` can be called with a crash
|
||||
image. It can only be set with a more restrictive value than the
|
||||
current one.
|
||||
|
||||
== ======================================================
|
||||
-1 Unlimited calls to kexec. This is the default setting.
|
||||
N Number of calls left.
|
||||
== ======================================================
|
||||
|
||||
kexec_load_limit_reboot
|
||||
=======================
|
||||
|
||||
Similar functionality as ``kexec_load_limit_panic``, but for a normal
|
||||
image.
|
||||
|
||||
kptr_restrict
|
||||
=============
|
||||
|
@ -231,6 +231,71 @@ proc entries
|
||||
This feature is intended for systematic testing of faults in a single
|
||||
system call. See an example below.
|
||||
|
||||
|
||||
Error Injectable Functions
|
||||
--------------------------
|
||||
|
||||
This part is for the kenrel developers considering to add a function to
|
||||
ALLOW_ERROR_INJECTION() macro.
|
||||
|
||||
Requirements for the Error Injectable Functions
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Since the function-level error injection forcibly changes the code path
|
||||
and returns an error even if the input and conditions are proper, this can
|
||||
cause unexpected kernel crash if you allow error injection on the function
|
||||
which is NOT error injectable. Thus, you (and reviewers) must ensure;
|
||||
|
||||
- The function returns an error code if it fails, and the callers must check
|
||||
it correctly (need to recover from it).
|
||||
|
||||
- The function does not execute any code which can change any state before
|
||||
the first error return. The state includes global or local, or input
|
||||
variable. For example, clear output address storage (e.g. `*ret = NULL`),
|
||||
increments/decrements counter, set a flag, preempt/irq disable or get
|
||||
a lock (if those are recovered before returning error, that will be OK.)
|
||||
|
||||
The first requirement is important, and it will result in that the release
|
||||
(free objects) functions are usually harder to inject errors than allocate
|
||||
functions. If errors of such release functions are not correctly handled
|
||||
it will cause a memory leak easily (the caller will confuse that the object
|
||||
has been released or corrupted.)
|
||||
|
||||
The second one is for the caller which expects the function should always
|
||||
does something. Thus if the function error injection skips whole of the
|
||||
function, the expectation is betrayed and causes an unexpected error.
|
||||
|
||||
Type of the Error Injectable Functions
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Each error injectable functions will have the error type specified by the
|
||||
ALLOW_ERROR_INJECTION() macro. You have to choose it carefully if you add
|
||||
a new error injectable function. If the wrong error type is chosen, the
|
||||
kernel may crash because it may not be able to handle the error.
|
||||
There are 4 types of errors defined in include/asm-generic/error-injection.h
|
||||
|
||||
EI_ETYPE_NULL
|
||||
This function will return `NULL` if it fails. e.g. return an allocateed
|
||||
object address.
|
||||
|
||||
EI_ETYPE_ERRNO
|
||||
This function will return an `-errno` error code if it fails. e.g. return
|
||||
-EINVAL if the input is wrong. This will include the functions which will
|
||||
return an address which encodes `-errno` by ERR_PTR() macro.
|
||||
|
||||
EI_ETYPE_ERRNO_NULL
|
||||
This function will return an `-errno` or `NULL` if it fails. If the caller
|
||||
of this function checks the return value with IS_ERR_OR_NULL() macro, this
|
||||
type will be appropriate.
|
||||
|
||||
EI_ETYPE_TRUE
|
||||
This function will return `true` (non-zero positive value) if it fails.
|
||||
|
||||
If you specifies a wrong type, for example, EI_TYPE_ERRNO for the function
|
||||
which returns an allocated object, it may cause a problem because the returned
|
||||
value is not an object address and the caller can not access to the address.
|
||||
|
||||
|
||||
How to add new fault injection capability
|
||||
-----------------------------------------
|
||||
|
||||
|
128
arch/Kconfig
128
arch/Kconfig
@ -35,7 +35,7 @@ config HOTPLUG_SMT
|
||||
bool
|
||||
|
||||
config GENERIC_ENTRY
|
||||
bool
|
||||
bool
|
||||
|
||||
config KPROBES
|
||||
bool "Kprobes"
|
||||
@ -55,26 +55,26 @@ config JUMP_LABEL
|
||||
depends on HAVE_ARCH_JUMP_LABEL
|
||||
select OBJTOOL if HAVE_JUMP_LABEL_HACK
|
||||
help
|
||||
This option enables a transparent branch optimization that
|
||||
makes certain almost-always-true or almost-always-false branch
|
||||
conditions even cheaper to execute within the kernel.
|
||||
This option enables a transparent branch optimization that
|
||||
makes certain almost-always-true or almost-always-false branch
|
||||
conditions even cheaper to execute within the kernel.
|
||||
|
||||
Certain performance-sensitive kernel code, such as trace points,
|
||||
scheduler functionality, networking code and KVM have such
|
||||
branches and include support for this optimization technique.
|
||||
Certain performance-sensitive kernel code, such as trace points,
|
||||
scheduler functionality, networking code and KVM have such
|
||||
branches and include support for this optimization technique.
|
||||
|
||||
If it is detected that the compiler has support for "asm goto",
|
||||
the kernel will compile such branches with just a nop
|
||||
instruction. When the condition flag is toggled to true, the
|
||||
nop will be converted to a jump instruction to execute the
|
||||
conditional block of instructions.
|
||||
If it is detected that the compiler has support for "asm goto",
|
||||
the kernel will compile such branches with just a nop
|
||||
instruction. When the condition flag is toggled to true, the
|
||||
nop will be converted to a jump instruction to execute the
|
||||
conditional block of instructions.
|
||||
|
||||
This technique lowers overhead and stress on the branch prediction
|
||||
of the processor and generally makes the kernel faster. The update
|
||||
of the condition is slower, but those are always very rare.
|
||||
This technique lowers overhead and stress on the branch prediction
|
||||
of the processor and generally makes the kernel faster. The update
|
||||
of the condition is slower, but those are always very rare.
|
||||
|
||||
( On 32-bit x86, the necessary options added to the compiler
|
||||
flags may increase the size of the kernel slightly. )
|
||||
( On 32-bit x86, the necessary options added to the compiler
|
||||
flags may increase the size of the kernel slightly. )
|
||||
|
||||
config STATIC_KEYS_SELFTEST
|
||||
bool "Static key selftest"
|
||||
@ -98,9 +98,9 @@ config KPROBES_ON_FTRACE
|
||||
depends on KPROBES && HAVE_KPROBES_ON_FTRACE
|
||||
depends on DYNAMIC_FTRACE_WITH_REGS
|
||||
help
|
||||
If function tracer is enabled and the arch supports full
|
||||
passing of pt_regs to function tracing, then kprobes can
|
||||
optimize on top of function tracing.
|
||||
If function tracer is enabled and the arch supports full
|
||||
passing of pt_regs to function tracing, then kprobes can
|
||||
optimize on top of function tracing.
|
||||
|
||||
config UPROBES
|
||||
def_bool n
|
||||
@ -154,21 +154,21 @@ config HAVE_EFFICIENT_UNALIGNED_ACCESS
|
||||
config ARCH_USE_BUILTIN_BSWAP
|
||||
bool
|
||||
help
|
||||
Modern versions of GCC (since 4.4) have builtin functions
|
||||
for handling byte-swapping. Using these, instead of the old
|
||||
inline assembler that the architecture code provides in the
|
||||
__arch_bswapXX() macros, allows the compiler to see what's
|
||||
happening and offers more opportunity for optimisation. In
|
||||
particular, the compiler will be able to combine the byteswap
|
||||
with a nearby load or store and use load-and-swap or
|
||||
store-and-swap instructions if the architecture has them. It
|
||||
should almost *never* result in code which is worse than the
|
||||
hand-coded assembler in <asm/swab.h>. But just in case it
|
||||
does, the use of the builtins is optional.
|
||||
Modern versions of GCC (since 4.4) have builtin functions
|
||||
for handling byte-swapping. Using these, instead of the old
|
||||
inline assembler that the architecture code provides in the
|
||||
__arch_bswapXX() macros, allows the compiler to see what's
|
||||
happening and offers more opportunity for optimisation. In
|
||||
particular, the compiler will be able to combine the byteswap
|
||||
with a nearby load or store and use load-and-swap or
|
||||
store-and-swap instructions if the architecture has them. It
|
||||
should almost *never* result in code which is worse than the
|
||||
hand-coded assembler in <asm/swab.h>. But just in case it
|
||||
does, the use of the builtins is optional.
|
||||
|
||||
Any architecture with load-and-swap or store-and-swap
|
||||
instructions should set this. And it shouldn't hurt to set it
|
||||
on architectures that don't have such instructions.
|
||||
Any architecture with load-and-swap or store-and-swap
|
||||
instructions should set this. And it shouldn't hurt to set it
|
||||
on architectures that don't have such instructions.
|
||||
|
||||
config KRETPROBES
|
||||
def_bool y
|
||||
@ -720,13 +720,13 @@ config LTO_CLANG_FULL
|
||||
depends on !COMPILE_TEST
|
||||
select LTO_CLANG
|
||||
help
|
||||
This option enables Clang's full Link Time Optimization (LTO), which
|
||||
allows the compiler to optimize the kernel globally. If you enable
|
||||
this option, the compiler generates LLVM bitcode instead of ELF
|
||||
object files, and the actual compilation from bitcode happens at
|
||||
the LTO link step, which may take several minutes depending on the
|
||||
kernel configuration. More information can be found from LLVM's
|
||||
documentation:
|
||||
This option enables Clang's full Link Time Optimization (LTO), which
|
||||
allows the compiler to optimize the kernel globally. If you enable
|
||||
this option, the compiler generates LLVM bitcode instead of ELF
|
||||
object files, and the actual compilation from bitcode happens at
|
||||
the LTO link step, which may take several minutes depending on the
|
||||
kernel configuration. More information can be found from LLVM's
|
||||
documentation:
|
||||
|
||||
https://llvm.org/docs/LinkTimeOptimization.html
|
||||
|
||||
@ -1330,9 +1330,9 @@ config ARCH_HAS_CC_PLATFORM
|
||||
bool
|
||||
|
||||
config HAVE_SPARSE_SYSCALL_NR
|
||||
bool
|
||||
help
|
||||
An architecture should select this if its syscall numbering is sparse
|
||||
bool
|
||||
help
|
||||
An architecture should select this if its syscall numbering is sparse
|
||||
to save space. For example, MIPS architecture has a syscall array with
|
||||
entries at 4000, 5000 and 6000 locations. This option turns on syscall
|
||||
related optimizations for a given architecture.
|
||||
@ -1356,35 +1356,35 @@ config HAVE_PREEMPT_DYNAMIC_CALL
|
||||
depends on HAVE_STATIC_CALL
|
||||
select HAVE_PREEMPT_DYNAMIC
|
||||
help
|
||||
An architecture should select this if it can handle the preemption
|
||||
model being selected at boot time using static calls.
|
||||
An architecture should select this if it can handle the preemption
|
||||
model being selected at boot time using static calls.
|
||||
|
||||
Where an architecture selects HAVE_STATIC_CALL_INLINE, any call to a
|
||||
preemption function will be patched directly.
|
||||
Where an architecture selects HAVE_STATIC_CALL_INLINE, any call to a
|
||||
preemption function will be patched directly.
|
||||
|
||||
Where an architecture does not select HAVE_STATIC_CALL_INLINE, any
|
||||
call to a preemption function will go through a trampoline, and the
|
||||
trampoline will be patched.
|
||||
Where an architecture does not select HAVE_STATIC_CALL_INLINE, any
|
||||
call to a preemption function will go through a trampoline, and the
|
||||
trampoline will be patched.
|
||||
|
||||
It is strongly advised to support inline static call to avoid any
|
||||
overhead.
|
||||
It is strongly advised to support inline static call to avoid any
|
||||
overhead.
|
||||
|
||||
config HAVE_PREEMPT_DYNAMIC_KEY
|
||||
bool
|
||||
depends on HAVE_ARCH_JUMP_LABEL
|
||||
select HAVE_PREEMPT_DYNAMIC
|
||||
help
|
||||
An architecture should select this if it can handle the preemption
|
||||
model being selected at boot time using static keys.
|
||||
An architecture should select this if it can handle the preemption
|
||||
model being selected at boot time using static keys.
|
||||
|
||||
Each preemption function will be given an early return based on a
|
||||
static key. This should have slightly lower overhead than non-inline
|
||||
static calls, as this effectively inlines each trampoline into the
|
||||
start of its callee. This may avoid redundant work, and may
|
||||
integrate better with CFI schemes.
|
||||
Each preemption function will be given an early return based on a
|
||||
static key. This should have slightly lower overhead than non-inline
|
||||
static calls, as this effectively inlines each trampoline into the
|
||||
start of its callee. This may avoid redundant work, and may
|
||||
integrate better with CFI schemes.
|
||||
|
||||
This will have greater overhead than using inline static calls as
|
||||
the call to the preemption function cannot be entirely elided.
|
||||
This will have greater overhead than using inline static calls as
|
||||
the call to the preemption function cannot be entirely elided.
|
||||
|
||||
config ARCH_WANT_LD_ORPHAN_WARN
|
||||
bool
|
||||
@ -1407,8 +1407,8 @@ config ARCH_SUPPORTS_PAGE_TABLE_CHECK
|
||||
config ARCH_SPLIT_ARG64
|
||||
bool
|
||||
help
|
||||
If a 32-bit architecture requires 64-bit arguments to be split into
|
||||
pairs of 32-bit arguments, select this option.
|
||||
If a 32-bit architecture requires 64-bit arguments to be split into
|
||||
pairs of 32-bit arguments, select this option.
|
||||
|
||||
config ARCH_HAS_ELFCORE_COMPAT
|
||||
bool
|
||||
|
@ -73,7 +73,7 @@ struct halt_info {
|
||||
static void
|
||||
common_shutdown_1(void *generic_ptr)
|
||||
{
|
||||
struct halt_info *how = (struct halt_info *)generic_ptr;
|
||||
struct halt_info *how = generic_ptr;
|
||||
struct percpu_struct *cpup;
|
||||
unsigned long *pflags, flags;
|
||||
int cpuid = smp_processor_id();
|
||||
|
@ -628,7 +628,7 @@ flush_tlb_all(void)
|
||||
static void
|
||||
ipi_flush_tlb_mm(void *x)
|
||||
{
|
||||
struct mm_struct *mm = (struct mm_struct *) x;
|
||||
struct mm_struct *mm = x;
|
||||
if (mm == current->active_mm && !asn_locked())
|
||||
flush_tlb_current(mm);
|
||||
else
|
||||
@ -670,7 +670,7 @@ struct flush_tlb_page_struct {
|
||||
static void
|
||||
ipi_flush_tlb_page(void *x)
|
||||
{
|
||||
struct flush_tlb_page_struct *data = (struct flush_tlb_page_struct *)x;
|
||||
struct flush_tlb_page_struct *data = x;
|
||||
struct mm_struct * mm = data->mm;
|
||||
|
||||
if (mm == current->active_mm && !asn_locked())
|
||||
|
@ -283,7 +283,7 @@ config ARCH_FORCE_MAX_ORDER
|
||||
This config option is actually maximum order plus one. For example,
|
||||
a value of 13 means that the largest free memory block is 2^12 pages.
|
||||
|
||||
if SPARC64
|
||||
if SPARC64 || COMPILE_TEST
|
||||
source "kernel/power/Kconfig"
|
||||
endif
|
||||
|
||||
|
@ -2615,8 +2615,8 @@ static bool emulator_io_port_access_allowed(struct x86_emulate_ctxt *ctxt,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool emulator_io_permited(struct x86_emulate_ctxt *ctxt,
|
||||
u16 port, u16 len)
|
||||
static bool emulator_io_permitted(struct x86_emulate_ctxt *ctxt,
|
||||
u16 port, u16 len)
|
||||
{
|
||||
if (ctxt->perm_ok)
|
||||
return true;
|
||||
@ -3961,7 +3961,7 @@ static int check_rdpmc(struct x86_emulate_ctxt *ctxt)
|
||||
static int check_perm_in(struct x86_emulate_ctxt *ctxt)
|
||||
{
|
||||
ctxt->dst.bytes = min(ctxt->dst.bytes, 4u);
|
||||
if (!emulator_io_permited(ctxt, ctxt->src.val, ctxt->dst.bytes))
|
||||
if (!emulator_io_permitted(ctxt, ctxt->src.val, ctxt->dst.bytes))
|
||||
return emulate_gp(ctxt, 0);
|
||||
|
||||
return X86EMUL_CONTINUE;
|
||||
@ -3970,7 +3970,7 @@ static int check_perm_in(struct x86_emulate_ctxt *ctxt)
|
||||
static int check_perm_out(struct x86_emulate_ctxt *ctxt)
|
||||
{
|
||||
ctxt->src.bytes = min(ctxt->src.bytes, 4u);
|
||||
if (!emulator_io_permited(ctxt, ctxt->dst.val, ctxt->src.bytes))
|
||||
if (!emulator_io_permitted(ctxt, ctxt->dst.val, ctxt->src.bytes))
|
||||
return emulate_gp(ctxt, 0);
|
||||
|
||||
return X86EMUL_CONTINUE;
|
||||
|
@ -446,7 +446,7 @@ iscsi_iser_conn_create(struct iscsi_cls_session *cls_session,
|
||||
* @is_leading: indicate if this is the session leading connection (MCS)
|
||||
*
|
||||
* Return: zero on success, $error if iscsi_conn_bind fails and
|
||||
* -EINVAL in case end-point doesn't exsits anymore or iser connection
|
||||
* -EINVAL in case end-point doesn't exists anymore or iser connection
|
||||
* state is not UP (teardown already started).
|
||||
*/
|
||||
static int iscsi_iser_conn_bind(struct iscsi_cls_session *cls_session,
|
||||
|
@ -38,7 +38,7 @@ config CRAMFS_MTD
|
||||
default y if !CRAMFS_BLOCKDEV
|
||||
help
|
||||
This option allows the CramFs driver to load data directly from
|
||||
a linear adressed memory range (usually non volatile memory
|
||||
a linear addressed memory range (usually non-volatile memory
|
||||
like flash) instead of going through the block device layer.
|
||||
This saves some memory since no intermediate buffering is
|
||||
necessary.
|
||||
|
@ -786,11 +786,10 @@ static void ext4_update_bh_state(struct buffer_head *bh, unsigned long flags)
|
||||
* once we get rid of using bh as a container for mapping information
|
||||
* to pass to / from get_block functions, this can go away.
|
||||
*/
|
||||
old_state = READ_ONCE(bh->b_state);
|
||||
do {
|
||||
old_state = READ_ONCE(bh->b_state);
|
||||
new_state = (old_state & ~EXT4_MAP_FLAGS) | flags;
|
||||
} while (unlikely(
|
||||
cmpxchg(&bh->b_state, old_state, new_state) != old_state));
|
||||
} while (unlikely(!try_cmpxchg(&bh->b_state, &old_state, new_state)));
|
||||
}
|
||||
|
||||
static int _ext4_get_block(struct inode *inode, sector_t iblock,
|
||||
|
@ -200,7 +200,7 @@ static const struct dentry_operations vfat_dentry_ops = {
|
||||
|
||||
/* Characters that are undesirable in an MS-DOS file name */
|
||||
|
||||
static inline wchar_t vfat_bad_char(wchar_t w)
|
||||
static inline bool vfat_bad_char(wchar_t w)
|
||||
{
|
||||
return (w < 0x0020)
|
||||
|| (w == '*') || (w == '?') || (w == '<') || (w == '>')
|
||||
@ -208,7 +208,7 @@ static inline wchar_t vfat_bad_char(wchar_t w)
|
||||
|| (w == '\\');
|
||||
}
|
||||
|
||||
static inline wchar_t vfat_replace_char(wchar_t w)
|
||||
static inline bool vfat_replace_char(wchar_t w)
|
||||
{
|
||||
return (w == '[') || (w == ']') || (w == ';') || (w == ',')
|
||||
|| (w == '+') || (w == '=');
|
||||
|
@ -31,7 +31,7 @@ vxfs_put_page(struct page *pp)
|
||||
|
||||
/**
|
||||
* vxfs_get_page - read a page into memory.
|
||||
* @ip: inode to read from
|
||||
* @mapping: mapping to read from
|
||||
* @n: page number
|
||||
*
|
||||
* Description:
|
||||
@ -81,14 +81,14 @@ vxfs_bread(struct inode *ip, int block)
|
||||
}
|
||||
|
||||
/**
|
||||
* vxfs_get_block - locate buffer for given inode,block tuple
|
||||
* vxfs_getblk - locate buffer for given inode,block tuple
|
||||
* @ip: inode
|
||||
* @iblock: logical block
|
||||
* @bp: buffer skeleton
|
||||
* @create: %TRUE if blocks may be newly allocated.
|
||||
*
|
||||
* Description:
|
||||
* The vxfs_get_block function fills @bp with the right physical
|
||||
* The vxfs_getblk function fills @bp with the right physical
|
||||
* block and device number to perform a lowlevel read/write on
|
||||
* it.
|
||||
*
|
||||
|
@ -165,7 +165,7 @@ static int vxfs_try_sb_magic(struct super_block *sbp, int silent,
|
||||
}
|
||||
|
||||
/**
|
||||
* vxfs_read_super - read superblock into memory and initialize filesystem
|
||||
* vxfs_fill_super - read superblock into memory and initialize filesystem
|
||||
* @sbp: VFS superblock (to fill)
|
||||
* @dp: fs private mount data
|
||||
* @silent: do not complain loudly when sth is wrong
|
||||
|
@ -274,6 +274,7 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid)
|
||||
tree->node_hash[hash] = node;
|
||||
tree->node_hash_cnt++;
|
||||
} else {
|
||||
hfs_bnode_get(node2);
|
||||
spin_unlock(&tree->hash_lock);
|
||||
kfree(node);
|
||||
wait_event(node2->lock_wq, !test_bit(HFS_BNODE_NEW, &node2->flags));
|
||||
|
@ -486,7 +486,7 @@ void hfs_file_truncate(struct inode *inode)
|
||||
inode->i_size);
|
||||
if (inode->i_size > HFS_I(inode)->phys_size) {
|
||||
struct address_space *mapping = inode->i_mapping;
|
||||
void *fsdata;
|
||||
void *fsdata = NULL;
|
||||
struct page *page;
|
||||
|
||||
/* XXX: Can use generic_cont_expand? */
|
||||
|
@ -554,7 +554,7 @@ void hfsplus_file_truncate(struct inode *inode)
|
||||
if (inode->i_size > hip->phys_size) {
|
||||
struct address_space *mapping = inode->i_mapping;
|
||||
struct page *page;
|
||||
void *fsdata;
|
||||
void *fsdata = NULL;
|
||||
loff_t size = inode->i_size;
|
||||
|
||||
res = hfsplus_write_begin(NULL, mapping, size, 0,
|
||||
|
@ -257,7 +257,7 @@ end_attr_file_creation:
|
||||
int __hfsplus_setxattr(struct inode *inode, const char *name,
|
||||
const void *value, size_t size, int flags)
|
||||
{
|
||||
int err = 0;
|
||||
int err;
|
||||
struct hfs_find_data cat_fd;
|
||||
hfsplus_cat_entry entry;
|
||||
u16 cat_entry_flags, cat_entry_type;
|
||||
@ -494,7 +494,7 @@ ssize_t __hfsplus_getxattr(struct inode *inode, const char *name,
|
||||
__be32 xattr_record_type;
|
||||
u32 record_type;
|
||||
u16 record_length = 0;
|
||||
ssize_t res = 0;
|
||||
ssize_t res;
|
||||
|
||||
if ((!S_ISREG(inode->i_mode) &&
|
||||
!S_ISDIR(inode->i_mode)) ||
|
||||
@ -606,7 +606,7 @@ static inline int can_list(const char *xattr_name)
|
||||
static ssize_t hfsplus_listxattr_finder_info(struct dentry *dentry,
|
||||
char *buffer, size_t size)
|
||||
{
|
||||
ssize_t res = 0;
|
||||
ssize_t res;
|
||||
struct inode *inode = d_inode(dentry);
|
||||
struct hfs_find_data fd;
|
||||
u16 entry_type;
|
||||
@ -674,10 +674,9 @@ end_listxattr_finder_info:
|
||||
ssize_t hfsplus_listxattr(struct dentry *dentry, char *buffer, size_t size)
|
||||
{
|
||||
ssize_t err;
|
||||
ssize_t res = 0;
|
||||
ssize_t res;
|
||||
struct inode *inode = d_inode(dentry);
|
||||
struct hfs_find_data fd;
|
||||
u16 key_len = 0;
|
||||
struct hfsplus_attr_key attr_key;
|
||||
char *strbuf;
|
||||
int xattr_name_len;
|
||||
@ -719,7 +718,8 @@ ssize_t hfsplus_listxattr(struct dentry *dentry, char *buffer, size_t size)
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
key_len = hfs_bnode_read_u16(fd.bnode, fd.keyoffset);
|
||||
u16 key_len = hfs_bnode_read_u16(fd.bnode, fd.keyoffset);
|
||||
|
||||
if (key_len == 0 || key_len > fd.tree->max_key_len) {
|
||||
pr_err("invalid xattr key length: %d\n", key_len);
|
||||
res = -EIO;
|
||||
@ -766,12 +766,12 @@ out:
|
||||
|
||||
static int hfsplus_removexattr(struct inode *inode, const char *name)
|
||||
{
|
||||
int err = 0;
|
||||
int err;
|
||||
struct hfs_find_data cat_fd;
|
||||
u16 flags;
|
||||
u16 cat_entry_type;
|
||||
int is_xattr_acl_deleted = 0;
|
||||
int is_all_xattrs_deleted = 0;
|
||||
int is_xattr_acl_deleted;
|
||||
int is_all_xattrs_deleted;
|
||||
|
||||
if (!HFSPLUS_SB(inode->i_sb)->attr_tree)
|
||||
return -EOPNOTSUPP;
|
||||
|
@ -40,8 +40,21 @@ static inline struct nilfs_dat_info *NILFS_DAT_I(struct inode *dat)
|
||||
static int nilfs_dat_prepare_entry(struct inode *dat,
|
||||
struct nilfs_palloc_req *req, int create)
|
||||
{
|
||||
return nilfs_palloc_get_entry_block(dat, req->pr_entry_nr,
|
||||
create, &req->pr_entry_bh);
|
||||
int ret;
|
||||
|
||||
ret = nilfs_palloc_get_entry_block(dat, req->pr_entry_nr,
|
||||
create, &req->pr_entry_bh);
|
||||
if (unlikely(ret == -ENOENT)) {
|
||||
nilfs_err(dat->i_sb,
|
||||
"DAT doesn't have a block to manage vblocknr = %llu",
|
||||
(unsigned long long)req->pr_entry_nr);
|
||||
/*
|
||||
* Return internal code -EINVAL to notify bmap layer of
|
||||
* metadata corruption.
|
||||
*/
|
||||
ret = -EINVAL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void nilfs_dat_commit_entry(struct inode *dat,
|
||||
@ -123,11 +136,7 @@ static void nilfs_dat_commit_free(struct inode *dat,
|
||||
|
||||
int nilfs_dat_prepare_start(struct inode *dat, struct nilfs_palloc_req *req)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = nilfs_dat_prepare_entry(dat, req, 0);
|
||||
WARN_ON(ret == -ENOENT);
|
||||
return ret;
|
||||
return nilfs_dat_prepare_entry(dat, req, 0);
|
||||
}
|
||||
|
||||
void nilfs_dat_commit_start(struct inode *dat, struct nilfs_palloc_req *req,
|
||||
@ -149,19 +158,19 @@ void nilfs_dat_commit_start(struct inode *dat, struct nilfs_palloc_req *req,
|
||||
int nilfs_dat_prepare_end(struct inode *dat, struct nilfs_palloc_req *req)
|
||||
{
|
||||
struct nilfs_dat_entry *entry;
|
||||
__u64 start;
|
||||
sector_t blocknr;
|
||||
void *kaddr;
|
||||
int ret;
|
||||
|
||||
ret = nilfs_dat_prepare_entry(dat, req, 0);
|
||||
if (ret < 0) {
|
||||
WARN_ON(ret == -ENOENT);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
kaddr = kmap_atomic(req->pr_entry_bh->b_page);
|
||||
entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr,
|
||||
req->pr_entry_bh, kaddr);
|
||||
start = le64_to_cpu(entry->de_start);
|
||||
blocknr = le64_to_cpu(entry->de_blocknr);
|
||||
kunmap_atomic(kaddr);
|
||||
|
||||
@ -172,6 +181,15 @@ int nilfs_dat_prepare_end(struct inode *dat, struct nilfs_palloc_req *req)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (unlikely(start > nilfs_mdt_cno(dat))) {
|
||||
nilfs_err(dat->i_sb,
|
||||
"vblocknr = %llu has abnormal lifetime: start cno (= %llu) > current cno (= %llu)",
|
||||
(unsigned long long)req->pr_entry_nr,
|
||||
(unsigned long long)start,
|
||||
(unsigned long long)nilfs_mdt_cno(dat));
|
||||
nilfs_dat_abort_entry(dat, req);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/**
|
||||
/*
|
||||
* aops.c - NTFS kernel address space operations and page cache handling.
|
||||
*
|
||||
* Copyright (c) 2001-2014 Anton Altaparmakov and Tuxera Inc.
|
||||
@ -1646,7 +1646,7 @@ hole:
|
||||
return block;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* ntfs_normal_aops - address space operations for normal inodes and attributes
|
||||
*
|
||||
* Note these are not used for compressed or mst protected inodes and
|
||||
@ -1664,7 +1664,7 @@ const struct address_space_operations ntfs_normal_aops = {
|
||||
.error_remove_page = generic_error_remove_page,
|
||||
};
|
||||
|
||||
/**
|
||||
/*
|
||||
* ntfs_compressed_aops - address space operations for compressed inodes
|
||||
*/
|
||||
const struct address_space_operations ntfs_compressed_aops = {
|
||||
@ -1678,9 +1678,9 @@ const struct address_space_operations ntfs_compressed_aops = {
|
||||
.error_remove_page = generic_error_remove_page,
|
||||
};
|
||||
|
||||
/**
|
||||
/*
|
||||
* ntfs_mst_aops - general address space operations for mst protecteed inodes
|
||||
* and attributes
|
||||
* and attributes
|
||||
*/
|
||||
const struct address_space_operations ntfs_mst_aops = {
|
||||
.read_folio = ntfs_read_folio, /* Fill page with data. */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/**
|
||||
/*
|
||||
* aops.h - Defines for NTFS kernel address space operations and page cache
|
||||
* handling. Part of the Linux-NTFS project.
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/**
|
||||
/*
|
||||
* compress.c - NTFS kernel compressed attributes handling.
|
||||
* Part of the Linux-NTFS project.
|
||||
*
|
||||
@ -41,12 +41,12 @@ typedef enum {
|
||||
NTFS_MAX_CB_SIZE = 64 * 1024,
|
||||
} ntfs_compression_constants;
|
||||
|
||||
/**
|
||||
/*
|
||||
* ntfs_compression_buffer - one buffer for the decompression engine
|
||||
*/
|
||||
static u8 *ntfs_compression_buffer;
|
||||
|
||||
/**
|
||||
/*
|
||||
* ntfs_cb_lock - spinlock which protects ntfs_compression_buffer
|
||||
*/
|
||||
static DEFINE_SPINLOCK(ntfs_cb_lock);
|
||||
|
@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/**
|
||||
/*
|
||||
* dir.c - NTFS kernel directory operations. Part of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2001-2007 Anton Altaparmakov
|
||||
@ -17,7 +17,7 @@
|
||||
#include "debug.h"
|
||||
#include "ntfs.h"
|
||||
|
||||
/**
|
||||
/*
|
||||
* The little endian Unicode string $I30 as a global constant.
|
||||
*/
|
||||
ntfschar I30[5] = { cpu_to_le16('$'), cpu_to_le16('I'),
|
||||
|
@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/**
|
||||
/*
|
||||
* inode.c - NTFS kernel inode handling.
|
||||
*
|
||||
* Copyright (c) 2001-2014 Anton Altaparmakov and Tuxera Inc.
|
||||
@ -2935,7 +2935,7 @@ out:
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_write_inode - write out a dirty inode
|
||||
* __ntfs_write_inode - write out a dirty inode
|
||||
* @vi: inode to write out
|
||||
* @sync: if true, write out synchronously
|
||||
*
|
||||
@ -3033,7 +3033,7 @@ int __ntfs_write_inode(struct inode *vi, int sync)
|
||||
* might not need to be written out.
|
||||
* NOTE: It is not a problem when the inode for $MFT itself is being
|
||||
* written out as mark_ntfs_record_dirty() will only set I_DIRTY_PAGES
|
||||
* on the $MFT inode and hence ntfs_write_inode() will not be
|
||||
* on the $MFT inode and hence __ntfs_write_inode() will not be
|
||||
* re-invoked because of it which in turn is ok since the dirtied mft
|
||||
* record will be cleaned and written out to disk below, i.e. before
|
||||
* this function returns.
|
||||
|
@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/**
|
||||
/*
|
||||
* mft.c - NTFS kernel mft record operations. Part of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2001-2012 Anton Altaparmakov and Tuxera Inc.
|
||||
|
@ -259,7 +259,7 @@ err_out:
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Inode operations for directories.
|
||||
*/
|
||||
const struct inode_operations ntfs_dir_inode_ops = {
|
||||
@ -364,7 +364,7 @@ static struct dentry *ntfs_fh_to_parent(struct super_block *sb, struct fid *fid,
|
||||
ntfs_nfs_get_inode);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Export operations allowing NFS exporting of mounted NTFS partitions.
|
||||
*
|
||||
* We use the default ->encode_fh() for now. Note that they
|
||||
|
@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/**
|
||||
/*
|
||||
* runlist.c - NTFS runlist handling code. Part of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2001-2007 Anton Altaparmakov
|
||||
|
@ -58,9 +58,17 @@ const option_t on_errors_arr[] = {
|
||||
};
|
||||
|
||||
/**
|
||||
* simple_getbool -
|
||||
* simple_getbool - convert input string to a boolean value
|
||||
* @s: input string to convert
|
||||
* @setval: where to store the output boolean value
|
||||
*
|
||||
* Copied from old ntfs driver (which copied from vfat driver).
|
||||
*
|
||||
* "1", "yes", "true", or an empty string are converted to %true.
|
||||
* "0", "no", and "false" are converted to %false.
|
||||
*
|
||||
* Return: %1 if the string is converted or was empty and *setval contains it;
|
||||
* %0 if the string was not valid.
|
||||
*/
|
||||
static int simple_getbool(char *s, bool *setval)
|
||||
{
|
||||
@ -2657,7 +2665,7 @@ static int ntfs_write_inode(struct inode *vi, struct writeback_control *wbc)
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
/*
|
||||
* The complete super operations.
|
||||
*/
|
||||
static const struct super_operations ntfs_sops = {
|
||||
|
@ -17,6 +17,7 @@ static int __init proc_cmdline_init(void)
|
||||
struct proc_dir_entry *pde;
|
||||
|
||||
pde = proc_create_single("cmdline", 0, NULL, cmdline_proc_show);
|
||||
pde_make_permanent(pde);
|
||||
pde->size = saved_command_line_len + 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
|
||||
enum {
|
||||
EI_ETYPE_NONE, /* Dummy value for undefined case */
|
||||
EI_ETYPE_NULL, /* Return NULL if failure */
|
||||
EI_ETYPE_ERRNO, /* Return -ERRNO if failure */
|
||||
EI_ETYPE_ERRNO_NULL, /* Return -ERRNO or NULL if failure */
|
||||
@ -20,8 +19,10 @@ struct pt_regs;
|
||||
|
||||
#ifdef CONFIG_FUNCTION_ERROR_INJECTION
|
||||
/*
|
||||
* Whitelist generating macro. Specify functions which can be
|
||||
* error-injectable using this macro.
|
||||
* Whitelist generating macro. Specify functions which can be error-injectable
|
||||
* using this macro. If you unsure what is required for the error-injectable
|
||||
* functions, please read Documentation/fault-injection/fault-injection.rst
|
||||
* 'Error Injectable Functions' section.
|
||||
*/
|
||||
#define ALLOW_ERROR_INJECTION(fname, _etype) \
|
||||
static struct error_injection_entry __used \
|
||||
|
@ -3,6 +3,7 @@
|
||||
#define _LINUX_ERROR_INJECTION_H
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/errno.h>
|
||||
#include <asm-generic/error-injection.h>
|
||||
|
||||
#ifdef CONFIG_FUNCTION_ERROR_INJECTION
|
||||
@ -19,7 +20,7 @@ static inline bool within_error_injection_list(unsigned long addr)
|
||||
|
||||
static inline int get_injectable_error_type(unsigned long addr)
|
||||
{
|
||||
return EI_ETYPE_NONE;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -403,7 +403,8 @@ extern int kimage_crash_copy_vmcoreinfo(struct kimage *image);
|
||||
|
||||
extern struct kimage *kexec_image;
|
||||
extern struct kimage *kexec_crash_image;
|
||||
extern int kexec_load_disabled;
|
||||
|
||||
bool kexec_load_permitted(int kexec_image_type);
|
||||
|
||||
#ifndef kexec_flush_icache_page
|
||||
#define kexec_flush_icache_page(page)
|
||||
|
@ -152,9 +152,11 @@ __percpu_counter_compare(struct percpu_counter *fbc, s64 rhs, s32 batch)
|
||||
static inline void
|
||||
percpu_counter_add(struct percpu_counter *fbc, s64 amount)
|
||||
{
|
||||
preempt_disable();
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
fbc->count += amount;
|
||||
preempt_enable();
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
/* non-SMP percpu_counter_add_local is the same with percpu_counter_add */
|
||||
|
@ -2,6 +2,8 @@
|
||||
#ifndef _LINUX_HELPER_MACROS_H_
|
||||
#define _LINUX_HELPER_MACROS_H_
|
||||
|
||||
#include <linux/math.h>
|
||||
|
||||
#define __find_closest(x, a, as, op) \
|
||||
({ \
|
||||
typeof(as) __fc_i, __fc_as = (as) - 1; \
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/utime.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/kstrtox.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/namei.h>
|
||||
@ -571,8 +572,7 @@ __setup("keepinitrd", keepinitrd_setup);
|
||||
static bool __initdata initramfs_async = true;
|
||||
static int __init initramfs_async_setup(char *str)
|
||||
{
|
||||
strtobool(str, &initramfs_async);
|
||||
return 1;
|
||||
return kstrtobool(str, &initramfs_async) == 0;
|
||||
}
|
||||
__setup("initramfs_async=", initramfs_async_setup);
|
||||
|
||||
|
@ -142,6 +142,8 @@ static void check_hung_task(struct task_struct *t, unsigned long timeout)
|
||||
|
||||
if (sysctl_hung_task_all_cpu_backtrace)
|
||||
hung_task_show_all_bt = true;
|
||||
if (!sysctl_hung_task_warnings)
|
||||
pr_info("Future hung task reports are suppressed, see sysctl kernel.hung_task_warnings\n");
|
||||
}
|
||||
|
||||
touch_nmi_watchdog();
|
||||
|
@ -190,10 +190,12 @@ out_unlock:
|
||||
static inline int kexec_load_check(unsigned long nr_segments,
|
||||
unsigned long flags)
|
||||
{
|
||||
int image_type = (flags & KEXEC_ON_CRASH) ?
|
||||
KEXEC_TYPE_CRASH : KEXEC_TYPE_DEFAULT;
|
||||
int result;
|
||||
|
||||
/* We only trust the superuser with rebooting the system. */
|
||||
if (!capable(CAP_SYS_BOOT) || kexec_load_disabled)
|
||||
if (!kexec_load_permitted(image_type))
|
||||
return -EPERM;
|
||||
|
||||
/* Permit LSMs and IMA to fail the kexec */
|
||||
|
@ -921,10 +921,64 @@ int kimage_load_segment(struct kimage *image,
|
||||
return result;
|
||||
}
|
||||
|
||||
struct kexec_load_limit {
|
||||
/* Mutex protects the limit count. */
|
||||
struct mutex mutex;
|
||||
int limit;
|
||||
};
|
||||
|
||||
static struct kexec_load_limit load_limit_reboot = {
|
||||
.mutex = __MUTEX_INITIALIZER(load_limit_reboot.mutex),
|
||||
.limit = -1,
|
||||
};
|
||||
|
||||
static struct kexec_load_limit load_limit_panic = {
|
||||
.mutex = __MUTEX_INITIALIZER(load_limit_panic.mutex),
|
||||
.limit = -1,
|
||||
};
|
||||
|
||||
struct kimage *kexec_image;
|
||||
struct kimage *kexec_crash_image;
|
||||
int kexec_load_disabled;
|
||||
static int kexec_load_disabled;
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
static int kexec_limit_handler(struct ctl_table *table, int write,
|
||||
void *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
struct kexec_load_limit *limit = table->data;
|
||||
int val;
|
||||
struct ctl_table tmp = {
|
||||
.data = &val,
|
||||
.maxlen = sizeof(val),
|
||||
.mode = table->mode,
|
||||
};
|
||||
int ret;
|
||||
|
||||
if (write) {
|
||||
ret = proc_dointvec(&tmp, write, buffer, lenp, ppos);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (val < 0)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&limit->mutex);
|
||||
if (limit->limit != -1 && val >= limit->limit)
|
||||
ret = -EINVAL;
|
||||
else
|
||||
limit->limit = val;
|
||||
mutex_unlock(&limit->mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
mutex_lock(&limit->mutex);
|
||||
val = limit->limit;
|
||||
mutex_unlock(&limit->mutex);
|
||||
|
||||
return proc_dointvec(&tmp, write, buffer, lenp, ppos);
|
||||
}
|
||||
|
||||
static struct ctl_table kexec_core_sysctls[] = {
|
||||
{
|
||||
.procname = "kexec_load_disabled",
|
||||
@ -936,6 +990,18 @@ static struct ctl_table kexec_core_sysctls[] = {
|
||||
.extra1 = SYSCTL_ONE,
|
||||
.extra2 = SYSCTL_ONE,
|
||||
},
|
||||
{
|
||||
.procname = "kexec_load_limit_panic",
|
||||
.data = &load_limit_panic,
|
||||
.mode = 0644,
|
||||
.proc_handler = kexec_limit_handler,
|
||||
},
|
||||
{
|
||||
.procname = "kexec_load_limit_reboot",
|
||||
.data = &load_limit_reboot,
|
||||
.mode = 0644,
|
||||
.proc_handler = kexec_limit_handler,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
@ -947,6 +1013,32 @@ static int __init kexec_core_sysctl_init(void)
|
||||
late_initcall(kexec_core_sysctl_init);
|
||||
#endif
|
||||
|
||||
bool kexec_load_permitted(int kexec_image_type)
|
||||
{
|
||||
struct kexec_load_limit *limit;
|
||||
|
||||
/*
|
||||
* Only the superuser can use the kexec syscall and if it has not
|
||||
* been disabled.
|
||||
*/
|
||||
if (!capable(CAP_SYS_BOOT) || kexec_load_disabled)
|
||||
return false;
|
||||
|
||||
/* Check limit counter and decrease it.*/
|
||||
limit = (kexec_image_type == KEXEC_TYPE_CRASH) ?
|
||||
&load_limit_panic : &load_limit_reboot;
|
||||
mutex_lock(&limit->mutex);
|
||||
if (!limit->limit) {
|
||||
mutex_unlock(&limit->mutex);
|
||||
return false;
|
||||
}
|
||||
if (limit->limit != -1)
|
||||
limit->limit--;
|
||||
mutex_unlock(&limit->mutex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* No panic_cpu check version of crash_kexec(). This function is called
|
||||
* only when panic_cpu holds the current CPU number; this is the only CPU
|
||||
|
@ -326,11 +326,13 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
|
||||
unsigned long, cmdline_len, const char __user *, cmdline_ptr,
|
||||
unsigned long, flags)
|
||||
{
|
||||
int ret = 0, i;
|
||||
int image_type = (flags & KEXEC_FILE_ON_CRASH) ?
|
||||
KEXEC_TYPE_CRASH : KEXEC_TYPE_DEFAULT;
|
||||
struct kimage **dest_image, *image;
|
||||
int ret = 0, i;
|
||||
|
||||
/* We only trust the superuser with rebooting the system. */
|
||||
if (!capable(CAP_SYS_BOOT) || kexec_load_disabled)
|
||||
if (!kexec_load_permitted(image_type))
|
||||
return -EPERM;
|
||||
|
||||
/* Make sure we have a legal set of flags */
|
||||
@ -342,11 +344,12 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
|
||||
if (!kexec_trylock())
|
||||
return -EBUSY;
|
||||
|
||||
dest_image = &kexec_image;
|
||||
if (flags & KEXEC_FILE_ON_CRASH) {
|
||||
if (image_type == KEXEC_TYPE_CRASH) {
|
||||
dest_image = &kexec_crash_image;
|
||||
if (kexec_crash_image)
|
||||
arch_kexec_unprotect_crashkres();
|
||||
} else {
|
||||
dest_image = &kexec_image;
|
||||
}
|
||||
|
||||
if (flags & KEXEC_FILE_UNLOAD)
|
||||
|
@ -1382,6 +1382,10 @@ EXPORT_SYMBOL_GPL(kthread_flush_worker);
|
||||
* Flush and destroy @worker. The simple flush is enough because the kthread
|
||||
* worker API is used only in trivial scenarios. There are no multi-step state
|
||||
* machines needed.
|
||||
*
|
||||
* Note that this function is not responsible for handling delayed work, so
|
||||
* caller should be responsible for queuing or canceling all delayed work items
|
||||
* before invoke this function.
|
||||
*/
|
||||
void kthread_destroy_worker(struct kthread_worker *worker)
|
||||
{
|
||||
@ -1393,6 +1397,7 @@ void kthread_destroy_worker(struct kthread_worker *worker)
|
||||
|
||||
kthread_flush_worker(worker);
|
||||
kthread_stop(task);
|
||||
WARN_ON(!list_empty(&worker->delayed_work_list));
|
||||
WARN_ON(!list_empty(&worker->work_list));
|
||||
kfree(worker);
|
||||
}
|
||||
|
@ -229,7 +229,7 @@ void __put_user_ns(struct user_namespace *ns)
|
||||
EXPORT_SYMBOL(__put_user_ns);
|
||||
|
||||
/**
|
||||
* idmap_key struct holds the information necessary to find an idmapping in a
|
||||
* struct idmap_key - holds the information necessary to find an idmapping in a
|
||||
* sorted idmap array. It is passed to cmp_map_id() as first argument.
|
||||
*/
|
||||
struct idmap_key {
|
||||
|
@ -1185,13 +1185,16 @@ config DEBUG_TIMEKEEPING
|
||||
config DEBUG_PREEMPT
|
||||
bool "Debug preemptible kernel"
|
||||
depends on DEBUG_KERNEL && PREEMPTION && TRACE_IRQFLAGS_SUPPORT
|
||||
default y
|
||||
help
|
||||
If you say Y here then the kernel will use a debug variant of the
|
||||
commonly used smp_processor_id() function and will print warnings
|
||||
if kernel code uses it in a preemption-unsafe way. Also, the kernel
|
||||
will detect preemption count underflows.
|
||||
|
||||
This option has potential to introduce high runtime overhead,
|
||||
depending on workload as it triggers debugging routines for each
|
||||
this_cpu operation. It should only be used for debugging purposes.
|
||||
|
||||
menu "Lock Debugging (spinlocks, mutexes, etc...)"
|
||||
|
||||
config LOCK_DEBUGGING_SUPPORT
|
||||
@ -2029,6 +2032,41 @@ menuconfig RUNTIME_TESTING_MENU
|
||||
|
||||
if RUNTIME_TESTING_MENU
|
||||
|
||||
config TEST_DHRY
|
||||
tristate "Dhrystone benchmark test"
|
||||
help
|
||||
Enable this to include the Dhrystone 2.1 benchmark. This test
|
||||
calculates the number of Dhrystones per second, and the number of
|
||||
DMIPS (Dhrystone MIPS) obtained when the Dhrystone score is divided
|
||||
by 1757 (the number of Dhrystones per second obtained on the VAX
|
||||
11/780, nominally a 1 MIPS machine).
|
||||
|
||||
To run the benchmark, it needs to be enabled explicitly, either from
|
||||
the kernel command line (when built-in), or from userspace (when
|
||||
built-in or modular.
|
||||
|
||||
Run once during kernel boot:
|
||||
|
||||
test_dhry.run
|
||||
|
||||
Set number of iterations from kernel command line:
|
||||
|
||||
test_dhry.iterations=<n>
|
||||
|
||||
Set number of iterations from userspace:
|
||||
|
||||
echo <n> > /sys/module/test_dhry/parameters/iterations
|
||||
|
||||
Trigger manual run from userspace:
|
||||
|
||||
echo y > /sys/module/test_dhry/parameters/run
|
||||
|
||||
If the number of iterations is <= 0, the test will devise a suitable
|
||||
number of iterations (test runs for at least 2s) automatically.
|
||||
This process takes ca. 4s.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config LKDTM
|
||||
tristate "Linux Kernel Dump Test Tool Module"
|
||||
depends on DEBUG_FS
|
||||
|
@ -57,6 +57,8 @@ obj-$(CONFIG_TEST_HEXDUMP) += test_hexdump.o
|
||||
obj-y += kstrtox.o
|
||||
obj-$(CONFIG_FIND_BIT_BENCHMARK) += find_bit_benchmark.o
|
||||
obj-$(CONFIG_TEST_BPF) += test_bpf.o
|
||||
test_dhry-objs := dhry_1.o dhry_2.o dhry_run.o
|
||||
obj-$(CONFIG_TEST_DHRY) += test_dhry.o
|
||||
obj-$(CONFIG_TEST_FIRMWARE) += test_firmware.o
|
||||
obj-$(CONFIG_TEST_BITOPS) += test_bitops.o
|
||||
CFLAGS_test_bitops.o += -Werror
|
||||
|
358
lib/dhry.h
Normal file
358
lib/dhry.h
Normal file
@ -0,0 +1,358 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
/*
|
||||
****************************************************************************
|
||||
*
|
||||
* "DHRYSTONE" Benchmark Program
|
||||
* -----------------------------
|
||||
*
|
||||
* Version: C, Version 2.1
|
||||
*
|
||||
* File: dhry.h (part 1 of 3)
|
||||
*
|
||||
* Date: May 25, 1988
|
||||
*
|
||||
* Author: Reinhold P. Weicker
|
||||
* Siemens AG, AUT E 51
|
||||
* Postfach 3220
|
||||
* 8520 Erlangen
|
||||
* Germany (West)
|
||||
* Phone: [+49]-9131-7-20330
|
||||
* (8-17 Central European Time)
|
||||
* Usenet: ..!mcsun!unido!estevax!weicker
|
||||
*
|
||||
* Original Version (in Ada) published in
|
||||
* "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
|
||||
* pp. 1013 - 1030, together with the statistics
|
||||
* on which the distribution of statements etc. is based.
|
||||
*
|
||||
* In this C version, the following C library functions are used:
|
||||
* - strcpy, strcmp (inside the measurement loop)
|
||||
* - printf, scanf (outside the measurement loop)
|
||||
* In addition, Berkeley UNIX system calls "times ()" or "time ()"
|
||||
* are used for execution time measurement. For measurements
|
||||
* on other systems, these calls have to be changed.
|
||||
*
|
||||
* Collection of Results:
|
||||
* Reinhold Weicker (address see above) and
|
||||
*
|
||||
* Rick Richardson
|
||||
* PC Research. Inc.
|
||||
* 94 Apple Orchard Drive
|
||||
* Tinton Falls, NJ 07724
|
||||
* Phone: (201) 389-8963 (9-17 EST)
|
||||
* Usenet: ...!uunet!pcrat!rick
|
||||
*
|
||||
* Please send results to Rick Richardson and/or Reinhold Weicker.
|
||||
* Complete information should be given on hardware and software used.
|
||||
* Hardware information includes: Machine type, CPU, type and size
|
||||
* of caches; for microprocessors: clock frequency, memory speed
|
||||
* (number of wait states).
|
||||
* Software information includes: Compiler (and runtime library)
|
||||
* manufacturer and version, compilation switches, OS version.
|
||||
* The Operating System version may give an indication about the
|
||||
* compiler; Dhrystone itself performs no OS calls in the measurement loop.
|
||||
*
|
||||
* The complete output generated by the program should be mailed
|
||||
* such that at least some checks for correctness can be made.
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* History: This version C/2.1 has been made for two reasons:
|
||||
*
|
||||
* 1) There is an obvious need for a common C version of
|
||||
* Dhrystone, since C is at present the most popular system
|
||||
* programming language for the class of processors
|
||||
* (microcomputers, minicomputers) where Dhrystone is used most.
|
||||
* There should be, as far as possible, only one C version of
|
||||
* Dhrystone such that results can be compared without
|
||||
* restrictions. In the past, the C versions distributed
|
||||
* by Rick Richardson (Version 1.1) and by Reinhold Weicker
|
||||
* had small (though not significant) differences.
|
||||
*
|
||||
* 2) As far as it is possible without changes to the Dhrystone
|
||||
* statistics, optimizing compilers should be prevented from
|
||||
* removing significant statements.
|
||||
*
|
||||
* This C version has been developed in cooperation with
|
||||
* Rick Richardson (Tinton Falls, NJ), it incorporates many
|
||||
* ideas from the "Version 1.1" distributed previously by
|
||||
* him over the UNIX network Usenet.
|
||||
* I also thank Chaim Benedelac (National Semiconductor),
|
||||
* David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
|
||||
* Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
|
||||
* for their help with comments on earlier versions of the
|
||||
* benchmark.
|
||||
*
|
||||
* Changes: In the initialization part, this version follows mostly
|
||||
* Rick Richardson's version distributed via Usenet, not the
|
||||
* version distributed earlier via floppy disk by Reinhold Weicker.
|
||||
* As a concession to older compilers, names have been made
|
||||
* unique within the first 8 characters.
|
||||
* Inside the measurement loop, this version follows the
|
||||
* version previously distributed by Reinhold Weicker.
|
||||
*
|
||||
* At several places in the benchmark, code has been added,
|
||||
* but within the measurement loop only in branches that
|
||||
* are not executed. The intention is that optimizing compilers
|
||||
* should be prevented from moving code out of the measurement
|
||||
* loop, or from removing code altogether. Since the statements
|
||||
* that are executed within the measurement loop have NOT been
|
||||
* changed, the numbers defining the "Dhrystone distribution"
|
||||
* (distribution of statements, operand types and locality)
|
||||
* still hold. Except for sophisticated optimizing compilers,
|
||||
* execution times for this version should be the same as
|
||||
* for previous versions.
|
||||
*
|
||||
* Since it has proven difficult to subtract the time for the
|
||||
* measurement loop overhead in a correct way, the loop check
|
||||
* has been made a part of the benchmark. This does have
|
||||
* an impact - though a very minor one - on the distribution
|
||||
* statistics which have been updated for this version.
|
||||
*
|
||||
* All changes within the measurement loop are described
|
||||
* and discussed in the companion paper "Rationale for
|
||||
* Dhrystone version 2".
|
||||
*
|
||||
* Because of the self-imposed limitation that the order and
|
||||
* distribution of the executed statements should not be
|
||||
* changed, there are still cases where optimizing compilers
|
||||
* may not generate code for some statements. To a certain
|
||||
* degree, this is unavoidable for small synthetic benchmarks.
|
||||
* Users of the benchmark are advised to check code listings
|
||||
* whether code is generated for all statements of Dhrystone.
|
||||
*
|
||||
* Version 2.1 is identical to version 2.0 distributed via
|
||||
* the UNIX network Usenet in March 1988 except that it corrects
|
||||
* some minor deficiencies that were found by users of version 2.0.
|
||||
* The only change within the measurement loop is that a
|
||||
* non-executed "else" part was added to the "if" statement in
|
||||
* Func_3, and a non-executed "else" part removed from Proc_3.
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Compilation model and measurement (IMPORTANT):
|
||||
*
|
||||
* This C version of Dhrystone consists of three files:
|
||||
* - dhry.h (this file, containing global definitions and comments)
|
||||
* - dhry_1.c (containing the code corresponding to Ada package Pack_1)
|
||||
* - dhry_2.c (containing the code corresponding to Ada package Pack_2)
|
||||
*
|
||||
* The following "ground rules" apply for measurements:
|
||||
* - Separate compilation
|
||||
* - No procedure merging
|
||||
* - Otherwise, compiler optimizations are allowed but should be indicated
|
||||
* - Default results are those without register declarations
|
||||
* See the companion paper "Rationale for Dhrystone Version 2" for a more
|
||||
* detailed discussion of these ground rules.
|
||||
*
|
||||
* For 16-Bit processors (e.g. 80186, 80286), times for all compilation
|
||||
* models ("small", "medium", "large" etc.) should be given if possible,
|
||||
* together with a definition of these models for the compiler system used.
|
||||
*
|
||||
**************************************************************************
|
||||
*
|
||||
* Dhrystone (C version) statistics:
|
||||
*
|
||||
* [Comment from the first distribution, updated for version 2.
|
||||
* Note that because of language differences, the numbers are slightly
|
||||
* different from the Ada version.]
|
||||
*
|
||||
* The following program contains statements of a high level programming
|
||||
* language (here: C) in a distribution considered representative:
|
||||
*
|
||||
* assignments 52 (51.0 %)
|
||||
* control statements 33 (32.4 %)
|
||||
* procedure, function calls 17 (16.7 %)
|
||||
*
|
||||
* 103 statements are dynamically executed. The program is balanced with
|
||||
* respect to the three aspects:
|
||||
*
|
||||
* - statement type
|
||||
* - operand type
|
||||
* - operand locality
|
||||
* operand global, local, parameter, or constant.
|
||||
*
|
||||
* The combination of these three aspects is balanced only approximately.
|
||||
*
|
||||
* 1. Statement Type:
|
||||
* ----------------- number
|
||||
*
|
||||
* V1 = V2 9
|
||||
* (incl. V1 = F(..)
|
||||
* V = Constant 12
|
||||
* Assignment, 7
|
||||
* with array element
|
||||
* Assignment, 6
|
||||
* with record component
|
||||
* --
|
||||
* 34 34
|
||||
*
|
||||
* X = Y +|-|"&&"|"|" Z 5
|
||||
* X = Y +|-|"==" Constant 6
|
||||
* X = X +|- 1 3
|
||||
* X = Y *|/ Z 2
|
||||
* X = Expression, 1
|
||||
* two operators
|
||||
* X = Expression, 1
|
||||
* three operators
|
||||
* --
|
||||
* 18 18
|
||||
*
|
||||
* if .... 14
|
||||
* with "else" 7
|
||||
* without "else" 7
|
||||
* executed 3
|
||||
* not executed 4
|
||||
* for ... 7 | counted every time
|
||||
* while ... 4 | the loop condition
|
||||
* do ... while 1 | is evaluated
|
||||
* switch ... 1
|
||||
* break 1
|
||||
* declaration with 1
|
||||
* initialization
|
||||
* --
|
||||
* 34 34
|
||||
*
|
||||
* P (...) procedure call 11
|
||||
* user procedure 10
|
||||
* library procedure 1
|
||||
* X = F (...)
|
||||
* function call 6
|
||||
* user function 5
|
||||
* library function 1
|
||||
* --
|
||||
* 17 17
|
||||
* ---
|
||||
* 103
|
||||
*
|
||||
* The average number of parameters in procedure or function calls
|
||||
* is 1.82 (not counting the function values as implicit parameters).
|
||||
*
|
||||
*
|
||||
* 2. Operators
|
||||
* ------------
|
||||
* number approximate
|
||||
* percentage
|
||||
*
|
||||
* Arithmetic 32 50.8
|
||||
*
|
||||
* + 21 33.3
|
||||
* - 7 11.1
|
||||
* * 3 4.8
|
||||
* / (int div) 1 1.6
|
||||
*
|
||||
* Comparison 27 42.8
|
||||
*
|
||||
* == 9 14.3
|
||||
* /= 4 6.3
|
||||
* > 1 1.6
|
||||
* < 3 4.8
|
||||
* >= 1 1.6
|
||||
* <= 9 14.3
|
||||
*
|
||||
* Logic 4 6.3
|
||||
*
|
||||
* && (AND-THEN) 1 1.6
|
||||
* | (OR) 1 1.6
|
||||
* ! (NOT) 2 3.2
|
||||
*
|
||||
* -- -----
|
||||
* 63 100.1
|
||||
*
|
||||
*
|
||||
* 3. Operand Type (counted once per operand reference):
|
||||
* ---------------
|
||||
* number approximate
|
||||
* percentage
|
||||
*
|
||||
* Integer 175 72.3 %
|
||||
* Character 45 18.6 %
|
||||
* Pointer 12 5.0 %
|
||||
* String30 6 2.5 %
|
||||
* Array 2 0.8 %
|
||||
* Record 2 0.8 %
|
||||
* --- -------
|
||||
* 242 100.0 %
|
||||
*
|
||||
* When there is an access path leading to the final operand (e.g. a record
|
||||
* component), only the final data type on the access path is counted.
|
||||
*
|
||||
*
|
||||
* 4. Operand Locality:
|
||||
* -------------------
|
||||
* number approximate
|
||||
* percentage
|
||||
*
|
||||
* local variable 114 47.1 %
|
||||
* global variable 22 9.1 %
|
||||
* parameter 45 18.6 %
|
||||
* value 23 9.5 %
|
||||
* reference 22 9.1 %
|
||||
* function result 6 2.5 %
|
||||
* constant 55 22.7 %
|
||||
* --- -------
|
||||
* 242 100.0 %
|
||||
*
|
||||
*
|
||||
* The program does not compute anything meaningful, but it is syntactically
|
||||
* and semantically correct. All variables have a value assigned to them
|
||||
* before they are used as a source operand.
|
||||
*
|
||||
* There has been no explicit effort to account for the effects of a
|
||||
* cache, or to balance the use of long or short displacements for code or
|
||||
* data.
|
||||
*
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
Ident_1,
|
||||
Ident_2,
|
||||
Ident_3,
|
||||
Ident_4,
|
||||
Ident_5
|
||||
} Enumeration; /* for boolean and enumeration types in Ada, Pascal */
|
||||
|
||||
/* General definitions: */
|
||||
|
||||
typedef int One_Thirty;
|
||||
typedef int One_Fifty;
|
||||
typedef char Capital_Letter;
|
||||
typedef int Boolean;
|
||||
typedef char Str_30[31];
|
||||
typedef int Arr_1_Dim[50];
|
||||
typedef int Arr_2_Dim[50][50];
|
||||
|
||||
typedef struct record {
|
||||
struct record *Ptr_Comp;
|
||||
Enumeration Discr;
|
||||
union {
|
||||
struct {
|
||||
Enumeration Enum_Comp;
|
||||
int Int_Comp;
|
||||
char Str_Comp[31];
|
||||
} var_1;
|
||||
struct {
|
||||
Enumeration E_Comp_2;
|
||||
char Str_2_Comp[31];
|
||||
} var_2;
|
||||
struct {
|
||||
char Ch_1_Comp;
|
||||
char Ch_2_Comp;
|
||||
} var_3;
|
||||
} variant;
|
||||
} Rec_Type, *Rec_Pointer;
|
||||
|
||||
|
||||
extern int Int_Glob;
|
||||
extern char Ch_1_Glob;
|
||||
|
||||
void Proc_6(Enumeration Enum_Val_Par, Enumeration *Enum_Ref_Par);
|
||||
void Proc_7(One_Fifty Int_1_Par_Val, One_Fifty Int_2_Par_Val,
|
||||
One_Fifty *Int_Par_Ref);
|
||||
void Proc_8(Arr_1_Dim Arr_1_Par_Ref, Arr_2_Dim Arr_2_Par_Ref,
|
||||
int Int_1_Par_Val, int Int_2_Par_Val);
|
||||
Enumeration Func_1(Capital_Letter Ch_1_Par_Val, Capital_Letter Ch_2_Par_Val);
|
||||
Boolean Func_2(Str_30 Str_1_Par_Ref, Str_30 Str_2_Par_Ref);
|
||||
|
||||
int dhry(int n);
|
283
lib/dhry_1.c
Normal file
283
lib/dhry_1.c
Normal file
@ -0,0 +1,283 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
/*
|
||||
****************************************************************************
|
||||
*
|
||||
* "DHRYSTONE" Benchmark Program
|
||||
* -----------------------------
|
||||
*
|
||||
* Version: C, Version 2.1
|
||||
*
|
||||
* File: dhry_1.c (part 2 of 3)
|
||||
*
|
||||
* Date: May 25, 1988
|
||||
*
|
||||
* Author: Reinhold P. Weicker
|
||||
*
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "dhry.h"
|
||||
|
||||
#include <linux/ktime.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
/* Global Variables: */
|
||||
|
||||
int Int_Glob;
|
||||
char Ch_1_Glob;
|
||||
|
||||
static Rec_Pointer Ptr_Glob, Next_Ptr_Glob;
|
||||
static Boolean Bool_Glob;
|
||||
static char Ch_2_Glob;
|
||||
static int Arr_1_Glob[50];
|
||||
static int Arr_2_Glob[50][50];
|
||||
|
||||
static void Proc_3(Rec_Pointer *Ptr_Ref_Par)
|
||||
/******************/
|
||||
/* executed once */
|
||||
/* Ptr_Ref_Par becomes Ptr_Glob */
|
||||
{
|
||||
if (Ptr_Glob) {
|
||||
/* then, executed */
|
||||
*Ptr_Ref_Par = Ptr_Glob->Ptr_Comp;
|
||||
}
|
||||
Proc_7(10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp);
|
||||
} /* Proc_3 */
|
||||
|
||||
|
||||
static void Proc_1(Rec_Pointer Ptr_Val_Par)
|
||||
/******************/
|
||||
/* executed once */
|
||||
{
|
||||
Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp;
|
||||
/* == Ptr_Glob_Next */
|
||||
/* Local variable, initialized with Ptr_Val_Par->Ptr_Comp, */
|
||||
/* corresponds to "rename" in Ada, "with" in Pascal */
|
||||
|
||||
*Ptr_Val_Par->Ptr_Comp = *Ptr_Glob;
|
||||
Ptr_Val_Par->variant.var_1.Int_Comp = 5;
|
||||
Next_Record->variant.var_1.Int_Comp =
|
||||
Ptr_Val_Par->variant.var_1.Int_Comp;
|
||||
Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp;
|
||||
Proc_3(&Next_Record->Ptr_Comp);
|
||||
/* Ptr_Val_Par->Ptr_Comp->Ptr_Comp == Ptr_Glob->Ptr_Comp */
|
||||
if (Next_Record->Discr == Ident_1) {
|
||||
/* then, executed */
|
||||
Next_Record->variant.var_1.Int_Comp = 6;
|
||||
Proc_6(Ptr_Val_Par->variant.var_1.Enum_Comp,
|
||||
&Next_Record->variant.var_1.Enum_Comp);
|
||||
Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp;
|
||||
Proc_7(Next_Record->variant.var_1.Int_Comp, 10,
|
||||
&Next_Record->variant.var_1.Int_Comp);
|
||||
} else {
|
||||
/* not executed */
|
||||
*Ptr_Val_Par = *Ptr_Val_Par->Ptr_Comp;
|
||||
}
|
||||
} /* Proc_1 */
|
||||
|
||||
|
||||
static void Proc_2(One_Fifty *Int_Par_Ref)
|
||||
/******************/
|
||||
/* executed once */
|
||||
/* *Int_Par_Ref == 1, becomes 4 */
|
||||
{
|
||||
One_Fifty Int_Loc;
|
||||
Enumeration Enum_Loc;
|
||||
|
||||
Int_Loc = *Int_Par_Ref + 10;
|
||||
do {
|
||||
/* executed once */
|
||||
if (Ch_1_Glob == 'A') {
|
||||
/* then, executed */
|
||||
Int_Loc -= 1;
|
||||
*Int_Par_Ref = Int_Loc - Int_Glob;
|
||||
Enum_Loc = Ident_1;
|
||||
} /* if */
|
||||
} while (Enum_Loc != Ident_1); /* true */
|
||||
} /* Proc_2 */
|
||||
|
||||
|
||||
static void Proc_4(void)
|
||||
/*******/
|
||||
/* executed once */
|
||||
{
|
||||
Boolean Bool_Loc;
|
||||
|
||||
Bool_Loc = Ch_1_Glob == 'A';
|
||||
Bool_Glob = Bool_Loc | Bool_Glob;
|
||||
Ch_2_Glob = 'B';
|
||||
} /* Proc_4 */
|
||||
|
||||
|
||||
static void Proc_5(void)
|
||||
/*******/
|
||||
/* executed once */
|
||||
{
|
||||
Ch_1_Glob = 'A';
|
||||
Bool_Glob = false;
|
||||
} /* Proc_5 */
|
||||
|
||||
|
||||
int dhry(int n)
|
||||
/*****/
|
||||
|
||||
/* main program, corresponds to procedures */
|
||||
/* Main and Proc_0 in the Ada version */
|
||||
{
|
||||
One_Fifty Int_1_Loc;
|
||||
One_Fifty Int_2_Loc;
|
||||
One_Fifty Int_3_Loc;
|
||||
char Ch_Index;
|
||||
Enumeration Enum_Loc;
|
||||
Str_30 Str_1_Loc;
|
||||
Str_30 Str_2_Loc;
|
||||
int Run_Index;
|
||||
int Number_Of_Runs;
|
||||
ktime_t Begin_Time, End_Time;
|
||||
u32 User_Time;
|
||||
|
||||
/* Initializations */
|
||||
|
||||
Next_Ptr_Glob = (Rec_Pointer)kzalloc(sizeof(Rec_Type), GFP_KERNEL);
|
||||
Ptr_Glob = (Rec_Pointer)kzalloc(sizeof(Rec_Type), GFP_KERNEL);
|
||||
|
||||
Ptr_Glob->Ptr_Comp = Next_Ptr_Glob;
|
||||
Ptr_Glob->Discr = Ident_1;
|
||||
Ptr_Glob->variant.var_1.Enum_Comp = Ident_3;
|
||||
Ptr_Glob->variant.var_1.Int_Comp = 40;
|
||||
strcpy(Ptr_Glob->variant.var_1.Str_Comp,
|
||||
"DHRYSTONE PROGRAM, SOME STRING");
|
||||
strcpy(Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
|
||||
|
||||
Arr_2_Glob[8][7] = 10;
|
||||
/* Was missing in published program. Without this statement, */
|
||||
/* Arr_2_Glob[8][7] would have an undefined value. */
|
||||
/* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */
|
||||
/* overflow may occur for this array element. */
|
||||
|
||||
pr_debug("Dhrystone Benchmark, Version 2.1 (Language: C)\n");
|
||||
|
||||
Number_Of_Runs = n;
|
||||
|
||||
pr_debug("Execution starts, %d runs through Dhrystone\n",
|
||||
Number_Of_Runs);
|
||||
|
||||
/***************/
|
||||
/* Start timer */
|
||||
/***************/
|
||||
|
||||
Begin_Time = ktime_get();
|
||||
|
||||
for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index) {
|
||||
Proc_5();
|
||||
Proc_4();
|
||||
/* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
|
||||
Int_1_Loc = 2;
|
||||
Int_2_Loc = 3;
|
||||
strcpy(Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
|
||||
Enum_Loc = Ident_2;
|
||||
Bool_Glob = !Func_2(Str_1_Loc, Str_2_Loc);
|
||||
/* Bool_Glob == 1 */
|
||||
while (Int_1_Loc < Int_2_Loc) {
|
||||
/* loop body executed once */
|
||||
Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
|
||||
/* Int_3_Loc == 7 */
|
||||
Proc_7(Int_1_Loc, Int_2_Loc, &Int_3_Loc);
|
||||
/* Int_3_Loc == 7 */
|
||||
Int_1_Loc += 1;
|
||||
} /* while */
|
||||
/* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
|
||||
Proc_8(Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
|
||||
/* Int_Glob == 5 */
|
||||
Proc_1(Ptr_Glob);
|
||||
for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index) {
|
||||
/* loop body executed twice */
|
||||
if (Enum_Loc == Func_1(Ch_Index, 'C')) {
|
||||
/* then, not executed */
|
||||
Proc_6(Ident_1, &Enum_Loc);
|
||||
strcpy(Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
|
||||
Int_2_Loc = Run_Index;
|
||||
Int_Glob = Run_Index;
|
||||
}
|
||||
}
|
||||
/* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
|
||||
Int_2_Loc = Int_2_Loc * Int_1_Loc;
|
||||
Int_1_Loc = Int_2_Loc / Int_3_Loc;
|
||||
Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
|
||||
/* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
|
||||
Proc_2(&Int_1_Loc);
|
||||
/* Int_1_Loc == 5 */
|
||||
|
||||
} /* loop "for Run_Index" */
|
||||
|
||||
/**************/
|
||||
/* Stop timer */
|
||||
/**************/
|
||||
|
||||
End_Time = ktime_get();
|
||||
|
||||
#define dhry_assert_int_eq(val, expected) \
|
||||
if (val != expected) \
|
||||
pr_err("%s: %d (FAIL, expected %d)\n", #val, val, \
|
||||
expected); \
|
||||
else \
|
||||
pr_debug("%s: %d (OK)\n", #val, val)
|
||||
|
||||
#define dhry_assert_char_eq(val, expected) \
|
||||
if (val != expected) \
|
||||
pr_err("%s: %c (FAIL, expected %c)\n", #val, val, \
|
||||
expected); \
|
||||
else \
|
||||
pr_debug("%s: %c (OK)\n", #val, val)
|
||||
|
||||
#define dhry_assert_string_eq(val, expected) \
|
||||
if (strcmp(val, expected)) \
|
||||
pr_err("%s: %s (FAIL, expected %s)\n", #val, val, \
|
||||
expected); \
|
||||
else \
|
||||
pr_debug("%s: %s (OK)\n", #val, val)
|
||||
|
||||
pr_debug("Execution ends\n");
|
||||
pr_debug("Final values of the variables used in the benchmark:\n");
|
||||
dhry_assert_int_eq(Int_Glob, 5);
|
||||
dhry_assert_int_eq(Bool_Glob, 1);
|
||||
dhry_assert_char_eq(Ch_1_Glob, 'A');
|
||||
dhry_assert_char_eq(Ch_2_Glob, 'B');
|
||||
dhry_assert_int_eq(Arr_1_Glob[8], 7);
|
||||
dhry_assert_int_eq(Arr_2_Glob[8][7], Number_Of_Runs + 10);
|
||||
pr_debug("Ptr_Comp: %px\n", Ptr_Glob->Ptr_Comp);
|
||||
dhry_assert_int_eq(Ptr_Glob->Discr, 0);
|
||||
dhry_assert_int_eq(Ptr_Glob->variant.var_1.Enum_Comp, 2);
|
||||
dhry_assert_int_eq(Ptr_Glob->variant.var_1.Int_Comp, 17);
|
||||
dhry_assert_string_eq(Ptr_Glob->variant.var_1.Str_Comp,
|
||||
"DHRYSTONE PROGRAM, SOME STRING");
|
||||
if (Next_Ptr_Glob->Ptr_Comp != Ptr_Glob->Ptr_Comp)
|
||||
pr_err("Next_Ptr_Glob->Ptr_Comp: %px (expected %px)\n",
|
||||
Next_Ptr_Glob->Ptr_Comp, Ptr_Glob->Ptr_Comp);
|
||||
else
|
||||
pr_debug("Next_Ptr_Glob->Ptr_Comp: %px\n",
|
||||
Next_Ptr_Glob->Ptr_Comp);
|
||||
dhry_assert_int_eq(Next_Ptr_Glob->Discr, 0);
|
||||
dhry_assert_int_eq(Next_Ptr_Glob->variant.var_1.Enum_Comp, 1);
|
||||
dhry_assert_int_eq(Next_Ptr_Glob->variant.var_1.Int_Comp, 18);
|
||||
dhry_assert_string_eq(Next_Ptr_Glob->variant.var_1.Str_Comp,
|
||||
"DHRYSTONE PROGRAM, SOME STRING");
|
||||
dhry_assert_int_eq(Int_1_Loc, 5);
|
||||
dhry_assert_int_eq(Int_2_Loc, 13);
|
||||
dhry_assert_int_eq(Int_3_Loc, 7);
|
||||
dhry_assert_int_eq(Enum_Loc, 1);
|
||||
dhry_assert_string_eq(Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
|
||||
dhry_assert_string_eq(Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
|
||||
|
||||
User_Time = ktime_to_ms(ktime_sub(End_Time, Begin_Time));
|
||||
|
||||
kfree(Ptr_Glob);
|
||||
kfree(Next_Ptr_Glob);
|
||||
|
||||
/* Measurements should last at least 2 seconds */
|
||||
if (User_Time < 2 * MSEC_PER_SEC)
|
||||
return -EAGAIN;
|
||||
|
||||
return div_u64(mul_u32_u32(MSEC_PER_SEC, Number_Of_Runs), User_Time);
|
||||
}
|
175
lib/dhry_2.c
Normal file
175
lib/dhry_2.c
Normal file
@ -0,0 +1,175 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
/*
|
||||
****************************************************************************
|
||||
*
|
||||
* "DHRYSTONE" Benchmark Program
|
||||
* -----------------------------
|
||||
*
|
||||
* Version: C, Version 2.1
|
||||
*
|
||||
* File: dhry_2.c (part 3 of 3)
|
||||
*
|
||||
* Date: May 25, 1988
|
||||
*
|
||||
* Author: Reinhold P. Weicker
|
||||
*
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "dhry.h"
|
||||
|
||||
#include <linux/string.h>
|
||||
|
||||
|
||||
static Boolean Func_3(Enumeration Enum_Par_Val)
|
||||
/***************************/
|
||||
/* executed once */
|
||||
/* Enum_Par_Val == Ident_3 */
|
||||
{
|
||||
Enumeration Enum_Loc;
|
||||
|
||||
Enum_Loc = Enum_Par_Val;
|
||||
if (Enum_Loc == Ident_3) {
|
||||
/* then, executed */
|
||||
return true;
|
||||
} else {
|
||||
/* not executed */
|
||||
return false;
|
||||
}
|
||||
} /* Func_3 */
|
||||
|
||||
|
||||
void Proc_6(Enumeration Enum_Val_Par, Enumeration *Enum_Ref_Par)
|
||||
/*********************************/
|
||||
/* executed once */
|
||||
/* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */
|
||||
{
|
||||
*Enum_Ref_Par = Enum_Val_Par;
|
||||
if (!Func_3(Enum_Val_Par)) {
|
||||
/* then, not executed */
|
||||
*Enum_Ref_Par = Ident_4;
|
||||
}
|
||||
switch (Enum_Val_Par) {
|
||||
case Ident_1:
|
||||
*Enum_Ref_Par = Ident_1;
|
||||
break;
|
||||
case Ident_2:
|
||||
if (Int_Glob > 100) {
|
||||
/* then */
|
||||
*Enum_Ref_Par = Ident_1;
|
||||
} else {
|
||||
*Enum_Ref_Par = Ident_4;
|
||||
}
|
||||
break;
|
||||
case Ident_3: /* executed */
|
||||
*Enum_Ref_Par = Ident_2;
|
||||
break;
|
||||
case Ident_4:
|
||||
break;
|
||||
case Ident_5:
|
||||
*Enum_Ref_Par = Ident_3;
|
||||
break;
|
||||
} /* switch */
|
||||
} /* Proc_6 */
|
||||
|
||||
|
||||
void Proc_7(One_Fifty Int_1_Par_Val, One_Fifty Int_2_Par_Val, One_Fifty *Int_Par_Ref)
|
||||
/**********************************************/
|
||||
/* executed three times */
|
||||
/* first call: Int_1_Par_Val == 2, Int_2_Par_Val == 3, */
|
||||
/* Int_Par_Ref becomes 7 */
|
||||
/* second call: Int_1_Par_Val == 10, Int_2_Par_Val == 5, */
|
||||
/* Int_Par_Ref becomes 17 */
|
||||
/* third call: Int_1_Par_Val == 6, Int_2_Par_Val == 10, */
|
||||
/* Int_Par_Ref becomes 18 */
|
||||
{
|
||||
One_Fifty Int_Loc;
|
||||
|
||||
Int_Loc = Int_1_Par_Val + 2;
|
||||
*Int_Par_Ref = Int_2_Par_Val + Int_Loc;
|
||||
} /* Proc_7 */
|
||||
|
||||
|
||||
void Proc_8(Arr_1_Dim Arr_1_Par_Ref, Arr_2_Dim Arr_2_Par_Ref, int Int_1_Par_Val, int Int_2_Par_Val)
|
||||
/*********************************************************************/
|
||||
/* executed once */
|
||||
/* Int_Par_Val_1 == 3 */
|
||||
/* Int_Par_Val_2 == 7 */
|
||||
{
|
||||
One_Fifty Int_Index;
|
||||
One_Fifty Int_Loc;
|
||||
|
||||
Int_Loc = Int_1_Par_Val + 5;
|
||||
Arr_1_Par_Ref[Int_Loc] = Int_2_Par_Val;
|
||||
Arr_1_Par_Ref[Int_Loc+1] = Arr_1_Par_Ref[Int_Loc];
|
||||
Arr_1_Par_Ref[Int_Loc+30] = Int_Loc;
|
||||
for (Int_Index = Int_Loc; Int_Index <= Int_Loc+1; ++Int_Index)
|
||||
Arr_2_Par_Ref[Int_Loc][Int_Index] = Int_Loc;
|
||||
Arr_2_Par_Ref[Int_Loc][Int_Loc-1] += 1;
|
||||
Arr_2_Par_Ref[Int_Loc+20][Int_Loc] = Arr_1_Par_Ref[Int_Loc];
|
||||
Int_Glob = 5;
|
||||
} /* Proc_8 */
|
||||
|
||||
|
||||
Enumeration Func_1(Capital_Letter Ch_1_Par_Val, Capital_Letter Ch_2_Par_Val)
|
||||
/*************************************************/
|
||||
/* executed three times */
|
||||
/* first call: Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R' */
|
||||
/* second call: Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C' */
|
||||
/* third call: Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C' */
|
||||
{
|
||||
Capital_Letter Ch_1_Loc;
|
||||
Capital_Letter Ch_2_Loc;
|
||||
|
||||
Ch_1_Loc = Ch_1_Par_Val;
|
||||
Ch_2_Loc = Ch_1_Loc;
|
||||
if (Ch_2_Loc != Ch_2_Par_Val) {
|
||||
/* then, executed */
|
||||
return Ident_1;
|
||||
} else {
|
||||
/* not executed */
|
||||
Ch_1_Glob = Ch_1_Loc;
|
||||
return Ident_2;
|
||||
}
|
||||
} /* Func_1 */
|
||||
|
||||
|
||||
Boolean Func_2(Str_30 Str_1_Par_Ref, Str_30 Str_2_Par_Ref)
|
||||
/*************************************************/
|
||||
/* executed once */
|
||||
/* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */
|
||||
/* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */
|
||||
{
|
||||
One_Thirty Int_Loc;
|
||||
Capital_Letter Ch_Loc;
|
||||
|
||||
Int_Loc = 2;
|
||||
while (Int_Loc <= 2) {
|
||||
/* loop body executed once */
|
||||
if (Func_1(Str_1_Par_Ref[Int_Loc],
|
||||
Str_2_Par_Ref[Int_Loc+1]) == Ident_1) {
|
||||
/* then, executed */
|
||||
Ch_Loc = 'A';
|
||||
Int_Loc += 1;
|
||||
}
|
||||
} /* if, while */
|
||||
if (Ch_Loc >= 'W' && Ch_Loc < 'Z') {
|
||||
/* then, not executed */
|
||||
Int_Loc = 7;
|
||||
}
|
||||
if (Ch_Loc == 'R') {
|
||||
/* then, not executed */
|
||||
return true;
|
||||
} else {
|
||||
/* executed */
|
||||
if (strcmp(Str_1_Par_Ref, Str_2_Par_Ref) > 0) {
|
||||
/* then, not executed */
|
||||
Int_Loc += 7;
|
||||
Int_Glob = Int_Loc;
|
||||
return true;
|
||||
} else {
|
||||
/* executed */
|
||||
return false;
|
||||
}
|
||||
} /* if Ch_Loc */
|
||||
} /* Func_2 */
|
85
lib/dhry_run.c
Normal file
85
lib/dhry_run.c
Normal file
@ -0,0 +1,85 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Dhrystone benchmark test module
|
||||
*
|
||||
* Copyright (C) 2022 Glider bv
|
||||
*/
|
||||
|
||||
#include "dhry.h"
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/smp.h>
|
||||
|
||||
#define DHRY_VAX 1757
|
||||
|
||||
static int dhry_run_set(const char *val, const struct kernel_param *kp);
|
||||
static const struct kernel_param_ops run_ops = {
|
||||
.flags = KERNEL_PARAM_OPS_FL_NOARG,
|
||||
.set = dhry_run_set,
|
||||
};
|
||||
static bool dhry_run;
|
||||
module_param_cb(run, &run_ops, &dhry_run, 0200);
|
||||
MODULE_PARM_DESC(run, "Run the test (default: false)");
|
||||
|
||||
static int iterations = -1;
|
||||
module_param(iterations, int, 0644);
|
||||
MODULE_PARM_DESC(iterations,
|
||||
"Number of iterations through the benchmark (default: auto)");
|
||||
|
||||
static void dhry_benchmark(void)
|
||||
{
|
||||
int i, n;
|
||||
|
||||
if (iterations > 0) {
|
||||
n = dhry(iterations);
|
||||
goto report;
|
||||
}
|
||||
|
||||
for (i = DHRY_VAX; i > 0; i <<= 1) {
|
||||
n = dhry(i);
|
||||
if (n != -EAGAIN)
|
||||
break;
|
||||
}
|
||||
|
||||
report:
|
||||
if (n >= 0)
|
||||
pr_info("CPU%u: Dhrystones per Second: %d (%d DMIPS)\n",
|
||||
smp_processor_id(), n, n / DHRY_VAX);
|
||||
else if (n == -EAGAIN)
|
||||
pr_err("Please increase the number of iterations\n");
|
||||
else
|
||||
pr_err("Dhrystone benchmark failed error %pe\n", ERR_PTR(n));
|
||||
}
|
||||
|
||||
static int dhry_run_set(const char *val, const struct kernel_param *kp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (val) {
|
||||
ret = param_set_bool(val, kp);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
dhry_run = true;
|
||||
}
|
||||
|
||||
if (dhry_run && system_state == SYSTEM_RUNNING)
|
||||
dhry_benchmark();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init dhry_init(void)
|
||||
{
|
||||
if (dhry_run)
|
||||
dhry_benchmark();
|
||||
|
||||
return 0;
|
||||
}
|
||||
module_init(dhry_init);
|
||||
|
||||
MODULE_AUTHOR("Geert Uytterhoeven <geert+renesas@glider.be>");
|
||||
MODULE_LICENSE("GPL");
|
@ -40,7 +40,7 @@ bool within_error_injection_list(unsigned long addr)
|
||||
int get_injectable_error_type(unsigned long addr)
|
||||
{
|
||||
struct ei_entry *ent;
|
||||
int ei_type = EI_ETYPE_NONE;
|
||||
int ei_type = -EINVAL;
|
||||
|
||||
mutex_lock(&ei_mutex);
|
||||
list_for_each_entry(ent, &error_injection_list, list) {
|
||||
|
@ -40,32 +40,30 @@ static inline size_t chunk_size(const struct gen_pool_chunk *chunk)
|
||||
return chunk->end_addr - chunk->start_addr + 1;
|
||||
}
|
||||
|
||||
static int set_bits_ll(unsigned long *addr, unsigned long mask_to_set)
|
||||
static inline int
|
||||
set_bits_ll(unsigned long *addr, unsigned long mask_to_set)
|
||||
{
|
||||
unsigned long val, nval;
|
||||
unsigned long val = READ_ONCE(*addr);
|
||||
|
||||
nval = *addr;
|
||||
do {
|
||||
val = nval;
|
||||
if (val & mask_to_set)
|
||||
return -EBUSY;
|
||||
cpu_relax();
|
||||
} while ((nval = cmpxchg(addr, val, val | mask_to_set)) != val);
|
||||
} while (!try_cmpxchg(addr, &val, val | mask_to_set));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clear_bits_ll(unsigned long *addr, unsigned long mask_to_clear)
|
||||
static inline int
|
||||
clear_bits_ll(unsigned long *addr, unsigned long mask_to_clear)
|
||||
{
|
||||
unsigned long val, nval;
|
||||
unsigned long val = READ_ONCE(*addr);
|
||||
|
||||
nval = *addr;
|
||||
do {
|
||||
val = nval;
|
||||
if ((val & mask_to_clear) != mask_to_clear)
|
||||
return -EBUSY;
|
||||
cpu_relax();
|
||||
} while ((nval = cmpxchg(addr, val, val & ~mask_to_clear)) != val);
|
||||
} while (!try_cmpxchg(addr, &val, val & ~mask_to_clear));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -73,28 +73,33 @@ void percpu_counter_set(struct percpu_counter *fbc, s64 amount)
|
||||
EXPORT_SYMBOL(percpu_counter_set);
|
||||
|
||||
/*
|
||||
* This function is both preempt and irq safe. The former is due to explicit
|
||||
* preemption disable. The latter is guaranteed by the fact that the slow path
|
||||
* is explicitly protected by an irq-safe spinlock whereas the fast patch uses
|
||||
* this_cpu_add which is irq-safe by definition. Hence there is no need muck
|
||||
* with irq state before calling this one
|
||||
* local_irq_save() is needed to make the function irq safe:
|
||||
* - The slow path would be ok as protected by an irq-safe spinlock.
|
||||
* - this_cpu_add would be ok as it is irq-safe by definition.
|
||||
* But:
|
||||
* The decision slow path/fast path and the actual update must be atomic, too.
|
||||
* Otherwise a call in process context could check the current values and
|
||||
* decide that the fast path can be used. If now an interrupt occurs before
|
||||
* the this_cpu_add(), and the interrupt updates this_cpu(*fbc->counters),
|
||||
* then the this_cpu_add() that is executed after the interrupt has completed
|
||||
* can produce values larger than "batch" or even overflows.
|
||||
*/
|
||||
void percpu_counter_add_batch(struct percpu_counter *fbc, s64 amount, s32 batch)
|
||||
{
|
||||
s64 count;
|
||||
unsigned long flags;
|
||||
|
||||
preempt_disable();
|
||||
local_irq_save(flags);
|
||||
count = __this_cpu_read(*fbc->counters) + amount;
|
||||
if (abs(count) >= batch) {
|
||||
unsigned long flags;
|
||||
raw_spin_lock_irqsave(&fbc->lock, flags);
|
||||
raw_spin_lock(&fbc->lock);
|
||||
fbc->count += count;
|
||||
__this_cpu_sub(*fbc->counters, count - amount);
|
||||
raw_spin_unlock_irqrestore(&fbc->lock, flags);
|
||||
raw_spin_unlock(&fbc->lock);
|
||||
} else {
|
||||
this_cpu_add(*fbc->counters, amount);
|
||||
}
|
||||
preempt_enable();
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
EXPORT_SYMBOL(percpu_counter_add_batch);
|
||||
|
||||
|
@ -54,7 +54,7 @@
|
||||
|
||||
/* architecture-specific bits */
|
||||
#ifdef CONFIG_ZLIB_DFLTCC
|
||||
# include "../zlib_dfltcc/dfltcc.h"
|
||||
# include "../zlib_dfltcc/dfltcc_deflate.h"
|
||||
#else
|
||||
#define DEFLATE_RESET_HOOK(strm) do {} while (0)
|
||||
#define DEFLATE_HOOK(strm, flush, bstate) 0
|
||||
@ -106,7 +106,7 @@ typedef struct deflate_workspace {
|
||||
deflate_state deflate_memory;
|
||||
#ifdef CONFIG_ZLIB_DFLTCC
|
||||
/* State memory for s390 hardware deflate */
|
||||
struct dfltcc_state dfltcc_memory;
|
||||
struct dfltcc_deflate_state dfltcc_memory;
|
||||
#endif
|
||||
Byte *window_memory;
|
||||
Pos *prev_memory;
|
||||
@ -451,17 +451,24 @@ int zlib_deflate(
|
||||
Assert(strm->avail_out > 0, "bug2");
|
||||
|
||||
if (flush != Z_FINISH) return Z_OK;
|
||||
if (s->noheader) return Z_STREAM_END;
|
||||
|
||||
/* Write the zlib trailer (adler32) */
|
||||
putShortMSB(s, (uInt)(strm->adler >> 16));
|
||||
putShortMSB(s, (uInt)(strm->adler & 0xffff));
|
||||
if (!s->noheader) {
|
||||
/* Write zlib trailer (adler32) */
|
||||
putShortMSB(s, (uInt)(strm->adler >> 16));
|
||||
putShortMSB(s, (uInt)(strm->adler & 0xffff));
|
||||
}
|
||||
flush_pending(strm);
|
||||
/* If avail_out is zero, the application will call deflate again
|
||||
* to flush the rest.
|
||||
*/
|
||||
s->noheader = -1; /* write the trailer only once! */
|
||||
return s->pending != 0 ? Z_OK : Z_STREAM_END;
|
||||
if (!s->noheader) {
|
||||
s->noheader = -1; /* write the trailer only once! */
|
||||
}
|
||||
if (s->pending == 0) {
|
||||
Assert(s->bi_valid == 0, "bi_buf not flushed");
|
||||
return Z_STREAM_END;
|
||||
}
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
@ -23,37 +23,18 @@ char *oesc_msg(
|
||||
}
|
||||
}
|
||||
|
||||
void dfltcc_reset(
|
||||
z_streamp strm,
|
||||
uInt size
|
||||
)
|
||||
{
|
||||
struct dfltcc_state *dfltcc_state =
|
||||
(struct dfltcc_state *)((char *)strm->state + size);
|
||||
struct dfltcc_qaf_param *param =
|
||||
(struct dfltcc_qaf_param *)&dfltcc_state->param;
|
||||
|
||||
void dfltcc_reset_state(struct dfltcc_state *dfltcc_state) {
|
||||
/* Initialize available functions */
|
||||
if (is_dfltcc_enabled()) {
|
||||
dfltcc(DFLTCC_QAF, param, NULL, NULL, NULL, NULL, NULL);
|
||||
memmove(&dfltcc_state->af, param, sizeof(dfltcc_state->af));
|
||||
dfltcc(DFLTCC_QAF, &dfltcc_state->param, NULL, NULL, NULL, NULL, NULL);
|
||||
memmove(&dfltcc_state->af, &dfltcc_state->param, sizeof(dfltcc_state->af));
|
||||
} else
|
||||
memset(&dfltcc_state->af, 0, sizeof(dfltcc_state->af));
|
||||
|
||||
/* Initialize parameter block */
|
||||
memset(&dfltcc_state->param, 0, sizeof(dfltcc_state->param));
|
||||
dfltcc_state->param.nt = 1;
|
||||
|
||||
/* Initialize tuning parameters */
|
||||
if (zlib_dfltcc_support == ZLIB_DFLTCC_FULL_DEBUG)
|
||||
dfltcc_state->level_mask = DFLTCC_LEVEL_MASK_DEBUG;
|
||||
else
|
||||
dfltcc_state->level_mask = DFLTCC_LEVEL_MASK;
|
||||
dfltcc_state->block_size = DFLTCC_BLOCK_SIZE;
|
||||
dfltcc_state->block_threshold = DFLTCC_FIRST_FHT_BLOCK_SIZE;
|
||||
dfltcc_state->dht_threshold = DFLTCC_DHT_MIN_SAMPLE_SIZE;
|
||||
dfltcc_state->param.ribm = DFLTCC_RIBM;
|
||||
}
|
||||
EXPORT_SYMBOL(dfltcc_reset);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -93,63 +93,32 @@ static_assert(sizeof(struct dfltcc_param_v0) == 1536);
|
||||
struct dfltcc_state {
|
||||
struct dfltcc_param_v0 param; /* Parameter block */
|
||||
struct dfltcc_qaf_param af; /* Available functions */
|
||||
char msg[64]; /* Buffer for strm->msg */
|
||||
};
|
||||
|
||||
/*
|
||||
* Extension of inflate_state and deflate_state for DFLTCC.
|
||||
*/
|
||||
struct dfltcc_deflate_state {
|
||||
struct dfltcc_state common; /* Parameter block */
|
||||
uLong level_mask; /* Levels on which to use DFLTCC */
|
||||
uLong block_size; /* New block each X bytes */
|
||||
uLong block_threshold; /* New block after total_in > X */
|
||||
uLong dht_threshold; /* New block only if avail_in >= X */
|
||||
char msg[64]; /* Buffer for strm->msg */
|
||||
};
|
||||
|
||||
#define ALIGN_UP(p, size) (__typeof__(p))(((uintptr_t)(p) + ((size) - 1)) & ~((size) - 1))
|
||||
/* Resides right after inflate_state or deflate_state */
|
||||
#define GET_DFLTCC_STATE(state) ((struct dfltcc_state *)((state) + 1))
|
||||
#define GET_DFLTCC_STATE(state) ((struct dfltcc_state *)((char *)(state) + ALIGN_UP(sizeof(*state), 8)))
|
||||
|
||||
void dfltcc_reset_state(struct dfltcc_state *dfltcc_state);
|
||||
|
||||
/* External functions */
|
||||
int dfltcc_can_deflate(z_streamp strm);
|
||||
int dfltcc_deflate(z_streamp strm,
|
||||
int flush,
|
||||
block_state *result);
|
||||
void dfltcc_reset(z_streamp strm, uInt size);
|
||||
int dfltcc_can_inflate(z_streamp strm);
|
||||
typedef enum {
|
||||
DFLTCC_INFLATE_CONTINUE,
|
||||
DFLTCC_INFLATE_BREAK,
|
||||
DFLTCC_INFLATE_SOFTWARE,
|
||||
} dfltcc_inflate_action;
|
||||
dfltcc_inflate_action dfltcc_inflate(z_streamp strm,
|
||||
int flush, int *ret);
|
||||
static inline int is_dfltcc_enabled(void)
|
||||
{
|
||||
return (zlib_dfltcc_support != ZLIB_DFLTCC_DISABLED &&
|
||||
test_facility(DFLTCC_FACILITY));
|
||||
}
|
||||
|
||||
#define DEFLATE_RESET_HOOK(strm) \
|
||||
dfltcc_reset((strm), sizeof(deflate_state))
|
||||
|
||||
#define DEFLATE_HOOK dfltcc_deflate
|
||||
|
||||
#define DEFLATE_NEED_CHECKSUM(strm) (!dfltcc_can_deflate((strm)))
|
||||
|
||||
#define DEFLATE_DFLTCC_ENABLED() is_dfltcc_enabled()
|
||||
|
||||
#define INFLATE_RESET_HOOK(strm) \
|
||||
dfltcc_reset((strm), sizeof(struct inflate_state))
|
||||
|
||||
#define INFLATE_TYPEDO_HOOK(strm, flush) \
|
||||
if (dfltcc_can_inflate((strm))) { \
|
||||
dfltcc_inflate_action action; \
|
||||
\
|
||||
RESTORE(); \
|
||||
action = dfltcc_inflate((strm), (flush), &ret); \
|
||||
LOAD(); \
|
||||
if (action == DFLTCC_INFLATE_CONTINUE) \
|
||||
break; \
|
||||
else if (action == DFLTCC_INFLATE_BREAK) \
|
||||
goto inf_leave; \
|
||||
}
|
||||
|
||||
#define INFLATE_NEED_CHECKSUM(strm) (!dfltcc_can_inflate((strm)))
|
||||
|
||||
#define INFLATE_NEED_UPDATEWINDOW(strm) (!dfltcc_can_inflate((strm)))
|
||||
|
||||
#endif /* DFLTCC_H */
|
||||
|
@ -2,11 +2,13 @@
|
||||
|
||||
#include "../zlib_deflate/defutil.h"
|
||||
#include "dfltcc_util.h"
|
||||
#include "dfltcc.h"
|
||||
#include "dfltcc_deflate.h"
|
||||
#include <asm/setup.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/zutil.h>
|
||||
|
||||
#define GET_DFLTCC_DEFLATE_STATE(state) ((struct dfltcc_deflate_state *)GET_DFLTCC_STATE(state))
|
||||
|
||||
/*
|
||||
* Compress.
|
||||
*/
|
||||
@ -15,7 +17,7 @@ int dfltcc_can_deflate(
|
||||
)
|
||||
{
|
||||
deflate_state *state = (deflate_state *)strm->state;
|
||||
struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state);
|
||||
struct dfltcc_deflate_state *dfltcc_state = GET_DFLTCC_DEFLATE_STATE(state);
|
||||
|
||||
/* Check for kernel dfltcc command line parameter */
|
||||
if (zlib_dfltcc_support == ZLIB_DFLTCC_DISABLED ||
|
||||
@ -28,22 +30,39 @@ int dfltcc_can_deflate(
|
||||
return 0;
|
||||
|
||||
/* Unsupported hardware */
|
||||
if (!is_bit_set(dfltcc_state->af.fns, DFLTCC_GDHT) ||
|
||||
!is_bit_set(dfltcc_state->af.fns, DFLTCC_CMPR) ||
|
||||
!is_bit_set(dfltcc_state->af.fmts, DFLTCC_FMT0))
|
||||
if (!is_bit_set(dfltcc_state->common.af.fns, DFLTCC_GDHT) ||
|
||||
!is_bit_set(dfltcc_state->common.af.fns, DFLTCC_CMPR) ||
|
||||
!is_bit_set(dfltcc_state->common.af.fmts, DFLTCC_FMT0))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL(dfltcc_can_deflate);
|
||||
|
||||
void dfltcc_reset_deflate_state(z_streamp strm) {
|
||||
deflate_state *state = (deflate_state *)strm->state;
|
||||
struct dfltcc_deflate_state *dfltcc_state = GET_DFLTCC_DEFLATE_STATE(state);
|
||||
|
||||
dfltcc_reset_state(&dfltcc_state->common);
|
||||
|
||||
/* Initialize tuning parameters */
|
||||
if (zlib_dfltcc_support == ZLIB_DFLTCC_FULL_DEBUG)
|
||||
dfltcc_state->level_mask = DFLTCC_LEVEL_MASK_DEBUG;
|
||||
else
|
||||
dfltcc_state->level_mask = DFLTCC_LEVEL_MASK;
|
||||
dfltcc_state->block_size = DFLTCC_BLOCK_SIZE;
|
||||
dfltcc_state->block_threshold = DFLTCC_FIRST_FHT_BLOCK_SIZE;
|
||||
dfltcc_state->dht_threshold = DFLTCC_DHT_MIN_SAMPLE_SIZE;
|
||||
}
|
||||
EXPORT_SYMBOL(dfltcc_reset_deflate_state);
|
||||
|
||||
static void dfltcc_gdht(
|
||||
z_streamp strm
|
||||
)
|
||||
{
|
||||
deflate_state *state = (deflate_state *)strm->state;
|
||||
struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param;
|
||||
size_t avail_in = avail_in = strm->avail_in;
|
||||
size_t avail_in = strm->avail_in;
|
||||
|
||||
dfltcc(DFLTCC_GDHT,
|
||||
param, NULL, NULL,
|
||||
@ -104,39 +123,46 @@ int dfltcc_deflate(
|
||||
)
|
||||
{
|
||||
deflate_state *state = (deflate_state *)strm->state;
|
||||
struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state);
|
||||
struct dfltcc_param_v0 *param = &dfltcc_state->param;
|
||||
struct dfltcc_deflate_state *dfltcc_state = GET_DFLTCC_DEFLATE_STATE(state);
|
||||
struct dfltcc_param_v0 *param = &dfltcc_state->common.param;
|
||||
uInt masked_avail_in;
|
||||
dfltcc_cc cc;
|
||||
int need_empty_block;
|
||||
int soft_bcc;
|
||||
int no_flush;
|
||||
|
||||
if (!dfltcc_can_deflate(strm))
|
||||
if (!dfltcc_can_deflate(strm)) {
|
||||
/* Clear history. */
|
||||
if (flush == Z_FULL_FLUSH)
|
||||
param->hl = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
again:
|
||||
masked_avail_in = 0;
|
||||
soft_bcc = 0;
|
||||
no_flush = flush == Z_NO_FLUSH;
|
||||
|
||||
/* Trailing empty block. Switch to software, except when Continuation Flag
|
||||
* is set, which means that DFLTCC has buffered some output in the
|
||||
* parameter block and needs to be called again in order to flush it.
|
||||
/* No input data. Return, except when Continuation Flag is set, which means
|
||||
* that DFLTCC has buffered some output in the parameter block and needs to
|
||||
* be called again in order to flush it.
|
||||
*/
|
||||
if (flush == Z_FINISH && strm->avail_in == 0 && !param->cf) {
|
||||
if (param->bcf) {
|
||||
/* A block is still open, and the hardware does not support closing
|
||||
* blocks without adding data. Thus, close it manually.
|
||||
*/
|
||||
if (strm->avail_in == 0 && !param->cf) {
|
||||
/* A block is still open, and the hardware does not support closing
|
||||
* blocks without adding data. Thus, close it manually.
|
||||
*/
|
||||
if (!no_flush && param->bcf) {
|
||||
send_eobs(strm, param);
|
||||
param->bcf = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strm->avail_in == 0 && !param->cf) {
|
||||
*result = need_more;
|
||||
/* Let one of deflate_* functions write a trailing empty block. */
|
||||
if (flush == Z_FINISH)
|
||||
return 0;
|
||||
/* Clear history. */
|
||||
if (flush == Z_FULL_FLUSH)
|
||||
param->hl = 0;
|
||||
/* Trigger block post-processing if necessary. */
|
||||
*result = no_flush ? need_more : block_done;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -163,13 +189,18 @@ again:
|
||||
param->bcf = 0;
|
||||
dfltcc_state->block_threshold =
|
||||
strm->total_in + dfltcc_state->block_size;
|
||||
if (strm->avail_out == 0) {
|
||||
*result = need_more;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* No space for compressed data. If we proceed, dfltcc_cmpr() will return
|
||||
* DFLTCC_CC_OP1_TOO_SHORT without buffering header bits, but we will still
|
||||
* set BCF=1, which is wrong. Avoid complications and return early.
|
||||
*/
|
||||
if (strm->avail_out == 0) {
|
||||
*result = need_more;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* The caller gave us too much data. Pass only one block worth of
|
||||
* uncompressed data to DFLTCC and mask the rest, so that on the next
|
||||
* iteration we start a new block.
|
||||
@ -189,7 +220,7 @@ again:
|
||||
param->cvt = CVT_ADLER32;
|
||||
if (!no_flush)
|
||||
/* We need to close a block. Always do this in software - when there is
|
||||
* no input data, the hardware will not nohor BCC. */
|
||||
* no input data, the hardware will not hohor BCC. */
|
||||
soft_bcc = 1;
|
||||
if (flush == Z_FINISH && !param->bcf)
|
||||
/* We are about to open a BFINAL block, set Block Header Final bit
|
||||
@ -204,8 +235,8 @@ again:
|
||||
param->sbb = (unsigned int)state->bi_valid;
|
||||
if (param->sbb > 0)
|
||||
*strm->next_out = (Byte)state->bi_buf;
|
||||
if (param->hl)
|
||||
param->nt = 0; /* Honor history */
|
||||
/* Honor history and check value */
|
||||
param->nt = 0;
|
||||
param->cv = strm->adler;
|
||||
|
||||
/* When opening a block, choose a Huffman-Table Type */
|
||||
@ -232,7 +263,7 @@ again:
|
||||
} while (cc == DFLTCC_CC_AGAIN);
|
||||
|
||||
/* Translate parameter block to stream */
|
||||
strm->msg = oesc_msg(dfltcc_state->msg, param->oesc);
|
||||
strm->msg = oesc_msg(dfltcc_state->common.msg, param->oesc);
|
||||
state->bi_valid = param->sbb;
|
||||
if (state->bi_valid == 0)
|
||||
state->bi_buf = 0; /* Avoid accessing next_out */
|
||||
|
21
lib/zlib_dfltcc/dfltcc_deflate.h
Normal file
21
lib/zlib_dfltcc/dfltcc_deflate.h
Normal file
@ -0,0 +1,21 @@
|
||||
// SPDX-License-Identifier: Zlib
|
||||
#ifndef DFLTCC_DEFLATE_H
|
||||
#define DFLTCC_DEFLATE_H
|
||||
|
||||
#include "dfltcc.h"
|
||||
|
||||
/* External functions */
|
||||
int dfltcc_can_deflate(z_streamp strm);
|
||||
int dfltcc_deflate(z_streamp strm,
|
||||
int flush,
|
||||
block_state *result);
|
||||
void dfltcc_reset_deflate_state(z_streamp strm);
|
||||
|
||||
#define DEFLATE_RESET_HOOK(strm) \
|
||||
dfltcc_reset_deflate_state((strm))
|
||||
|
||||
#define DEFLATE_HOOK dfltcc_deflate
|
||||
|
||||
#define DEFLATE_NEED_CHECKSUM(strm) (!dfltcc_can_deflate((strm)))
|
||||
|
||||
#endif /* DFLTCC_DEFLATE_H */
|
@ -2,7 +2,7 @@
|
||||
|
||||
#include "../zlib_inflate/inflate.h"
|
||||
#include "dfltcc_util.h"
|
||||
#include "dfltcc.h"
|
||||
#include "dfltcc_inflate.h"
|
||||
#include <asm/setup.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/zutil.h>
|
||||
@ -22,16 +22,20 @@ int dfltcc_can_inflate(
|
||||
zlib_dfltcc_support == ZLIB_DFLTCC_DEFLATE_ONLY)
|
||||
return 0;
|
||||
|
||||
/* Unsupported compression settings */
|
||||
if (state->wbits != HB_BITS)
|
||||
return 0;
|
||||
|
||||
/* Unsupported hardware */
|
||||
return is_bit_set(dfltcc_state->af.fns, DFLTCC_XPND) &&
|
||||
is_bit_set(dfltcc_state->af.fmts, DFLTCC_FMT0);
|
||||
}
|
||||
EXPORT_SYMBOL(dfltcc_can_inflate);
|
||||
|
||||
void dfltcc_reset_inflate_state(z_streamp strm) {
|
||||
struct inflate_state *state = (struct inflate_state *)strm->state;
|
||||
struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state);
|
||||
|
||||
dfltcc_reset_state(dfltcc_state);
|
||||
}
|
||||
EXPORT_SYMBOL(dfltcc_reset_inflate_state);
|
||||
|
||||
static int dfltcc_was_inflate_used(
|
||||
z_streamp strm
|
||||
)
|
||||
@ -91,8 +95,10 @@ dfltcc_inflate_action dfltcc_inflate(
|
||||
struct dfltcc_param_v0 *param = &dfltcc_state->param;
|
||||
dfltcc_cc cc;
|
||||
|
||||
if (flush == Z_BLOCK) {
|
||||
/* DFLTCC does not support stopping on block boundaries */
|
||||
if (flush == Z_BLOCK || flush == Z_PACKET_FLUSH) {
|
||||
/* DFLTCC does not support stopping on block boundaries (Z_BLOCK flush option)
|
||||
* as well as the use of Z_PACKET_FLUSH option (used exclusively by PPP driver)
|
||||
*/
|
||||
if (dfltcc_inflate_disable(strm)) {
|
||||
*ret = Z_STREAM_ERROR;
|
||||
return DFLTCC_INFLATE_BREAK;
|
||||
@ -121,8 +127,6 @@ dfltcc_inflate_action dfltcc_inflate(
|
||||
/* Translate stream to parameter block */
|
||||
param->cvt = CVT_ADLER32;
|
||||
param->sbb = state->bits;
|
||||
param->hl = state->whave; /* Software and hardware history formats match */
|
||||
param->ho = (state->write - state->whave) & ((1 << HB_BITS) - 1);
|
||||
if (param->hl)
|
||||
param->nt = 0; /* Honor history for the first block */
|
||||
param->cv = state->check;
|
||||
@ -136,8 +140,6 @@ dfltcc_inflate_action dfltcc_inflate(
|
||||
strm->msg = oesc_msg(dfltcc_state->msg, param->oesc);
|
||||
state->last = cc == DFLTCC_CC_OK;
|
||||
state->bits = param->sbb;
|
||||
state->whave = param->hl;
|
||||
state->write = (param->ho + param->hl) & ((1 << HB_BITS) - 1);
|
||||
state->check = param->cv;
|
||||
if (cc == DFLTCC_CC_OP2_CORRUPT && param->oesc != 0) {
|
||||
/* Report an error if stream is corrupted */
|
||||
|
37
lib/zlib_dfltcc/dfltcc_inflate.h
Normal file
37
lib/zlib_dfltcc/dfltcc_inflate.h
Normal file
@ -0,0 +1,37 @@
|
||||
// SPDX-License-Identifier: Zlib
|
||||
#ifndef DFLTCC_INFLATE_H
|
||||
#define DFLTCC_INFLATE_H
|
||||
|
||||
#include "dfltcc.h"
|
||||
|
||||
/* External functions */
|
||||
void dfltcc_reset_inflate_state(z_streamp strm);
|
||||
int dfltcc_can_inflate(z_streamp strm);
|
||||
typedef enum {
|
||||
DFLTCC_INFLATE_CONTINUE,
|
||||
DFLTCC_INFLATE_BREAK,
|
||||
DFLTCC_INFLATE_SOFTWARE,
|
||||
} dfltcc_inflate_action;
|
||||
dfltcc_inflate_action dfltcc_inflate(z_streamp strm,
|
||||
int flush, int *ret);
|
||||
#define INFLATE_RESET_HOOK(strm) \
|
||||
dfltcc_reset_inflate_state((strm))
|
||||
|
||||
#define INFLATE_TYPEDO_HOOK(strm, flush) \
|
||||
if (dfltcc_can_inflate((strm))) { \
|
||||
dfltcc_inflate_action action; \
|
||||
\
|
||||
RESTORE(); \
|
||||
action = dfltcc_inflate((strm), (flush), &ret); \
|
||||
LOAD(); \
|
||||
if (action == DFLTCC_INFLATE_CONTINUE) \
|
||||
break; \
|
||||
else if (action == DFLTCC_INFLATE_BREAK) \
|
||||
goto inf_leave; \
|
||||
}
|
||||
|
||||
#define INFLATE_NEED_CHECKSUM(strm) (!dfltcc_can_inflate((strm)))
|
||||
|
||||
#define INFLATE_NEED_UPDATEWINDOW(strm) (!dfltcc_can_inflate((strm)))
|
||||
|
||||
#endif /* DFLTCC_DEFLATE_H */
|
@ -17,7 +17,7 @@
|
||||
|
||||
/* architecture-specific bits */
|
||||
#ifdef CONFIG_ZLIB_DFLTCC
|
||||
# include "../zlib_dfltcc/dfltcc.h"
|
||||
# include "../zlib_dfltcc/dfltcc_inflate.h"
|
||||
#else
|
||||
#define INFLATE_RESET_HOOK(strm) do {} while (0)
|
||||
#define INFLATE_TYPEDO_HOOK(strm, flush) do {} while (0)
|
||||
|
@ -1013,7 +1013,7 @@ static int flow_mask_insert(struct flow_table *tbl, struct sw_flow *flow,
|
||||
|
||||
mask = flow_mask_find(tbl, new);
|
||||
if (!mask) {
|
||||
/* Allocate a new mask if none exsits. */
|
||||
/* Allocate a new mask if none exists. */
|
||||
mask = mask_alloc();
|
||||
if (!mask)
|
||||
return -ENOMEM;
|
||||
|
@ -80,8 +80,7 @@ def calc(oldfile, newfile, format):
|
||||
if d<0: shrink, down = shrink+1, down-d
|
||||
delta.append((d, name))
|
||||
|
||||
delta.sort()
|
||||
delta.reverse()
|
||||
delta.sort(reverse=True)
|
||||
return grow, shrink, add, remove, up, down, delta, old, new, otot, ntot
|
||||
|
||||
def print_result(symboltype, symbolformat):
|
||||
|
@ -823,7 +823,9 @@ our %deprecated_apis = (
|
||||
"get_state_synchronize_sched" => "get_state_synchronize_rcu",
|
||||
"cond_synchronize_sched" => "cond_synchronize_rcu",
|
||||
"kmap" => "kmap_local_page",
|
||||
"kunmap" => "kunmap_local",
|
||||
"kmap_atomic" => "kmap_local_page",
|
||||
"kunmap_atomic" => "kunmap_local",
|
||||
);
|
||||
|
||||
#Create a search pattern for all these strings to speed up a loop below
|
||||
@ -3142,21 +3144,33 @@ sub process {
|
||||
if ($sign_off =~ /^co-developed-by:$/i) {
|
||||
if ($email eq $author) {
|
||||
WARN("BAD_SIGN_OFF",
|
||||
"Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline);
|
||||
"Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . $herecurr);
|
||||
}
|
||||
if (!defined $lines[$linenr]) {
|
||||
WARN("BAD_SIGN_OFF",
|
||||
"Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline);
|
||||
} elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) {
|
||||
"Co-developed-by: must be immediately followed by Signed-off-by:\n" . $herecurr);
|
||||
} elsif ($rawlines[$linenr] !~ /^signed-off-by:\s*(.*)/i) {
|
||||
WARN("BAD_SIGN_OFF",
|
||||
"Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
|
||||
"Co-developed-by: must be immediately followed by Signed-off-by:\n" . $herecurr . $rawlines[$linenr] . "\n");
|
||||
} elsif ($1 ne $email) {
|
||||
WARN("BAD_SIGN_OFF",
|
||||
"Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
|
||||
"Co-developed-by and Signed-off-by: name/email do not match\n" . $herecurr . $rawlines[$linenr] . "\n");
|
||||
}
|
||||
}
|
||||
|
||||
# check if Reported-by: is followed by a Link:
|
||||
if ($sign_off =~ /^reported(?:|-and-tested)-by:$/i) {
|
||||
if (!defined $lines[$linenr]) {
|
||||
WARN("BAD_REPORTED_BY_LINK",
|
||||
"Reported-by: should be immediately followed by Link: to the report\n" . $herecurr . $rawlines[$linenr] . "\n");
|
||||
} elsif ($rawlines[$linenr] !~ m{^link:\s*https?://}i) {
|
||||
WARN("BAD_REPORTED_BY_LINK",
|
||||
"Reported-by: should be immediately followed by Link: with a URL to the report\n" . $herecurr . $rawlines[$linenr] . "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Check Fixes: styles is correct
|
||||
if (!$in_header_lines &&
|
||||
$line =~ /^\s*fixes:?\s*(?:commit\s*)?[0-9a-f]{5,}\b/i) {
|
||||
@ -3250,6 +3264,18 @@ sub process {
|
||||
$commit_log_possible_stack_dump = 0;
|
||||
}
|
||||
|
||||
# Check for odd tags before a URI/URL
|
||||
if ($in_commit_log &&
|
||||
$line =~ /^\s*(\w+):\s*http/ && $1 ne 'Link') {
|
||||
if ($1 =~ /^v(?:ersion)?\d+/i) {
|
||||
WARN("COMMIT_LOG_VERSIONING",
|
||||
"Patch version information should be after the --- line\n" . $herecurr);
|
||||
} else {
|
||||
WARN("COMMIT_LOG_USE_LINK",
|
||||
"Unknown link reference '$1:', use 'Link:' instead\n" . $herecurr);
|
||||
}
|
||||
}
|
||||
|
||||
# Check for lines starting with a #
|
||||
if ($in_commit_log && $line =~ /^#/) {
|
||||
if (WARN("COMMIT_COMMENT_SYMBOL",
|
||||
@ -3725,7 +3751,7 @@ sub process {
|
||||
}
|
||||
|
||||
# check for embedded filenames
|
||||
if ($rawline =~ /^\+.*\Q$realfile\E/) {
|
||||
if ($rawline =~ /^\+.*\b\Q$realfile\E\b/) {
|
||||
WARN("EMBEDDED_FILENAME",
|
||||
"It's generally not useful to have the filename in the file\n" . $herecurr);
|
||||
}
|
||||
|
222
scripts/gdb/linux/mm.py
Normal file
222
scripts/gdb/linux/mm.py
Normal file
@ -0,0 +1,222 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# gdb helper commands and functions for Linux kernel debugging
|
||||
#
|
||||
# routines to introspect page table
|
||||
#
|
||||
# Authors:
|
||||
# Dmitrii Bundin <dmitrii.bundin.a@gmail.com>
|
||||
#
|
||||
|
||||
import gdb
|
||||
|
||||
from linux import utils
|
||||
|
||||
PHYSICAL_ADDRESS_MASK = gdb.parse_and_eval('0xfffffffffffff')
|
||||
|
||||
|
||||
def page_mask(level=1):
|
||||
# 4KB
|
||||
if level == 1:
|
||||
return gdb.parse_and_eval('(u64) ~0xfff')
|
||||
# 2MB
|
||||
elif level == 2:
|
||||
return gdb.parse_and_eval('(u64) ~0x1fffff')
|
||||
# 1GB
|
||||
elif level == 3:
|
||||
return gdb.parse_and_eval('(u64) ~0x3fffffff')
|
||||
else:
|
||||
raise Exception(f'Unknown page level: {level}')
|
||||
|
||||
|
||||
#page_offset_base in case CONFIG_DYNAMIC_MEMORY_LAYOUT is disabled
|
||||
POB_NO_DYNAMIC_MEM_LAYOUT = '0xffff888000000000'
|
||||
def _page_offset_base():
|
||||
pob_symbol = gdb.lookup_global_symbol('page_offset_base')
|
||||
pob = pob_symbol.name if pob_symbol else POB_NO_DYNAMIC_MEM_LAYOUT
|
||||
return gdb.parse_and_eval(pob)
|
||||
|
||||
|
||||
def is_bit_defined_tupled(data, offset):
|
||||
return offset, bool(data >> offset & 1)
|
||||
|
||||
def content_tupled(data, bit_start, bit_end):
|
||||
return (bit_start, bit_end), data >> bit_start & ((1 << (1 + bit_end - bit_start)) - 1)
|
||||
|
||||
def entry_va(level, phys_addr, translating_va):
|
||||
def start_bit(level):
|
||||
if level == 5:
|
||||
return 48
|
||||
elif level == 4:
|
||||
return 39
|
||||
elif level == 3:
|
||||
return 30
|
||||
elif level == 2:
|
||||
return 21
|
||||
elif level == 1:
|
||||
return 12
|
||||
else:
|
||||
raise Exception(f'Unknown level {level}')
|
||||
|
||||
entry_offset = ((translating_va >> start_bit(level)) & 511) * 8
|
||||
entry_va = _page_offset_base() + phys_addr + entry_offset
|
||||
return entry_va
|
||||
|
||||
class Cr3():
|
||||
def __init__(self, cr3, page_levels):
|
||||
self.cr3 = cr3
|
||||
self.page_levels = page_levels
|
||||
self.page_level_write_through = is_bit_defined_tupled(cr3, 3)
|
||||
self.page_level_cache_disabled = is_bit_defined_tupled(cr3, 4)
|
||||
self.next_entry_physical_address = cr3 & PHYSICAL_ADDRESS_MASK & page_mask()
|
||||
|
||||
def next_entry(self, va):
|
||||
next_level = self.page_levels
|
||||
return PageHierarchyEntry(entry_va(next_level, self.next_entry_physical_address, va), next_level)
|
||||
|
||||
def mk_string(self):
|
||||
return f"""\
|
||||
cr3:
|
||||
{'cr3 binary data': <30} {hex(self.cr3)}
|
||||
{'next entry physical address': <30} {hex(self.next_entry_physical_address)}
|
||||
---
|
||||
{'bit' : <4} {self.page_level_write_through[0]: <10} {'page level write through': <30} {self.page_level_write_through[1]}
|
||||
{'bit' : <4} {self.page_level_cache_disabled[0]: <10} {'page level cache disabled': <30} {self.page_level_cache_disabled[1]}
|
||||
"""
|
||||
|
||||
|
||||
class PageHierarchyEntry():
|
||||
def __init__(self, address, level):
|
||||
data = int.from_bytes(
|
||||
memoryview(gdb.selected_inferior().read_memory(address, 8)),
|
||||
"little"
|
||||
)
|
||||
if level == 1:
|
||||
self.is_page = True
|
||||
self.entry_present = is_bit_defined_tupled(data, 0)
|
||||
self.read_write = is_bit_defined_tupled(data, 1)
|
||||
self.user_access_allowed = is_bit_defined_tupled(data, 2)
|
||||
self.page_level_write_through = is_bit_defined_tupled(data, 3)
|
||||
self.page_level_cache_disabled = is_bit_defined_tupled(data, 4)
|
||||
self.entry_was_accessed = is_bit_defined_tupled(data, 5)
|
||||
self.dirty = is_bit_defined_tupled(data, 6)
|
||||
self.pat = is_bit_defined_tupled(data, 7)
|
||||
self.global_translation = is_bit_defined_tupled(data, 8)
|
||||
self.page_physical_address = data & PHYSICAL_ADDRESS_MASK & page_mask(level)
|
||||
self.next_entry_physical_address = None
|
||||
self.hlat_restart_with_ordinary = is_bit_defined_tupled(data, 11)
|
||||
self.protection_key = content_tupled(data, 59, 62)
|
||||
self.executed_disable = is_bit_defined_tupled(data, 63)
|
||||
else:
|
||||
page_size = is_bit_defined_tupled(data, 7)
|
||||
page_size_bit = page_size[1]
|
||||
self.is_page = page_size_bit
|
||||
self.entry_present = is_bit_defined_tupled(data, 0)
|
||||
self.read_write = is_bit_defined_tupled(data, 1)
|
||||
self.user_access_allowed = is_bit_defined_tupled(data, 2)
|
||||
self.page_level_write_through = is_bit_defined_tupled(data, 3)
|
||||
self.page_level_cache_disabled = is_bit_defined_tupled(data, 4)
|
||||
self.entry_was_accessed = is_bit_defined_tupled(data, 5)
|
||||
self.page_size = page_size
|
||||
self.dirty = is_bit_defined_tupled(
|
||||
data, 6) if page_size_bit else None
|
||||
self.global_translation = is_bit_defined_tupled(
|
||||
data, 8) if page_size_bit else None
|
||||
self.pat = is_bit_defined_tupled(
|
||||
data, 12) if page_size_bit else None
|
||||
self.page_physical_address = data & PHYSICAL_ADDRESS_MASK & page_mask(level) if page_size_bit else None
|
||||
self.next_entry_physical_address = None if page_size_bit else data & PHYSICAL_ADDRESS_MASK & page_mask()
|
||||
self.hlat_restart_with_ordinary = is_bit_defined_tupled(data, 11)
|
||||
self.protection_key = content_tupled(data, 59, 62) if page_size_bit else None
|
||||
self.executed_disable = is_bit_defined_tupled(data, 63)
|
||||
self.address = address
|
||||
self.page_entry_binary_data = data
|
||||
self.page_hierarchy_level = level
|
||||
|
||||
def next_entry(self, va):
|
||||
if self.is_page or not self.entry_present[1]:
|
||||
return None
|
||||
|
||||
next_level = self.page_hierarchy_level - 1
|
||||
return PageHierarchyEntry(entry_va(next_level, self.next_entry_physical_address, va), next_level)
|
||||
|
||||
|
||||
def mk_string(self):
|
||||
if not self.entry_present[1]:
|
||||
return f"""\
|
||||
level {self.page_hierarchy_level}:
|
||||
{'entry address': <30} {hex(self.address)}
|
||||
{'page entry binary data': <30} {hex(self.page_entry_binary_data)}
|
||||
---
|
||||
PAGE ENTRY IS NOT PRESENT!
|
||||
"""
|
||||
elif self.is_page:
|
||||
def page_size_line(ps_bit, ps, level):
|
||||
return "" if level == 1 else f"{'bit': <3} {ps_bit: <5} {'page size': <30} {ps}"
|
||||
|
||||
return f"""\
|
||||
level {self.page_hierarchy_level}:
|
||||
{'entry address': <30} {hex(self.address)}
|
||||
{'page entry binary data': <30} {hex(self.page_entry_binary_data)}
|
||||
{'page size': <30} {'1GB' if self.page_hierarchy_level == 3 else '2MB' if self.page_hierarchy_level == 2 else '4KB' if self.page_hierarchy_level == 1 else 'Unknown page size for level:' + self.page_hierarchy_level}
|
||||
{'page physical address': <30} {hex(self.page_physical_address)}
|
||||
---
|
||||
{'bit': <4} {self.entry_present[0]: <10} {'entry present': <30} {self.entry_present[1]}
|
||||
{'bit': <4} {self.read_write[0]: <10} {'read/write access allowed': <30} {self.read_write[1]}
|
||||
{'bit': <4} {self.user_access_allowed[0]: <10} {'user access allowed': <30} {self.user_access_allowed[1]}
|
||||
{'bit': <4} {self.page_level_write_through[0]: <10} {'page level write through': <30} {self.page_level_write_through[1]}
|
||||
{'bit': <4} {self.page_level_cache_disabled[0]: <10} {'page level cache disabled': <30} {self.page_level_cache_disabled[1]}
|
||||
{'bit': <4} {self.entry_was_accessed[0]: <10} {'entry has been accessed': <30} {self.entry_was_accessed[1]}
|
||||
{"" if self.page_hierarchy_level == 1 else f"{'bit': <4} {self.page_size[0]: <10} {'page size': <30} {self.page_size[1]}"}
|
||||
{'bit': <4} {self.dirty[0]: <10} {'page dirty': <30} {self.dirty[1]}
|
||||
{'bit': <4} {self.global_translation[0]: <10} {'global translation': <30} {self.global_translation[1]}
|
||||
{'bit': <4} {self.hlat_restart_with_ordinary[0]: <10} {'restart to ordinary': <30} {self.hlat_restart_with_ordinary[1]}
|
||||
{'bit': <4} {self.pat[0]: <10} {'pat': <30} {self.pat[1]}
|
||||
{'bits': <4} {str(self.protection_key[0]): <10} {'protection key': <30} {self.protection_key[1]}
|
||||
{'bit': <4} {self.executed_disable[0]: <10} {'execute disable': <30} {self.executed_disable[1]}
|
||||
"""
|
||||
else:
|
||||
return f"""\
|
||||
level {self.page_hierarchy_level}:
|
||||
{'entry address': <30} {hex(self.address)}
|
||||
{'page entry binary data': <30} {hex(self.page_entry_binary_data)}
|
||||
{'next entry physical address': <30} {hex(self.next_entry_physical_address)}
|
||||
---
|
||||
{'bit': <4} {self.entry_present[0]: <10} {'entry present': <30} {self.entry_present[1]}
|
||||
{'bit': <4} {self.read_write[0]: <10} {'read/write access allowed': <30} {self.read_write[1]}
|
||||
{'bit': <4} {self.user_access_allowed[0]: <10} {'user access allowed': <30} {self.user_access_allowed[1]}
|
||||
{'bit': <4} {self.page_level_write_through[0]: <10} {'page level write through': <30} {self.page_level_write_through[1]}
|
||||
{'bit': <4} {self.page_level_cache_disabled[0]: <10} {'page level cache disabled': <30} {self.page_level_cache_disabled[1]}
|
||||
{'bit': <4} {self.entry_was_accessed[0]: <10} {'entry has been accessed': <30} {self.entry_was_accessed[1]}
|
||||
{'bit': <4} {self.page_size[0]: <10} {'page size': <30} {self.page_size[1]}
|
||||
{'bit': <4} {self.hlat_restart_with_ordinary[0]: <10} {'restart to ordinary': <30} {self.hlat_restart_with_ordinary[1]}
|
||||
{'bit': <4} {self.executed_disable[0]: <10} {'execute disable': <30} {self.executed_disable[1]}
|
||||
"""
|
||||
|
||||
|
||||
class TranslateVM(gdb.Command):
|
||||
"""Prints the entire paging structure used to translate a given virtual address.
|
||||
|
||||
Having an address space of the currently executed process translates the virtual address
|
||||
and prints detailed information of all paging structure levels used for the transaltion.
|
||||
Currently supported arch: x86"""
|
||||
|
||||
def __init__(self):
|
||||
super(TranslateVM, self).__init__('translate-vm', gdb.COMMAND_USER)
|
||||
|
||||
def invoke(self, arg, from_tty):
|
||||
if utils.is_target_arch("x86"):
|
||||
vm_address = gdb.parse_and_eval(f'{arg}')
|
||||
cr3_data = gdb.parse_and_eval('$cr3')
|
||||
cr4 = gdb.parse_and_eval('$cr4')
|
||||
page_levels = 5 if cr4 & (1 << 12) else 4
|
||||
page_entry = Cr3(cr3_data, page_levels)
|
||||
while page_entry:
|
||||
gdb.write(page_entry.mk_string())
|
||||
page_entry = page_entry.next_entry(vm_address)
|
||||
else:
|
||||
gdb.GdbError("Virtual address translation is not"
|
||||
"supported for this arch")
|
||||
|
||||
|
||||
TranslateVM()
|
@ -37,3 +37,4 @@ else:
|
||||
import linux.clk
|
||||
import linux.genpd
|
||||
import linux.device
|
||||
import linux.mm
|
||||
|
@ -65,6 +65,7 @@ acumulative||accumulative
|
||||
acumulator||accumulator
|
||||
acutally||actually
|
||||
adapater||adapter
|
||||
adderted||asserted
|
||||
addional||additional
|
||||
additionaly||additionally
|
||||
additonal||additional
|
||||
@ -122,6 +123,7 @@ alue||value
|
||||
ambigious||ambiguous
|
||||
ambigous||ambiguous
|
||||
amoung||among
|
||||
amount of times||number of times
|
||||
amout||amount
|
||||
amplifer||amplifier
|
||||
amplifyer||amplifier
|
||||
@ -287,6 +289,7 @@ capapbilities||capabilities
|
||||
caputure||capture
|
||||
carefuly||carefully
|
||||
cariage||carriage
|
||||
casued||caused
|
||||
catagory||category
|
||||
cehck||check
|
||||
challange||challenge
|
||||
@ -370,6 +373,7 @@ conbination||combination
|
||||
conditionaly||conditionally
|
||||
conditon||condition
|
||||
condtion||condition
|
||||
condtional||conditional
|
||||
conected||connected
|
||||
conector||connector
|
||||
configration||configuration
|
||||
@ -423,6 +427,7 @@ cound||could
|
||||
couter||counter
|
||||
coutner||counter
|
||||
cryptocraphic||cryptographic
|
||||
cummulative||cumulative
|
||||
cunter||counter
|
||||
curently||currently
|
||||
cylic||cyclic
|
||||
@ -625,8 +630,10 @@ exeuction||execution
|
||||
existance||existence
|
||||
existant||existent
|
||||
exixt||exist
|
||||
exsits||exists
|
||||
exlcude||exclude
|
||||
exlcusive||exclusive
|
||||
exlusive||exclusive
|
||||
exmaple||example
|
||||
expecially||especially
|
||||
experies||expires
|
||||
@ -664,11 +671,13 @@ feauture||feature
|
||||
feautures||features
|
||||
fetaure||feature
|
||||
fetaures||features
|
||||
fetcing||fetching
|
||||
fileystem||filesystem
|
||||
fimrware||firmware
|
||||
fimware||firmware
|
||||
firmare||firmware
|
||||
firmaware||firmware
|
||||
firtly||firstly
|
||||
firware||firmware
|
||||
firwmare||firmware
|
||||
finanize||finalize
|
||||
@ -838,6 +847,7 @@ integrety||integrity
|
||||
integrey||integrity
|
||||
intendet||intended
|
||||
intented||intended
|
||||
interal||internal
|
||||
interanl||internal
|
||||
interchangable||interchangeable
|
||||
interferring||interfering
|
||||
@ -1023,6 +1033,7 @@ negotation||negotiation
|
||||
nerver||never
|
||||
nescessary||necessary
|
||||
nessessary||necessary
|
||||
none existent||non-existent
|
||||
noticable||noticeable
|
||||
notication||notification
|
||||
notications||notifications
|
||||
@ -1044,6 +1055,7 @@ occured||occurred
|
||||
occurence||occurrence
|
||||
occure||occurred
|
||||
occuring||occurring
|
||||
ocurrence||occurrence
|
||||
offser||offset
|
||||
offet||offset
|
||||
offlaod||offload
|
||||
@ -1055,6 +1067,7 @@ omitt||omit
|
||||
ommiting||omitting
|
||||
ommitted||omitted
|
||||
onself||oneself
|
||||
onthe||on the
|
||||
ony||only
|
||||
openning||opening
|
||||
operatione||operation
|
||||
@ -1121,6 +1134,7 @@ perfomring||performing
|
||||
periperal||peripheral
|
||||
peripherial||peripheral
|
||||
permissons||permissions
|
||||
permited||permitted
|
||||
peroid||period
|
||||
persistance||persistence
|
||||
persistant||persistent
|
||||
@ -1334,6 +1348,7 @@ sacrifying||sacrificing
|
||||
safly||safely
|
||||
safty||safety
|
||||
satify||satisfy
|
||||
satisifed||satisfied
|
||||
savable||saveable
|
||||
scaleing||scaling
|
||||
scaned||scanned
|
||||
@ -1558,6 +1573,7 @@ tunning||tuning
|
||||
ture||true
|
||||
tyep||type
|
||||
udpate||update
|
||||
updtes||updates
|
||||
uesd||used
|
||||
unknwon||unknown
|
||||
uknown||unknown
|
||||
@ -1614,6 +1630,7 @@ unuseful||useless
|
||||
unvalid||invalid
|
||||
upate||update
|
||||
upsupported||unsupported
|
||||
upto||up to
|
||||
useable||usable
|
||||
usefule||useful
|
||||
usefull||useful
|
||||
|
@ -264,10 +264,12 @@ exuberant()
|
||||
--$CTAGS_EXTRA=+fq --c-kinds=+px --fields=+iaS --langmap=c:+.h \
|
||||
"${regex[@]}"
|
||||
|
||||
setup_regex exuberant kconfig
|
||||
all_kconfigs | xargs $1 -a \
|
||||
--langdef=kconfig --language-force=kconfig "${regex[@]}"
|
||||
|
||||
KCONFIG_ARGS=()
|
||||
if ! $1 --list-languages | grep -iq kconfig; then
|
||||
setup_regex exuberant kconfig
|
||||
KCONFIG_ARGS=(--langdef=kconfig --language-force=kconfig "${regex[@]}")
|
||||
fi
|
||||
all_kconfigs | xargs $1 -a "${KCONFIG_ARGS[@]}"
|
||||
}
|
||||
|
||||
emacs()
|
||||
|
@ -811,7 +811,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
|
||||
priv->card.num_links = 1;
|
||||
|
||||
if (asrc_pdev) {
|
||||
/* DPCM DAI Links only if ASRC exsits */
|
||||
/* DPCM DAI Links only if ASRC exists */
|
||||
priv->dai_link[1].cpus->of_node = asrc_np;
|
||||
priv->dai_link[1].platforms->of_node = asrc_np;
|
||||
priv->dai_link[2].codecs->dai_name = codec_dai_name;
|
||||
|
Loading…
Reference in New Issue
Block a user