mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 04:02:20 +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
|
D: fbdev hacking
|
||||||
|
|
||||||
N: Jesper Juhl
|
N: Jesper Juhl
|
||||||
E: jj@chaosbits.net
|
E: jesperjuhl76@gmail.com
|
||||||
D: Various fixes, cleanups and minor features all over the tree.
|
D: Various fixes, cleanups and minor features all over the tree.
|
||||||
D: Wrote initial version of the hdaps driver (since passed on to others).
|
D: Wrote initial version of the hdaps driver (since passed on to others).
|
||||||
S: Lemnosvej 1, 3.tv
|
S: Titangade 5G, 2.tv
|
||||||
S: 2300 Copenhagen S.
|
S: 2200 Copenhagen N.
|
||||||
S: Denmark
|
S: Denmark
|
||||||
|
|
||||||
N: Jozsef Kadlecsik
|
N: Jozsef Kadlecsik
|
||||||
|
@ -453,9 +453,10 @@ this allows system administrators to override the
|
|||||||
kexec_load_disabled
|
kexec_load_disabled
|
||||||
===================
|
===================
|
||||||
|
|
||||||
A toggle indicating if the ``kexec_load`` syscall has been disabled.
|
A toggle indicating if the syscalls ``kexec_load`` and
|
||||||
This value defaults to 0 (false: ``kexec_load`` enabled), but can be
|
``kexec_file_load`` have been disabled.
|
||||||
set to 1 (true: ``kexec_load`` 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
|
Once true, kexec can no longer be used, and the toggle cannot be set
|
||||||
back to false.
|
back to false.
|
||||||
This allows a kexec image to be loaded before disabling the syscall,
|
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.
|
altered.
|
||||||
Generally used together with the `modules_disabled`_ sysctl.
|
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
|
kptr_restrict
|
||||||
=============
|
=============
|
||||||
|
@ -231,6 +231,71 @@ proc entries
|
|||||||
This feature is intended for systematic testing of faults in a single
|
This feature is intended for systematic testing of faults in a single
|
||||||
system call. See an example below.
|
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
|
How to add new fault injection capability
|
||||||
-----------------------------------------
|
-----------------------------------------
|
||||||
|
|
||||||
|
128
arch/Kconfig
128
arch/Kconfig
@ -35,7 +35,7 @@ config HOTPLUG_SMT
|
|||||||
bool
|
bool
|
||||||
|
|
||||||
config GENERIC_ENTRY
|
config GENERIC_ENTRY
|
||||||
bool
|
bool
|
||||||
|
|
||||||
config KPROBES
|
config KPROBES
|
||||||
bool "Kprobes"
|
bool "Kprobes"
|
||||||
@ -55,26 +55,26 @@ config JUMP_LABEL
|
|||||||
depends on HAVE_ARCH_JUMP_LABEL
|
depends on HAVE_ARCH_JUMP_LABEL
|
||||||
select OBJTOOL if HAVE_JUMP_LABEL_HACK
|
select OBJTOOL if HAVE_JUMP_LABEL_HACK
|
||||||
help
|
help
|
||||||
This option enables a transparent branch optimization that
|
This option enables a transparent branch optimization that
|
||||||
makes certain almost-always-true or almost-always-false branch
|
makes certain almost-always-true or almost-always-false branch
|
||||||
conditions even cheaper to execute within the kernel.
|
conditions even cheaper to execute within the kernel.
|
||||||
|
|
||||||
Certain performance-sensitive kernel code, such as trace points,
|
Certain performance-sensitive kernel code, such as trace points,
|
||||||
scheduler functionality, networking code and KVM have such
|
scheduler functionality, networking code and KVM have such
|
||||||
branches and include support for this optimization technique.
|
branches and include support for this optimization technique.
|
||||||
|
|
||||||
If it is detected that the compiler has support for "asm goto",
|
If it is detected that the compiler has support for "asm goto",
|
||||||
the kernel will compile such branches with just a nop
|
the kernel will compile such branches with just a nop
|
||||||
instruction. When the condition flag is toggled to true, the
|
instruction. When the condition flag is toggled to true, the
|
||||||
nop will be converted to a jump instruction to execute the
|
nop will be converted to a jump instruction to execute the
|
||||||
conditional block of instructions.
|
conditional block of instructions.
|
||||||
|
|
||||||
This technique lowers overhead and stress on the branch prediction
|
This technique lowers overhead and stress on the branch prediction
|
||||||
of the processor and generally makes the kernel faster. The update
|
of the processor and generally makes the kernel faster. The update
|
||||||
of the condition is slower, but those are always very rare.
|
of the condition is slower, but those are always very rare.
|
||||||
|
|
||||||
( On 32-bit x86, the necessary options added to the compiler
|
( On 32-bit x86, the necessary options added to the compiler
|
||||||
flags may increase the size of the kernel slightly. )
|
flags may increase the size of the kernel slightly. )
|
||||||
|
|
||||||
config STATIC_KEYS_SELFTEST
|
config STATIC_KEYS_SELFTEST
|
||||||
bool "Static key selftest"
|
bool "Static key selftest"
|
||||||
@ -98,9 +98,9 @@ config KPROBES_ON_FTRACE
|
|||||||
depends on KPROBES && HAVE_KPROBES_ON_FTRACE
|
depends on KPROBES && HAVE_KPROBES_ON_FTRACE
|
||||||
depends on DYNAMIC_FTRACE_WITH_REGS
|
depends on DYNAMIC_FTRACE_WITH_REGS
|
||||||
help
|
help
|
||||||
If function tracer is enabled and the arch supports full
|
If function tracer is enabled and the arch supports full
|
||||||
passing of pt_regs to function tracing, then kprobes can
|
passing of pt_regs to function tracing, then kprobes can
|
||||||
optimize on top of function tracing.
|
optimize on top of function tracing.
|
||||||
|
|
||||||
config UPROBES
|
config UPROBES
|
||||||
def_bool n
|
def_bool n
|
||||||
@ -154,21 +154,21 @@ config HAVE_EFFICIENT_UNALIGNED_ACCESS
|
|||||||
config ARCH_USE_BUILTIN_BSWAP
|
config ARCH_USE_BUILTIN_BSWAP
|
||||||
bool
|
bool
|
||||||
help
|
help
|
||||||
Modern versions of GCC (since 4.4) have builtin functions
|
Modern versions of GCC (since 4.4) have builtin functions
|
||||||
for handling byte-swapping. Using these, instead of the old
|
for handling byte-swapping. Using these, instead of the old
|
||||||
inline assembler that the architecture code provides in the
|
inline assembler that the architecture code provides in the
|
||||||
__arch_bswapXX() macros, allows the compiler to see what's
|
__arch_bswapXX() macros, allows the compiler to see what's
|
||||||
happening and offers more opportunity for optimisation. In
|
happening and offers more opportunity for optimisation. In
|
||||||
particular, the compiler will be able to combine the byteswap
|
particular, the compiler will be able to combine the byteswap
|
||||||
with a nearby load or store and use load-and-swap or
|
with a nearby load or store and use load-and-swap or
|
||||||
store-and-swap instructions if the architecture has them. It
|
store-and-swap instructions if the architecture has them. It
|
||||||
should almost *never* result in code which is worse than the
|
should almost *never* result in code which is worse than the
|
||||||
hand-coded assembler in <asm/swab.h>. But just in case it
|
hand-coded assembler in <asm/swab.h>. But just in case it
|
||||||
does, the use of the builtins is optional.
|
does, the use of the builtins is optional.
|
||||||
|
|
||||||
Any architecture with load-and-swap or store-and-swap
|
Any architecture with load-and-swap or store-and-swap
|
||||||
instructions should set this. And it shouldn't hurt to set it
|
instructions should set this. And it shouldn't hurt to set it
|
||||||
on architectures that don't have such instructions.
|
on architectures that don't have such instructions.
|
||||||
|
|
||||||
config KRETPROBES
|
config KRETPROBES
|
||||||
def_bool y
|
def_bool y
|
||||||
@ -720,13 +720,13 @@ config LTO_CLANG_FULL
|
|||||||
depends on !COMPILE_TEST
|
depends on !COMPILE_TEST
|
||||||
select LTO_CLANG
|
select LTO_CLANG
|
||||||
help
|
help
|
||||||
This option enables Clang's full Link Time Optimization (LTO), which
|
This option enables Clang's full Link Time Optimization (LTO), which
|
||||||
allows the compiler to optimize the kernel globally. If you enable
|
allows the compiler to optimize the kernel globally. If you enable
|
||||||
this option, the compiler generates LLVM bitcode instead of ELF
|
this option, the compiler generates LLVM bitcode instead of ELF
|
||||||
object files, and the actual compilation from bitcode happens at
|
object files, and the actual compilation from bitcode happens at
|
||||||
the LTO link step, which may take several minutes depending on the
|
the LTO link step, which may take several minutes depending on the
|
||||||
kernel configuration. More information can be found from LLVM's
|
kernel configuration. More information can be found from LLVM's
|
||||||
documentation:
|
documentation:
|
||||||
|
|
||||||
https://llvm.org/docs/LinkTimeOptimization.html
|
https://llvm.org/docs/LinkTimeOptimization.html
|
||||||
|
|
||||||
@ -1330,9 +1330,9 @@ config ARCH_HAS_CC_PLATFORM
|
|||||||
bool
|
bool
|
||||||
|
|
||||||
config HAVE_SPARSE_SYSCALL_NR
|
config HAVE_SPARSE_SYSCALL_NR
|
||||||
bool
|
bool
|
||||||
help
|
help
|
||||||
An architecture should select this if its syscall numbering is sparse
|
An architecture should select this if its syscall numbering is sparse
|
||||||
to save space. For example, MIPS architecture has a syscall array with
|
to save space. For example, MIPS architecture has a syscall array with
|
||||||
entries at 4000, 5000 and 6000 locations. This option turns on syscall
|
entries at 4000, 5000 and 6000 locations. This option turns on syscall
|
||||||
related optimizations for a given architecture.
|
related optimizations for a given architecture.
|
||||||
@ -1356,35 +1356,35 @@ config HAVE_PREEMPT_DYNAMIC_CALL
|
|||||||
depends on HAVE_STATIC_CALL
|
depends on HAVE_STATIC_CALL
|
||||||
select HAVE_PREEMPT_DYNAMIC
|
select HAVE_PREEMPT_DYNAMIC
|
||||||
help
|
help
|
||||||
An architecture should select this if it can handle the preemption
|
An architecture should select this if it can handle the preemption
|
||||||
model being selected at boot time using static calls.
|
model being selected at boot time using static calls.
|
||||||
|
|
||||||
Where an architecture selects HAVE_STATIC_CALL_INLINE, any call to a
|
Where an architecture selects HAVE_STATIC_CALL_INLINE, any call to a
|
||||||
preemption function will be patched directly.
|
preemption function will be patched directly.
|
||||||
|
|
||||||
Where an architecture does not select HAVE_STATIC_CALL_INLINE, any
|
Where an architecture does not select HAVE_STATIC_CALL_INLINE, any
|
||||||
call to a preemption function will go through a trampoline, and the
|
call to a preemption function will go through a trampoline, and the
|
||||||
trampoline will be patched.
|
trampoline will be patched.
|
||||||
|
|
||||||
It is strongly advised to support inline static call to avoid any
|
It is strongly advised to support inline static call to avoid any
|
||||||
overhead.
|
overhead.
|
||||||
|
|
||||||
config HAVE_PREEMPT_DYNAMIC_KEY
|
config HAVE_PREEMPT_DYNAMIC_KEY
|
||||||
bool
|
bool
|
||||||
depends on HAVE_ARCH_JUMP_LABEL
|
depends on HAVE_ARCH_JUMP_LABEL
|
||||||
select HAVE_PREEMPT_DYNAMIC
|
select HAVE_PREEMPT_DYNAMIC
|
||||||
help
|
help
|
||||||
An architecture should select this if it can handle the preemption
|
An architecture should select this if it can handle the preemption
|
||||||
model being selected at boot time using static keys.
|
model being selected at boot time using static keys.
|
||||||
|
|
||||||
Each preemption function will be given an early return based on a
|
Each preemption function will be given an early return based on a
|
||||||
static key. This should have slightly lower overhead than non-inline
|
static key. This should have slightly lower overhead than non-inline
|
||||||
static calls, as this effectively inlines each trampoline into the
|
static calls, as this effectively inlines each trampoline into the
|
||||||
start of its callee. This may avoid redundant work, and may
|
start of its callee. This may avoid redundant work, and may
|
||||||
integrate better with CFI schemes.
|
integrate better with CFI schemes.
|
||||||
|
|
||||||
This will have greater overhead than using inline static calls as
|
This will have greater overhead than using inline static calls as
|
||||||
the call to the preemption function cannot be entirely elided.
|
the call to the preemption function cannot be entirely elided.
|
||||||
|
|
||||||
config ARCH_WANT_LD_ORPHAN_WARN
|
config ARCH_WANT_LD_ORPHAN_WARN
|
||||||
bool
|
bool
|
||||||
@ -1407,8 +1407,8 @@ config ARCH_SUPPORTS_PAGE_TABLE_CHECK
|
|||||||
config ARCH_SPLIT_ARG64
|
config ARCH_SPLIT_ARG64
|
||||||
bool
|
bool
|
||||||
help
|
help
|
||||||
If a 32-bit architecture requires 64-bit arguments to be split into
|
If a 32-bit architecture requires 64-bit arguments to be split into
|
||||||
pairs of 32-bit arguments, select this option.
|
pairs of 32-bit arguments, select this option.
|
||||||
|
|
||||||
config ARCH_HAS_ELFCORE_COMPAT
|
config ARCH_HAS_ELFCORE_COMPAT
|
||||||
bool
|
bool
|
||||||
|
@ -73,7 +73,7 @@ struct halt_info {
|
|||||||
static void
|
static void
|
||||||
common_shutdown_1(void *generic_ptr)
|
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;
|
struct percpu_struct *cpup;
|
||||||
unsigned long *pflags, flags;
|
unsigned long *pflags, flags;
|
||||||
int cpuid = smp_processor_id();
|
int cpuid = smp_processor_id();
|
||||||
|
@ -628,7 +628,7 @@ flush_tlb_all(void)
|
|||||||
static void
|
static void
|
||||||
ipi_flush_tlb_mm(void *x)
|
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())
|
if (mm == current->active_mm && !asn_locked())
|
||||||
flush_tlb_current(mm);
|
flush_tlb_current(mm);
|
||||||
else
|
else
|
||||||
@ -670,7 +670,7 @@ struct flush_tlb_page_struct {
|
|||||||
static void
|
static void
|
||||||
ipi_flush_tlb_page(void *x)
|
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;
|
struct mm_struct * mm = data->mm;
|
||||||
|
|
||||||
if (mm == current->active_mm && !asn_locked())
|
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,
|
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.
|
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"
|
source "kernel/power/Kconfig"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -2615,8 +2615,8 @@ static bool emulator_io_port_access_allowed(struct x86_emulate_ctxt *ctxt,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool emulator_io_permited(struct x86_emulate_ctxt *ctxt,
|
static bool emulator_io_permitted(struct x86_emulate_ctxt *ctxt,
|
||||||
u16 port, u16 len)
|
u16 port, u16 len)
|
||||||
{
|
{
|
||||||
if (ctxt->perm_ok)
|
if (ctxt->perm_ok)
|
||||||
return true;
|
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)
|
static int check_perm_in(struct x86_emulate_ctxt *ctxt)
|
||||||
{
|
{
|
||||||
ctxt->dst.bytes = min(ctxt->dst.bytes, 4u);
|
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 emulate_gp(ctxt, 0);
|
||||||
|
|
||||||
return X86EMUL_CONTINUE;
|
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)
|
static int check_perm_out(struct x86_emulate_ctxt *ctxt)
|
||||||
{
|
{
|
||||||
ctxt->src.bytes = min(ctxt->src.bytes, 4u);
|
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 emulate_gp(ctxt, 0);
|
||||||
|
|
||||||
return X86EMUL_CONTINUE;
|
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)
|
* @is_leading: indicate if this is the session leading connection (MCS)
|
||||||
*
|
*
|
||||||
* Return: zero on success, $error if iscsi_conn_bind fails and
|
* 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).
|
* state is not UP (teardown already started).
|
||||||
*/
|
*/
|
||||||
static int iscsi_iser_conn_bind(struct iscsi_cls_session *cls_session,
|
static int iscsi_iser_conn_bind(struct iscsi_cls_session *cls_session,
|
||||||
|
@ -38,7 +38,7 @@ config CRAMFS_MTD
|
|||||||
default y if !CRAMFS_BLOCKDEV
|
default y if !CRAMFS_BLOCKDEV
|
||||||
help
|
help
|
||||||
This option allows the CramFs driver to load data directly from
|
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.
|
like flash) instead of going through the block device layer.
|
||||||
This saves some memory since no intermediate buffering is
|
This saves some memory since no intermediate buffering is
|
||||||
necessary.
|
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
|
* once we get rid of using bh as a container for mapping information
|
||||||
* to pass to / from get_block functions, this can go away.
|
* to pass to / from get_block functions, this can go away.
|
||||||
*/
|
*/
|
||||||
|
old_state = READ_ONCE(bh->b_state);
|
||||||
do {
|
do {
|
||||||
old_state = READ_ONCE(bh->b_state);
|
|
||||||
new_state = (old_state & ~EXT4_MAP_FLAGS) | flags;
|
new_state = (old_state & ~EXT4_MAP_FLAGS) | flags;
|
||||||
} while (unlikely(
|
} while (unlikely(!try_cmpxchg(&bh->b_state, &old_state, new_state)));
|
||||||
cmpxchg(&bh->b_state, old_state, new_state) != old_state));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _ext4_get_block(struct inode *inode, sector_t iblock,
|
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 */
|
/* 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)
|
return (w < 0x0020)
|
||||||
|| (w == '*') || (w == '?') || (w == '<') || (w == '>')
|
|| (w == '*') || (w == '?') || (w == '<') || (w == '>')
|
||||||
@ -208,7 +208,7 @@ static inline wchar_t vfat_bad_char(wchar_t w)
|
|||||||
|| (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 == ',')
|
return (w == '[') || (w == ']') || (w == ';') || (w == ',')
|
||||||
|| (w == '+') || (w == '=');
|
|| (w == '+') || (w == '=');
|
||||||
|
@ -31,7 +31,7 @@ vxfs_put_page(struct page *pp)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* vxfs_get_page - read a page into memory.
|
* vxfs_get_page - read a page into memory.
|
||||||
* @ip: inode to read from
|
* @mapping: mapping to read from
|
||||||
* @n: page number
|
* @n: page number
|
||||||
*
|
*
|
||||||
* Description:
|
* 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
|
* @ip: inode
|
||||||
* @iblock: logical block
|
* @iblock: logical block
|
||||||
* @bp: buffer skeleton
|
* @bp: buffer skeleton
|
||||||
* @create: %TRUE if blocks may be newly allocated.
|
* @create: %TRUE if blocks may be newly allocated.
|
||||||
*
|
*
|
||||||
* Description:
|
* 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
|
* block and device number to perform a lowlevel read/write on
|
||||||
* it.
|
* 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)
|
* @sbp: VFS superblock (to fill)
|
||||||
* @dp: fs private mount data
|
* @dp: fs private mount data
|
||||||
* @silent: do not complain loudly when sth is wrong
|
* @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[hash] = node;
|
||||||
tree->node_hash_cnt++;
|
tree->node_hash_cnt++;
|
||||||
} else {
|
} else {
|
||||||
|
hfs_bnode_get(node2);
|
||||||
spin_unlock(&tree->hash_lock);
|
spin_unlock(&tree->hash_lock);
|
||||||
kfree(node);
|
kfree(node);
|
||||||
wait_event(node2->lock_wq, !test_bit(HFS_BNODE_NEW, &node2->flags));
|
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);
|
inode->i_size);
|
||||||
if (inode->i_size > HFS_I(inode)->phys_size) {
|
if (inode->i_size > HFS_I(inode)->phys_size) {
|
||||||
struct address_space *mapping = inode->i_mapping;
|
struct address_space *mapping = inode->i_mapping;
|
||||||
void *fsdata;
|
void *fsdata = NULL;
|
||||||
struct page *page;
|
struct page *page;
|
||||||
|
|
||||||
/* XXX: Can use generic_cont_expand? */
|
/* XXX: Can use generic_cont_expand? */
|
||||||
|
@ -554,7 +554,7 @@ void hfsplus_file_truncate(struct inode *inode)
|
|||||||
if (inode->i_size > hip->phys_size) {
|
if (inode->i_size > hip->phys_size) {
|
||||||
struct address_space *mapping = inode->i_mapping;
|
struct address_space *mapping = inode->i_mapping;
|
||||||
struct page *page;
|
struct page *page;
|
||||||
void *fsdata;
|
void *fsdata = NULL;
|
||||||
loff_t size = inode->i_size;
|
loff_t size = inode->i_size;
|
||||||
|
|
||||||
res = hfsplus_write_begin(NULL, mapping, size, 0,
|
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,
|
int __hfsplus_setxattr(struct inode *inode, const char *name,
|
||||||
const void *value, size_t size, int flags)
|
const void *value, size_t size, int flags)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err;
|
||||||
struct hfs_find_data cat_fd;
|
struct hfs_find_data cat_fd;
|
||||||
hfsplus_cat_entry entry;
|
hfsplus_cat_entry entry;
|
||||||
u16 cat_entry_flags, cat_entry_type;
|
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;
|
__be32 xattr_record_type;
|
||||||
u32 record_type;
|
u32 record_type;
|
||||||
u16 record_length = 0;
|
u16 record_length = 0;
|
||||||
ssize_t res = 0;
|
ssize_t res;
|
||||||
|
|
||||||
if ((!S_ISREG(inode->i_mode) &&
|
if ((!S_ISREG(inode->i_mode) &&
|
||||||
!S_ISDIR(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,
|
static ssize_t hfsplus_listxattr_finder_info(struct dentry *dentry,
|
||||||
char *buffer, size_t size)
|
char *buffer, size_t size)
|
||||||
{
|
{
|
||||||
ssize_t res = 0;
|
ssize_t res;
|
||||||
struct inode *inode = d_inode(dentry);
|
struct inode *inode = d_inode(dentry);
|
||||||
struct hfs_find_data fd;
|
struct hfs_find_data fd;
|
||||||
u16 entry_type;
|
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 hfsplus_listxattr(struct dentry *dentry, char *buffer, size_t size)
|
||||||
{
|
{
|
||||||
ssize_t err;
|
ssize_t err;
|
||||||
ssize_t res = 0;
|
ssize_t res;
|
||||||
struct inode *inode = d_inode(dentry);
|
struct inode *inode = d_inode(dentry);
|
||||||
struct hfs_find_data fd;
|
struct hfs_find_data fd;
|
||||||
u16 key_len = 0;
|
|
||||||
struct hfsplus_attr_key attr_key;
|
struct hfsplus_attr_key attr_key;
|
||||||
char *strbuf;
|
char *strbuf;
|
||||||
int xattr_name_len;
|
int xattr_name_len;
|
||||||
@ -719,7 +718,8 @@ ssize_t hfsplus_listxattr(struct dentry *dentry, char *buffer, size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
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) {
|
if (key_len == 0 || key_len > fd.tree->max_key_len) {
|
||||||
pr_err("invalid xattr key length: %d\n", key_len);
|
pr_err("invalid xattr key length: %d\n", key_len);
|
||||||
res = -EIO;
|
res = -EIO;
|
||||||
@ -766,12 +766,12 @@ out:
|
|||||||
|
|
||||||
static int hfsplus_removexattr(struct inode *inode, const char *name)
|
static int hfsplus_removexattr(struct inode *inode, const char *name)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err;
|
||||||
struct hfs_find_data cat_fd;
|
struct hfs_find_data cat_fd;
|
||||||
u16 flags;
|
u16 flags;
|
||||||
u16 cat_entry_type;
|
u16 cat_entry_type;
|
||||||
int is_xattr_acl_deleted = 0;
|
int is_xattr_acl_deleted;
|
||||||
int is_all_xattrs_deleted = 0;
|
int is_all_xattrs_deleted;
|
||||||
|
|
||||||
if (!HFSPLUS_SB(inode->i_sb)->attr_tree)
|
if (!HFSPLUS_SB(inode->i_sb)->attr_tree)
|
||||||
return -EOPNOTSUPP;
|
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,
|
static int nilfs_dat_prepare_entry(struct inode *dat,
|
||||||
struct nilfs_palloc_req *req, int create)
|
struct nilfs_palloc_req *req, int create)
|
||||||
{
|
{
|
||||||
return nilfs_palloc_get_entry_block(dat, req->pr_entry_nr,
|
int ret;
|
||||||
create, &req->pr_entry_bh);
|
|
||||||
|
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,
|
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 nilfs_dat_prepare_start(struct inode *dat, struct nilfs_palloc_req *req)
|
||||||
{
|
{
|
||||||
int ret;
|
return nilfs_dat_prepare_entry(dat, req, 0);
|
||||||
|
|
||||||
ret = nilfs_dat_prepare_entry(dat, req, 0);
|
|
||||||
WARN_ON(ret == -ENOENT);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nilfs_dat_commit_start(struct inode *dat, struct nilfs_palloc_req *req,
|
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)
|
int nilfs_dat_prepare_end(struct inode *dat, struct nilfs_palloc_req *req)
|
||||||
{
|
{
|
||||||
struct nilfs_dat_entry *entry;
|
struct nilfs_dat_entry *entry;
|
||||||
|
__u64 start;
|
||||||
sector_t blocknr;
|
sector_t blocknr;
|
||||||
void *kaddr;
|
void *kaddr;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = nilfs_dat_prepare_entry(dat, req, 0);
|
ret = nilfs_dat_prepare_entry(dat, req, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
WARN_ON(ret == -ENOENT);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
kaddr = kmap_atomic(req->pr_entry_bh->b_page);
|
kaddr = kmap_atomic(req->pr_entry_bh->b_page);
|
||||||
entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr,
|
entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr,
|
||||||
req->pr_entry_bh, kaddr);
|
req->pr_entry_bh, kaddr);
|
||||||
|
start = le64_to_cpu(entry->de_start);
|
||||||
blocknr = le64_to_cpu(entry->de_blocknr);
|
blocknr = le64_to_cpu(entry->de_blocknr);
|
||||||
kunmap_atomic(kaddr);
|
kunmap_atomic(kaddr);
|
||||||
|
|
||||||
@ -172,6 +181,15 @@ int nilfs_dat_prepare_end(struct inode *dat, struct nilfs_palloc_req *req)
|
|||||||
return ret;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
/**
|
/*
|
||||||
* aops.c - NTFS kernel address space operations and page cache handling.
|
* aops.c - NTFS kernel address space operations and page cache handling.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2001-2014 Anton Altaparmakov and Tuxera Inc.
|
* Copyright (c) 2001-2014 Anton Altaparmakov and Tuxera Inc.
|
||||||
@ -1646,7 +1646,7 @@ hole:
|
|||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* ntfs_normal_aops - address space operations for normal inodes and attributes
|
* ntfs_normal_aops - address space operations for normal inodes and attributes
|
||||||
*
|
*
|
||||||
* Note these are not used for compressed or mst protected inodes and
|
* 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,
|
.error_remove_page = generic_error_remove_page,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* ntfs_compressed_aops - address space operations for compressed inodes
|
* ntfs_compressed_aops - address space operations for compressed inodes
|
||||||
*/
|
*/
|
||||||
const struct address_space_operations ntfs_compressed_aops = {
|
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,
|
.error_remove_page = generic_error_remove_page,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* ntfs_mst_aops - general address space operations for mst protecteed inodes
|
* ntfs_mst_aops - general address space operations for mst protecteed inodes
|
||||||
* and attributes
|
* and attributes
|
||||||
*/
|
*/
|
||||||
const struct address_space_operations ntfs_mst_aops = {
|
const struct address_space_operations ntfs_mst_aops = {
|
||||||
.read_folio = ntfs_read_folio, /* Fill page with data. */
|
.read_folio = ntfs_read_folio, /* Fill page with data. */
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
/**
|
/*
|
||||||
* aops.h - Defines for NTFS kernel address space operations and page cache
|
* aops.h - Defines for NTFS kernel address space operations and page cache
|
||||||
* handling. Part of the Linux-NTFS project.
|
* handling. Part of the Linux-NTFS project.
|
||||||
*
|
*
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
/**
|
/*
|
||||||
* compress.c - NTFS kernel compressed attributes handling.
|
* compress.c - NTFS kernel compressed attributes handling.
|
||||||
* Part of the Linux-NTFS project.
|
* Part of the Linux-NTFS project.
|
||||||
*
|
*
|
||||||
@ -41,12 +41,12 @@ typedef enum {
|
|||||||
NTFS_MAX_CB_SIZE = 64 * 1024,
|
NTFS_MAX_CB_SIZE = 64 * 1024,
|
||||||
} ntfs_compression_constants;
|
} ntfs_compression_constants;
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* ntfs_compression_buffer - one buffer for the decompression engine
|
* ntfs_compression_buffer - one buffer for the decompression engine
|
||||||
*/
|
*/
|
||||||
static u8 *ntfs_compression_buffer;
|
static u8 *ntfs_compression_buffer;
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* ntfs_cb_lock - spinlock which protects ntfs_compression_buffer
|
* ntfs_cb_lock - spinlock which protects ntfs_compression_buffer
|
||||||
*/
|
*/
|
||||||
static DEFINE_SPINLOCK(ntfs_cb_lock);
|
static DEFINE_SPINLOCK(ntfs_cb_lock);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
/**
|
/*
|
||||||
* dir.c - NTFS kernel directory operations. Part of the Linux-NTFS project.
|
* dir.c - NTFS kernel directory operations. Part of the Linux-NTFS project.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2001-2007 Anton Altaparmakov
|
* Copyright (c) 2001-2007 Anton Altaparmakov
|
||||||
@ -17,7 +17,7 @@
|
|||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "ntfs.h"
|
#include "ntfs.h"
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* The little endian Unicode string $I30 as a global constant.
|
* The little endian Unicode string $I30 as a global constant.
|
||||||
*/
|
*/
|
||||||
ntfschar I30[5] = { cpu_to_le16('$'), cpu_to_le16('I'),
|
ntfschar I30[5] = { cpu_to_le16('$'), cpu_to_le16('I'),
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
/**
|
/*
|
||||||
* inode.c - NTFS kernel inode handling.
|
* inode.c - NTFS kernel inode handling.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2001-2014 Anton Altaparmakov and Tuxera Inc.
|
* 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
|
* @vi: inode to write out
|
||||||
* @sync: if true, write out synchronously
|
* @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.
|
* might not need to be written out.
|
||||||
* NOTE: It is not a problem when the inode for $MFT itself is being
|
* 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
|
* 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
|
* 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
|
* record will be cleaned and written out to disk below, i.e. before
|
||||||
* this function returns.
|
* this function returns.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
/**
|
/*
|
||||||
* mft.c - NTFS kernel mft record operations. Part of the Linux-NTFS project.
|
* mft.c - NTFS kernel mft record operations. Part of the Linux-NTFS project.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2001-2012 Anton Altaparmakov and Tuxera Inc.
|
* Copyright (c) 2001-2012 Anton Altaparmakov and Tuxera Inc.
|
||||||
|
@ -259,7 +259,7 @@ err_out:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Inode operations for directories.
|
* Inode operations for directories.
|
||||||
*/
|
*/
|
||||||
const struct inode_operations ntfs_dir_inode_ops = {
|
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);
|
ntfs_nfs_get_inode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Export operations allowing NFS exporting of mounted NTFS partitions.
|
* Export operations allowing NFS exporting of mounted NTFS partitions.
|
||||||
*
|
*
|
||||||
* We use the default ->encode_fh() for now. Note that they
|
* We use the default ->encode_fh() for now. Note that they
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
/**
|
/*
|
||||||
* runlist.c - NTFS runlist handling code. Part of the Linux-NTFS project.
|
* runlist.c - NTFS runlist handling code. Part of the Linux-NTFS project.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2001-2007 Anton Altaparmakov
|
* 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).
|
* 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)
|
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
|
#endif
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* The complete super operations.
|
* The complete super operations.
|
||||||
*/
|
*/
|
||||||
static const struct super_operations ntfs_sops = {
|
static const struct super_operations ntfs_sops = {
|
||||||
|
@ -17,6 +17,7 @@ static int __init proc_cmdline_init(void)
|
|||||||
struct proc_dir_entry *pde;
|
struct proc_dir_entry *pde;
|
||||||
|
|
||||||
pde = proc_create_single("cmdline", 0, NULL, cmdline_proc_show);
|
pde = proc_create_single("cmdline", 0, NULL, cmdline_proc_show);
|
||||||
|
pde_make_permanent(pde);
|
||||||
pde->size = saved_command_line_len + 1;
|
pde->size = saved_command_line_len + 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
|
#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
|
||||||
enum {
|
enum {
|
||||||
EI_ETYPE_NONE, /* Dummy value for undefined case */
|
|
||||||
EI_ETYPE_NULL, /* Return NULL if failure */
|
EI_ETYPE_NULL, /* Return NULL if failure */
|
||||||
EI_ETYPE_ERRNO, /* Return -ERRNO if failure */
|
EI_ETYPE_ERRNO, /* Return -ERRNO if failure */
|
||||||
EI_ETYPE_ERRNO_NULL, /* Return -ERRNO or NULL if failure */
|
EI_ETYPE_ERRNO_NULL, /* Return -ERRNO or NULL if failure */
|
||||||
@ -20,8 +19,10 @@ struct pt_regs;
|
|||||||
|
|
||||||
#ifdef CONFIG_FUNCTION_ERROR_INJECTION
|
#ifdef CONFIG_FUNCTION_ERROR_INJECTION
|
||||||
/*
|
/*
|
||||||
* Whitelist generating macro. Specify functions which can be
|
* Whitelist generating macro. Specify functions which can be error-injectable
|
||||||
* error-injectable using this macro.
|
* 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) \
|
#define ALLOW_ERROR_INJECTION(fname, _etype) \
|
||||||
static struct error_injection_entry __used \
|
static struct error_injection_entry __used \
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#define _LINUX_ERROR_INJECTION_H
|
#define _LINUX_ERROR_INJECTION_H
|
||||||
|
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
|
#include <linux/errno.h>
|
||||||
#include <asm-generic/error-injection.h>
|
#include <asm-generic/error-injection.h>
|
||||||
|
|
||||||
#ifdef CONFIG_FUNCTION_ERROR_INJECTION
|
#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)
|
static inline int get_injectable_error_type(unsigned long addr)
|
||||||
{
|
{
|
||||||
return EI_ETYPE_NONE;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -403,7 +403,8 @@ extern int kimage_crash_copy_vmcoreinfo(struct kimage *image);
|
|||||||
|
|
||||||
extern struct kimage *kexec_image;
|
extern struct kimage *kexec_image;
|
||||||
extern struct kimage *kexec_crash_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
|
#ifndef kexec_flush_icache_page
|
||||||
#define kexec_flush_icache_page(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
|
static inline void
|
||||||
percpu_counter_add(struct percpu_counter *fbc, s64 amount)
|
percpu_counter_add(struct percpu_counter *fbc, s64 amount)
|
||||||
{
|
{
|
||||||
preempt_disable();
|
unsigned long flags;
|
||||||
|
|
||||||
|
local_irq_save(flags);
|
||||||
fbc->count += amount;
|
fbc->count += amount;
|
||||||
preempt_enable();
|
local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* non-SMP percpu_counter_add_local is the same with percpu_counter_add */
|
/* non-SMP percpu_counter_add_local is the same with percpu_counter_add */
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
#ifndef _LINUX_HELPER_MACROS_H_
|
#ifndef _LINUX_HELPER_MACROS_H_
|
||||||
#define _LINUX_HELPER_MACROS_H_
|
#define _LINUX_HELPER_MACROS_H_
|
||||||
|
|
||||||
|
#include <linux/math.h>
|
||||||
|
|
||||||
#define __find_closest(x, a, as, op) \
|
#define __find_closest(x, a, as, op) \
|
||||||
({ \
|
({ \
|
||||||
typeof(as) __fc_i, __fc_as = (as) - 1; \
|
typeof(as) __fc_i, __fc_as = (as) - 1; \
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <linux/syscalls.h>
|
#include <linux/syscalls.h>
|
||||||
#include <linux/utime.h>
|
#include <linux/utime.h>
|
||||||
#include <linux/file.h>
|
#include <linux/file.h>
|
||||||
|
#include <linux/kstrtox.h>
|
||||||
#include <linux/memblock.h>
|
#include <linux/memblock.h>
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
#include <linux/namei.h>
|
#include <linux/namei.h>
|
||||||
@ -571,8 +572,7 @@ __setup("keepinitrd", keepinitrd_setup);
|
|||||||
static bool __initdata initramfs_async = true;
|
static bool __initdata initramfs_async = true;
|
||||||
static int __init initramfs_async_setup(char *str)
|
static int __init initramfs_async_setup(char *str)
|
||||||
{
|
{
|
||||||
strtobool(str, &initramfs_async);
|
return kstrtobool(str, &initramfs_async) == 0;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
__setup("initramfs_async=", initramfs_async_setup);
|
__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)
|
if (sysctl_hung_task_all_cpu_backtrace)
|
||||||
hung_task_show_all_bt = true;
|
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();
|
touch_nmi_watchdog();
|
||||||
|
@ -190,10 +190,12 @@ out_unlock:
|
|||||||
static inline int kexec_load_check(unsigned long nr_segments,
|
static inline int kexec_load_check(unsigned long nr_segments,
|
||||||
unsigned long flags)
|
unsigned long flags)
|
||||||
{
|
{
|
||||||
|
int image_type = (flags & KEXEC_ON_CRASH) ?
|
||||||
|
KEXEC_TYPE_CRASH : KEXEC_TYPE_DEFAULT;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
/* We only trust the superuser with rebooting the system. */
|
/* 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;
|
return -EPERM;
|
||||||
|
|
||||||
/* Permit LSMs and IMA to fail the kexec */
|
/* Permit LSMs and IMA to fail the kexec */
|
||||||
|
@ -921,10 +921,64 @@ int kimage_load_segment(struct kimage *image,
|
|||||||
return result;
|
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_image;
|
||||||
struct kimage *kexec_crash_image;
|
struct kimage *kexec_crash_image;
|
||||||
int kexec_load_disabled;
|
static int kexec_load_disabled;
|
||||||
|
|
||||||
#ifdef CONFIG_SYSCTL
|
#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[] = {
|
static struct ctl_table kexec_core_sysctls[] = {
|
||||||
{
|
{
|
||||||
.procname = "kexec_load_disabled",
|
.procname = "kexec_load_disabled",
|
||||||
@ -936,6 +990,18 @@ static struct ctl_table kexec_core_sysctls[] = {
|
|||||||
.extra1 = SYSCTL_ONE,
|
.extra1 = SYSCTL_ONE,
|
||||||
.extra2 = 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);
|
late_initcall(kexec_core_sysctl_init);
|
||||||
#endif
|
#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
|
* 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
|
* 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, cmdline_len, const char __user *, cmdline_ptr,
|
||||||
unsigned long, flags)
|
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;
|
struct kimage **dest_image, *image;
|
||||||
|
int ret = 0, i;
|
||||||
|
|
||||||
/* We only trust the superuser with rebooting the system. */
|
/* 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;
|
return -EPERM;
|
||||||
|
|
||||||
/* Make sure we have a legal set of flags */
|
/* 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())
|
if (!kexec_trylock())
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
dest_image = &kexec_image;
|
if (image_type == KEXEC_TYPE_CRASH) {
|
||||||
if (flags & KEXEC_FILE_ON_CRASH) {
|
|
||||||
dest_image = &kexec_crash_image;
|
dest_image = &kexec_crash_image;
|
||||||
if (kexec_crash_image)
|
if (kexec_crash_image)
|
||||||
arch_kexec_unprotect_crashkres();
|
arch_kexec_unprotect_crashkres();
|
||||||
|
} else {
|
||||||
|
dest_image = &kexec_image;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & KEXEC_FILE_UNLOAD)
|
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
|
* 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
|
* worker API is used only in trivial scenarios. There are no multi-step state
|
||||||
* machines needed.
|
* 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)
|
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_flush_worker(worker);
|
||||||
kthread_stop(task);
|
kthread_stop(task);
|
||||||
|
WARN_ON(!list_empty(&worker->delayed_work_list));
|
||||||
WARN_ON(!list_empty(&worker->work_list));
|
WARN_ON(!list_empty(&worker->work_list));
|
||||||
kfree(worker);
|
kfree(worker);
|
||||||
}
|
}
|
||||||
|
@ -229,7 +229,7 @@ void __put_user_ns(struct user_namespace *ns)
|
|||||||
EXPORT_SYMBOL(__put_user_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.
|
* sorted idmap array. It is passed to cmp_map_id() as first argument.
|
||||||
*/
|
*/
|
||||||
struct idmap_key {
|
struct idmap_key {
|
||||||
|
@ -1185,13 +1185,16 @@ config DEBUG_TIMEKEEPING
|
|||||||
config DEBUG_PREEMPT
|
config DEBUG_PREEMPT
|
||||||
bool "Debug preemptible kernel"
|
bool "Debug preemptible kernel"
|
||||||
depends on DEBUG_KERNEL && PREEMPTION && TRACE_IRQFLAGS_SUPPORT
|
depends on DEBUG_KERNEL && PREEMPTION && TRACE_IRQFLAGS_SUPPORT
|
||||||
default y
|
|
||||||
help
|
help
|
||||||
If you say Y here then the kernel will use a debug variant of the
|
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
|
commonly used smp_processor_id() function and will print warnings
|
||||||
if kernel code uses it in a preemption-unsafe way. Also, the kernel
|
if kernel code uses it in a preemption-unsafe way. Also, the kernel
|
||||||
will detect preemption count underflows.
|
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...)"
|
menu "Lock Debugging (spinlocks, mutexes, etc...)"
|
||||||
|
|
||||||
config LOCK_DEBUGGING_SUPPORT
|
config LOCK_DEBUGGING_SUPPORT
|
||||||
@ -2029,6 +2032,41 @@ menuconfig RUNTIME_TESTING_MENU
|
|||||||
|
|
||||||
if 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
|
config LKDTM
|
||||||
tristate "Linux Kernel Dump Test Tool Module"
|
tristate "Linux Kernel Dump Test Tool Module"
|
||||||
depends on DEBUG_FS
|
depends on DEBUG_FS
|
||||||
|
@ -57,6 +57,8 @@ obj-$(CONFIG_TEST_HEXDUMP) += test_hexdump.o
|
|||||||
obj-y += kstrtox.o
|
obj-y += kstrtox.o
|
||||||
obj-$(CONFIG_FIND_BIT_BENCHMARK) += find_bit_benchmark.o
|
obj-$(CONFIG_FIND_BIT_BENCHMARK) += find_bit_benchmark.o
|
||||||
obj-$(CONFIG_TEST_BPF) += test_bpf.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_FIRMWARE) += test_firmware.o
|
||||||
obj-$(CONFIG_TEST_BITOPS) += test_bitops.o
|
obj-$(CONFIG_TEST_BITOPS) += test_bitops.o
|
||||||
CFLAGS_test_bitops.o += -Werror
|
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)
|
int get_injectable_error_type(unsigned long addr)
|
||||||
{
|
{
|
||||||
struct ei_entry *ent;
|
struct ei_entry *ent;
|
||||||
int ei_type = EI_ETYPE_NONE;
|
int ei_type = -EINVAL;
|
||||||
|
|
||||||
mutex_lock(&ei_mutex);
|
mutex_lock(&ei_mutex);
|
||||||
list_for_each_entry(ent, &error_injection_list, list) {
|
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;
|
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 {
|
do {
|
||||||
val = nval;
|
|
||||||
if (val & mask_to_set)
|
if (val & mask_to_set)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
cpu_relax();
|
cpu_relax();
|
||||||
} while ((nval = cmpxchg(addr, val, val | mask_to_set)) != val);
|
} while (!try_cmpxchg(addr, &val, val | mask_to_set));
|
||||||
|
|
||||||
return 0;
|
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 {
|
do {
|
||||||
val = nval;
|
|
||||||
if ((val & mask_to_clear) != mask_to_clear)
|
if ((val & mask_to_clear) != mask_to_clear)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
cpu_relax();
|
cpu_relax();
|
||||||
} while ((nval = cmpxchg(addr, val, val & ~mask_to_clear)) != val);
|
} while (!try_cmpxchg(addr, &val, val & ~mask_to_clear));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -73,28 +73,33 @@ void percpu_counter_set(struct percpu_counter *fbc, s64 amount)
|
|||||||
EXPORT_SYMBOL(percpu_counter_set);
|
EXPORT_SYMBOL(percpu_counter_set);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function is both preempt and irq safe. The former is due to explicit
|
* local_irq_save() is needed to make the function irq safe:
|
||||||
* preemption disable. The latter is guaranteed by the fact that the slow path
|
* - The slow path would be ok as protected by an irq-safe spinlock.
|
||||||
* is explicitly protected by an irq-safe spinlock whereas the fast patch uses
|
* - this_cpu_add would be ok as it is irq-safe by definition.
|
||||||
* this_cpu_add which is irq-safe by definition. Hence there is no need muck
|
* But:
|
||||||
* with irq state before calling this one
|
* 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)
|
void percpu_counter_add_batch(struct percpu_counter *fbc, s64 amount, s32 batch)
|
||||||
{
|
{
|
||||||
s64 count;
|
s64 count;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
preempt_disable();
|
local_irq_save(flags);
|
||||||
count = __this_cpu_read(*fbc->counters) + amount;
|
count = __this_cpu_read(*fbc->counters) + amount;
|
||||||
if (abs(count) >= batch) {
|
if (abs(count) >= batch) {
|
||||||
unsigned long flags;
|
raw_spin_lock(&fbc->lock);
|
||||||
raw_spin_lock_irqsave(&fbc->lock, flags);
|
|
||||||
fbc->count += count;
|
fbc->count += count;
|
||||||
__this_cpu_sub(*fbc->counters, count - amount);
|
__this_cpu_sub(*fbc->counters, count - amount);
|
||||||
raw_spin_unlock_irqrestore(&fbc->lock, flags);
|
raw_spin_unlock(&fbc->lock);
|
||||||
} else {
|
} else {
|
||||||
this_cpu_add(*fbc->counters, amount);
|
this_cpu_add(*fbc->counters, amount);
|
||||||
}
|
}
|
||||||
preempt_enable();
|
local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(percpu_counter_add_batch);
|
EXPORT_SYMBOL(percpu_counter_add_batch);
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@
|
|||||||
|
|
||||||
/* architecture-specific bits */
|
/* architecture-specific bits */
|
||||||
#ifdef CONFIG_ZLIB_DFLTCC
|
#ifdef CONFIG_ZLIB_DFLTCC
|
||||||
# include "../zlib_dfltcc/dfltcc.h"
|
# include "../zlib_dfltcc/dfltcc_deflate.h"
|
||||||
#else
|
#else
|
||||||
#define DEFLATE_RESET_HOOK(strm) do {} while (0)
|
#define DEFLATE_RESET_HOOK(strm) do {} while (0)
|
||||||
#define DEFLATE_HOOK(strm, flush, bstate) 0
|
#define DEFLATE_HOOK(strm, flush, bstate) 0
|
||||||
@ -106,7 +106,7 @@ typedef struct deflate_workspace {
|
|||||||
deflate_state deflate_memory;
|
deflate_state deflate_memory;
|
||||||
#ifdef CONFIG_ZLIB_DFLTCC
|
#ifdef CONFIG_ZLIB_DFLTCC
|
||||||
/* State memory for s390 hardware deflate */
|
/* State memory for s390 hardware deflate */
|
||||||
struct dfltcc_state dfltcc_memory;
|
struct dfltcc_deflate_state dfltcc_memory;
|
||||||
#endif
|
#endif
|
||||||
Byte *window_memory;
|
Byte *window_memory;
|
||||||
Pos *prev_memory;
|
Pos *prev_memory;
|
||||||
@ -451,17 +451,24 @@ int zlib_deflate(
|
|||||||
Assert(strm->avail_out > 0, "bug2");
|
Assert(strm->avail_out > 0, "bug2");
|
||||||
|
|
||||||
if (flush != Z_FINISH) return Z_OK;
|
if (flush != Z_FINISH) return Z_OK;
|
||||||
if (s->noheader) return Z_STREAM_END;
|
|
||||||
|
|
||||||
/* Write the zlib trailer (adler32) */
|
if (!s->noheader) {
|
||||||
putShortMSB(s, (uInt)(strm->adler >> 16));
|
/* Write zlib trailer (adler32) */
|
||||||
putShortMSB(s, (uInt)(strm->adler & 0xffff));
|
putShortMSB(s, (uInt)(strm->adler >> 16));
|
||||||
|
putShortMSB(s, (uInt)(strm->adler & 0xffff));
|
||||||
|
}
|
||||||
flush_pending(strm);
|
flush_pending(strm);
|
||||||
/* If avail_out is zero, the application will call deflate again
|
/* If avail_out is zero, the application will call deflate again
|
||||||
* to flush the rest.
|
* to flush the rest.
|
||||||
*/
|
*/
|
||||||
s->noheader = -1; /* write the trailer only once! */
|
if (!s->noheader) {
|
||||||
return s->pending != 0 ? Z_OK : Z_STREAM_END;
|
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(
|
void dfltcc_reset_state(struct dfltcc_state *dfltcc_state) {
|
||||||
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;
|
|
||||||
|
|
||||||
/* Initialize available functions */
|
/* Initialize available functions */
|
||||||
if (is_dfltcc_enabled()) {
|
if (is_dfltcc_enabled()) {
|
||||||
dfltcc(DFLTCC_QAF, param, NULL, NULL, NULL, NULL, NULL);
|
dfltcc(DFLTCC_QAF, &dfltcc_state->param, NULL, NULL, NULL, NULL, NULL);
|
||||||
memmove(&dfltcc_state->af, param, sizeof(dfltcc_state->af));
|
memmove(&dfltcc_state->af, &dfltcc_state->param, sizeof(dfltcc_state->af));
|
||||||
} else
|
} else
|
||||||
memset(&dfltcc_state->af, 0, sizeof(dfltcc_state->af));
|
memset(&dfltcc_state->af, 0, sizeof(dfltcc_state->af));
|
||||||
|
|
||||||
/* Initialize parameter block */
|
/* Initialize parameter block */
|
||||||
memset(&dfltcc_state->param, 0, sizeof(dfltcc_state->param));
|
memset(&dfltcc_state->param, 0, sizeof(dfltcc_state->param));
|
||||||
dfltcc_state->param.nt = 1;
|
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;
|
dfltcc_state->param.ribm = DFLTCC_RIBM;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dfltcc_reset);
|
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
@ -93,63 +93,32 @@ static_assert(sizeof(struct dfltcc_param_v0) == 1536);
|
|||||||
struct dfltcc_state {
|
struct dfltcc_state {
|
||||||
struct dfltcc_param_v0 param; /* Parameter block */
|
struct dfltcc_param_v0 param; /* Parameter block */
|
||||||
struct dfltcc_qaf_param af; /* Available functions */
|
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 level_mask; /* Levels on which to use DFLTCC */
|
||||||
uLong block_size; /* New block each X bytes */
|
uLong block_size; /* New block each X bytes */
|
||||||
uLong block_threshold; /* New block after total_in > X */
|
uLong block_threshold; /* New block after total_in > X */
|
||||||
uLong dht_threshold; /* New block only if avail_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 */
|
/* 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)
|
static inline int is_dfltcc_enabled(void)
|
||||||
{
|
{
|
||||||
return (zlib_dfltcc_support != ZLIB_DFLTCC_DISABLED &&
|
return (zlib_dfltcc_support != ZLIB_DFLTCC_DISABLED &&
|
||||||
test_facility(DFLTCC_FACILITY));
|
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 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 */
|
#endif /* DFLTCC_H */
|
||||||
|
@ -2,11 +2,13 @@
|
|||||||
|
|
||||||
#include "../zlib_deflate/defutil.h"
|
#include "../zlib_deflate/defutil.h"
|
||||||
#include "dfltcc_util.h"
|
#include "dfltcc_util.h"
|
||||||
#include "dfltcc.h"
|
#include "dfltcc_deflate.h"
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
#include <linux/zutil.h>
|
#include <linux/zutil.h>
|
||||||
|
|
||||||
|
#define GET_DFLTCC_DEFLATE_STATE(state) ((struct dfltcc_deflate_state *)GET_DFLTCC_STATE(state))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compress.
|
* Compress.
|
||||||
*/
|
*/
|
||||||
@ -15,7 +17,7 @@ int dfltcc_can_deflate(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
deflate_state *state = (deflate_state *)strm->state;
|
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 */
|
/* Check for kernel dfltcc command line parameter */
|
||||||
if (zlib_dfltcc_support == ZLIB_DFLTCC_DISABLED ||
|
if (zlib_dfltcc_support == ZLIB_DFLTCC_DISABLED ||
|
||||||
@ -28,22 +30,39 @@ int dfltcc_can_deflate(
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Unsupported hardware */
|
/* Unsupported hardware */
|
||||||
if (!is_bit_set(dfltcc_state->af.fns, DFLTCC_GDHT) ||
|
if (!is_bit_set(dfltcc_state->common.af.fns, DFLTCC_GDHT) ||
|
||||||
!is_bit_set(dfltcc_state->af.fns, DFLTCC_CMPR) ||
|
!is_bit_set(dfltcc_state->common.af.fns, DFLTCC_CMPR) ||
|
||||||
!is_bit_set(dfltcc_state->af.fmts, DFLTCC_FMT0))
|
!is_bit_set(dfltcc_state->common.af.fmts, DFLTCC_FMT0))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dfltcc_can_deflate);
|
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(
|
static void dfltcc_gdht(
|
||||||
z_streamp strm
|
z_streamp strm
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
deflate_state *state = (deflate_state *)strm->state;
|
deflate_state *state = (deflate_state *)strm->state;
|
||||||
struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param;
|
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,
|
dfltcc(DFLTCC_GDHT,
|
||||||
param, NULL, NULL,
|
param, NULL, NULL,
|
||||||
@ -104,39 +123,46 @@ int dfltcc_deflate(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
deflate_state *state = (deflate_state *)strm->state;
|
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);
|
||||||
struct dfltcc_param_v0 *param = &dfltcc_state->param;
|
struct dfltcc_param_v0 *param = &dfltcc_state->common.param;
|
||||||
uInt masked_avail_in;
|
uInt masked_avail_in;
|
||||||
dfltcc_cc cc;
|
dfltcc_cc cc;
|
||||||
int need_empty_block;
|
int need_empty_block;
|
||||||
int soft_bcc;
|
int soft_bcc;
|
||||||
int no_flush;
|
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;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
again:
|
again:
|
||||||
masked_avail_in = 0;
|
masked_avail_in = 0;
|
||||||
soft_bcc = 0;
|
soft_bcc = 0;
|
||||||
no_flush = flush == Z_NO_FLUSH;
|
no_flush = flush == Z_NO_FLUSH;
|
||||||
|
|
||||||
/* Trailing empty block. Switch to software, except when Continuation Flag
|
/* No input data. Return, except when Continuation Flag is set, which means
|
||||||
* is set, which means that DFLTCC has buffered some output in the
|
* that DFLTCC has buffered some output in the parameter block and needs to
|
||||||
* parameter block and needs to be called again in order to flush it.
|
* be called again in order to flush it.
|
||||||
*/
|
*/
|
||||||
if (flush == Z_FINISH && strm->avail_in == 0 && !param->cf) {
|
if (strm->avail_in == 0 && !param->cf) {
|
||||||
if (param->bcf) {
|
/* A block is still open, and the hardware does not support closing
|
||||||
/* A block is still open, and the hardware does not support closing
|
* blocks without adding data. Thus, close it manually.
|
||||||
* blocks without adding data. Thus, close it manually.
|
*/
|
||||||
*/
|
if (!no_flush && param->bcf) {
|
||||||
send_eobs(strm, param);
|
send_eobs(strm, param);
|
||||||
param->bcf = 0;
|
param->bcf = 0;
|
||||||
}
|
}
|
||||||
return 0;
|
/* Let one of deflate_* functions write a trailing empty block. */
|
||||||
}
|
if (flush == Z_FINISH)
|
||||||
|
return 0;
|
||||||
if (strm->avail_in == 0 && !param->cf) {
|
/* Clear history. */
|
||||||
*result = need_more;
|
if (flush == Z_FULL_FLUSH)
|
||||||
|
param->hl = 0;
|
||||||
|
/* Trigger block post-processing if necessary. */
|
||||||
|
*result = no_flush ? need_more : block_done;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,13 +189,18 @@ again:
|
|||||||
param->bcf = 0;
|
param->bcf = 0;
|
||||||
dfltcc_state->block_threshold =
|
dfltcc_state->block_threshold =
|
||||||
strm->total_in + dfltcc_state->block_size;
|
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
|
/* 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
|
* uncompressed data to DFLTCC and mask the rest, so that on the next
|
||||||
* iteration we start a new block.
|
* iteration we start a new block.
|
||||||
@ -189,7 +220,7 @@ again:
|
|||||||
param->cvt = CVT_ADLER32;
|
param->cvt = CVT_ADLER32;
|
||||||
if (!no_flush)
|
if (!no_flush)
|
||||||
/* We need to close a block. Always do this in software - when there is
|
/* 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;
|
soft_bcc = 1;
|
||||||
if (flush == Z_FINISH && !param->bcf)
|
if (flush == Z_FINISH && !param->bcf)
|
||||||
/* We are about to open a BFINAL block, set Block Header Final bit
|
/* 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;
|
param->sbb = (unsigned int)state->bi_valid;
|
||||||
if (param->sbb > 0)
|
if (param->sbb > 0)
|
||||||
*strm->next_out = (Byte)state->bi_buf;
|
*strm->next_out = (Byte)state->bi_buf;
|
||||||
if (param->hl)
|
/* Honor history and check value */
|
||||||
param->nt = 0; /* Honor history */
|
param->nt = 0;
|
||||||
param->cv = strm->adler;
|
param->cv = strm->adler;
|
||||||
|
|
||||||
/* When opening a block, choose a Huffman-Table Type */
|
/* When opening a block, choose a Huffman-Table Type */
|
||||||
@ -232,7 +263,7 @@ again:
|
|||||||
} while (cc == DFLTCC_CC_AGAIN);
|
} while (cc == DFLTCC_CC_AGAIN);
|
||||||
|
|
||||||
/* Translate parameter block to stream */
|
/* 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;
|
state->bi_valid = param->sbb;
|
||||||
if (state->bi_valid == 0)
|
if (state->bi_valid == 0)
|
||||||
state->bi_buf = 0; /* Avoid accessing next_out */
|
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 "../zlib_inflate/inflate.h"
|
||||||
#include "dfltcc_util.h"
|
#include "dfltcc_util.h"
|
||||||
#include "dfltcc.h"
|
#include "dfltcc_inflate.h"
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
#include <linux/zutil.h>
|
#include <linux/zutil.h>
|
||||||
@ -22,16 +22,20 @@ int dfltcc_can_inflate(
|
|||||||
zlib_dfltcc_support == ZLIB_DFLTCC_DEFLATE_ONLY)
|
zlib_dfltcc_support == ZLIB_DFLTCC_DEFLATE_ONLY)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Unsupported compression settings */
|
|
||||||
if (state->wbits != HB_BITS)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Unsupported hardware */
|
/* Unsupported hardware */
|
||||||
return is_bit_set(dfltcc_state->af.fns, DFLTCC_XPND) &&
|
return is_bit_set(dfltcc_state->af.fns, DFLTCC_XPND) &&
|
||||||
is_bit_set(dfltcc_state->af.fmts, DFLTCC_FMT0);
|
is_bit_set(dfltcc_state->af.fmts, DFLTCC_FMT0);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dfltcc_can_inflate);
|
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(
|
static int dfltcc_was_inflate_used(
|
||||||
z_streamp strm
|
z_streamp strm
|
||||||
)
|
)
|
||||||
@ -91,8 +95,10 @@ dfltcc_inflate_action dfltcc_inflate(
|
|||||||
struct dfltcc_param_v0 *param = &dfltcc_state->param;
|
struct dfltcc_param_v0 *param = &dfltcc_state->param;
|
||||||
dfltcc_cc cc;
|
dfltcc_cc cc;
|
||||||
|
|
||||||
if (flush == Z_BLOCK) {
|
if (flush == Z_BLOCK || flush == Z_PACKET_FLUSH) {
|
||||||
/* DFLTCC does not support stopping on block boundaries */
|
/* 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)) {
|
if (dfltcc_inflate_disable(strm)) {
|
||||||
*ret = Z_STREAM_ERROR;
|
*ret = Z_STREAM_ERROR;
|
||||||
return DFLTCC_INFLATE_BREAK;
|
return DFLTCC_INFLATE_BREAK;
|
||||||
@ -121,8 +127,6 @@ dfltcc_inflate_action dfltcc_inflate(
|
|||||||
/* Translate stream to parameter block */
|
/* Translate stream to parameter block */
|
||||||
param->cvt = CVT_ADLER32;
|
param->cvt = CVT_ADLER32;
|
||||||
param->sbb = state->bits;
|
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)
|
if (param->hl)
|
||||||
param->nt = 0; /* Honor history for the first block */
|
param->nt = 0; /* Honor history for the first block */
|
||||||
param->cv = state->check;
|
param->cv = state->check;
|
||||||
@ -136,8 +140,6 @@ dfltcc_inflate_action dfltcc_inflate(
|
|||||||
strm->msg = oesc_msg(dfltcc_state->msg, param->oesc);
|
strm->msg = oesc_msg(dfltcc_state->msg, param->oesc);
|
||||||
state->last = cc == DFLTCC_CC_OK;
|
state->last = cc == DFLTCC_CC_OK;
|
||||||
state->bits = param->sbb;
|
state->bits = param->sbb;
|
||||||
state->whave = param->hl;
|
|
||||||
state->write = (param->ho + param->hl) & ((1 << HB_BITS) - 1);
|
|
||||||
state->check = param->cv;
|
state->check = param->cv;
|
||||||
if (cc == DFLTCC_CC_OP2_CORRUPT && param->oesc != 0) {
|
if (cc == DFLTCC_CC_OP2_CORRUPT && param->oesc != 0) {
|
||||||
/* Report an error if stream is corrupted */
|
/* 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 */
|
/* architecture-specific bits */
|
||||||
#ifdef CONFIG_ZLIB_DFLTCC
|
#ifdef CONFIG_ZLIB_DFLTCC
|
||||||
# include "../zlib_dfltcc/dfltcc.h"
|
# include "../zlib_dfltcc/dfltcc_inflate.h"
|
||||||
#else
|
#else
|
||||||
#define INFLATE_RESET_HOOK(strm) do {} while (0)
|
#define INFLATE_RESET_HOOK(strm) do {} while (0)
|
||||||
#define INFLATE_TYPEDO_HOOK(strm, flush) 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);
|
mask = flow_mask_find(tbl, new);
|
||||||
if (!mask) {
|
if (!mask) {
|
||||||
/* Allocate a new mask if none exsits. */
|
/* Allocate a new mask if none exists. */
|
||||||
mask = mask_alloc();
|
mask = mask_alloc();
|
||||||
if (!mask)
|
if (!mask)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -80,8 +80,7 @@ def calc(oldfile, newfile, format):
|
|||||||
if d<0: shrink, down = shrink+1, down-d
|
if d<0: shrink, down = shrink+1, down-d
|
||||||
delta.append((d, name))
|
delta.append((d, name))
|
||||||
|
|
||||||
delta.sort()
|
delta.sort(reverse=True)
|
||||||
delta.reverse()
|
|
||||||
return grow, shrink, add, remove, up, down, delta, old, new, otot, ntot
|
return grow, shrink, add, remove, up, down, delta, old, new, otot, ntot
|
||||||
|
|
||||||
def print_result(symboltype, symbolformat):
|
def print_result(symboltype, symbolformat):
|
||||||
|
@ -823,7 +823,9 @@ our %deprecated_apis = (
|
|||||||
"get_state_synchronize_sched" => "get_state_synchronize_rcu",
|
"get_state_synchronize_sched" => "get_state_synchronize_rcu",
|
||||||
"cond_synchronize_sched" => "cond_synchronize_rcu",
|
"cond_synchronize_sched" => "cond_synchronize_rcu",
|
||||||
"kmap" => "kmap_local_page",
|
"kmap" => "kmap_local_page",
|
||||||
|
"kunmap" => "kunmap_local",
|
||||||
"kmap_atomic" => "kmap_local_page",
|
"kmap_atomic" => "kmap_local_page",
|
||||||
|
"kunmap_atomic" => "kunmap_local",
|
||||||
);
|
);
|
||||||
|
|
||||||
#Create a search pattern for all these strings to speed up a loop below
|
#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 ($sign_off =~ /^co-developed-by:$/i) {
|
||||||
if ($email eq $author) {
|
if ($email eq $author) {
|
||||||
WARN("BAD_SIGN_OFF",
|
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]) {
|
if (!defined $lines[$linenr]) {
|
||||||
WARN("BAD_SIGN_OFF",
|
WARN("BAD_SIGN_OFF",
|
||||||
"Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline);
|
"Co-developed-by: must be immediately followed by Signed-off-by:\n" . $herecurr);
|
||||||
} elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) {
|
} elsif ($rawlines[$linenr] !~ /^signed-off-by:\s*(.*)/i) {
|
||||||
WARN("BAD_SIGN_OFF",
|
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) {
|
} elsif ($1 ne $email) {
|
||||||
WARN("BAD_SIGN_OFF",
|
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
|
# Check Fixes: styles is correct
|
||||||
if (!$in_header_lines &&
|
if (!$in_header_lines &&
|
||||||
$line =~ /^\s*fixes:?\s*(?:commit\s*)?[0-9a-f]{5,}\b/i) {
|
$line =~ /^\s*fixes:?\s*(?:commit\s*)?[0-9a-f]{5,}\b/i) {
|
||||||
@ -3250,6 +3264,18 @@ sub process {
|
|||||||
$commit_log_possible_stack_dump = 0;
|
$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 #
|
# Check for lines starting with a #
|
||||||
if ($in_commit_log && $line =~ /^#/) {
|
if ($in_commit_log && $line =~ /^#/) {
|
||||||
if (WARN("COMMIT_COMMENT_SYMBOL",
|
if (WARN("COMMIT_COMMENT_SYMBOL",
|
||||||
@ -3725,7 +3751,7 @@ sub process {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# check for embedded filenames
|
# check for embedded filenames
|
||||||
if ($rawline =~ /^\+.*\Q$realfile\E/) {
|
if ($rawline =~ /^\+.*\b\Q$realfile\E\b/) {
|
||||||
WARN("EMBEDDED_FILENAME",
|
WARN("EMBEDDED_FILENAME",
|
||||||
"It's generally not useful to have the filename in the file\n" . $herecurr);
|
"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.clk
|
||||||
import linux.genpd
|
import linux.genpd
|
||||||
import linux.device
|
import linux.device
|
||||||
|
import linux.mm
|
||||||
|
@ -65,6 +65,7 @@ acumulative||accumulative
|
|||||||
acumulator||accumulator
|
acumulator||accumulator
|
||||||
acutally||actually
|
acutally||actually
|
||||||
adapater||adapter
|
adapater||adapter
|
||||||
|
adderted||asserted
|
||||||
addional||additional
|
addional||additional
|
||||||
additionaly||additionally
|
additionaly||additionally
|
||||||
additonal||additional
|
additonal||additional
|
||||||
@ -122,6 +123,7 @@ alue||value
|
|||||||
ambigious||ambiguous
|
ambigious||ambiguous
|
||||||
ambigous||ambiguous
|
ambigous||ambiguous
|
||||||
amoung||among
|
amoung||among
|
||||||
|
amount of times||number of times
|
||||||
amout||amount
|
amout||amount
|
||||||
amplifer||amplifier
|
amplifer||amplifier
|
||||||
amplifyer||amplifier
|
amplifyer||amplifier
|
||||||
@ -287,6 +289,7 @@ capapbilities||capabilities
|
|||||||
caputure||capture
|
caputure||capture
|
||||||
carefuly||carefully
|
carefuly||carefully
|
||||||
cariage||carriage
|
cariage||carriage
|
||||||
|
casued||caused
|
||||||
catagory||category
|
catagory||category
|
||||||
cehck||check
|
cehck||check
|
||||||
challange||challenge
|
challange||challenge
|
||||||
@ -370,6 +373,7 @@ conbination||combination
|
|||||||
conditionaly||conditionally
|
conditionaly||conditionally
|
||||||
conditon||condition
|
conditon||condition
|
||||||
condtion||condition
|
condtion||condition
|
||||||
|
condtional||conditional
|
||||||
conected||connected
|
conected||connected
|
||||||
conector||connector
|
conector||connector
|
||||||
configration||configuration
|
configration||configuration
|
||||||
@ -423,6 +427,7 @@ cound||could
|
|||||||
couter||counter
|
couter||counter
|
||||||
coutner||counter
|
coutner||counter
|
||||||
cryptocraphic||cryptographic
|
cryptocraphic||cryptographic
|
||||||
|
cummulative||cumulative
|
||||||
cunter||counter
|
cunter||counter
|
||||||
curently||currently
|
curently||currently
|
||||||
cylic||cyclic
|
cylic||cyclic
|
||||||
@ -625,8 +630,10 @@ exeuction||execution
|
|||||||
existance||existence
|
existance||existence
|
||||||
existant||existent
|
existant||existent
|
||||||
exixt||exist
|
exixt||exist
|
||||||
|
exsits||exists
|
||||||
exlcude||exclude
|
exlcude||exclude
|
||||||
exlcusive||exclusive
|
exlcusive||exclusive
|
||||||
|
exlusive||exclusive
|
||||||
exmaple||example
|
exmaple||example
|
||||||
expecially||especially
|
expecially||especially
|
||||||
experies||expires
|
experies||expires
|
||||||
@ -664,11 +671,13 @@ feauture||feature
|
|||||||
feautures||features
|
feautures||features
|
||||||
fetaure||feature
|
fetaure||feature
|
||||||
fetaures||features
|
fetaures||features
|
||||||
|
fetcing||fetching
|
||||||
fileystem||filesystem
|
fileystem||filesystem
|
||||||
fimrware||firmware
|
fimrware||firmware
|
||||||
fimware||firmware
|
fimware||firmware
|
||||||
firmare||firmware
|
firmare||firmware
|
||||||
firmaware||firmware
|
firmaware||firmware
|
||||||
|
firtly||firstly
|
||||||
firware||firmware
|
firware||firmware
|
||||||
firwmare||firmware
|
firwmare||firmware
|
||||||
finanize||finalize
|
finanize||finalize
|
||||||
@ -838,6 +847,7 @@ integrety||integrity
|
|||||||
integrey||integrity
|
integrey||integrity
|
||||||
intendet||intended
|
intendet||intended
|
||||||
intented||intended
|
intented||intended
|
||||||
|
interal||internal
|
||||||
interanl||internal
|
interanl||internal
|
||||||
interchangable||interchangeable
|
interchangable||interchangeable
|
||||||
interferring||interfering
|
interferring||interfering
|
||||||
@ -1023,6 +1033,7 @@ negotation||negotiation
|
|||||||
nerver||never
|
nerver||never
|
||||||
nescessary||necessary
|
nescessary||necessary
|
||||||
nessessary||necessary
|
nessessary||necessary
|
||||||
|
none existent||non-existent
|
||||||
noticable||noticeable
|
noticable||noticeable
|
||||||
notication||notification
|
notication||notification
|
||||||
notications||notifications
|
notications||notifications
|
||||||
@ -1044,6 +1055,7 @@ occured||occurred
|
|||||||
occurence||occurrence
|
occurence||occurrence
|
||||||
occure||occurred
|
occure||occurred
|
||||||
occuring||occurring
|
occuring||occurring
|
||||||
|
ocurrence||occurrence
|
||||||
offser||offset
|
offser||offset
|
||||||
offet||offset
|
offet||offset
|
||||||
offlaod||offload
|
offlaod||offload
|
||||||
@ -1055,6 +1067,7 @@ omitt||omit
|
|||||||
ommiting||omitting
|
ommiting||omitting
|
||||||
ommitted||omitted
|
ommitted||omitted
|
||||||
onself||oneself
|
onself||oneself
|
||||||
|
onthe||on the
|
||||||
ony||only
|
ony||only
|
||||||
openning||opening
|
openning||opening
|
||||||
operatione||operation
|
operatione||operation
|
||||||
@ -1121,6 +1134,7 @@ perfomring||performing
|
|||||||
periperal||peripheral
|
periperal||peripheral
|
||||||
peripherial||peripheral
|
peripherial||peripheral
|
||||||
permissons||permissions
|
permissons||permissions
|
||||||
|
permited||permitted
|
||||||
peroid||period
|
peroid||period
|
||||||
persistance||persistence
|
persistance||persistence
|
||||||
persistant||persistent
|
persistant||persistent
|
||||||
@ -1334,6 +1348,7 @@ sacrifying||sacrificing
|
|||||||
safly||safely
|
safly||safely
|
||||||
safty||safety
|
safty||safety
|
||||||
satify||satisfy
|
satify||satisfy
|
||||||
|
satisifed||satisfied
|
||||||
savable||saveable
|
savable||saveable
|
||||||
scaleing||scaling
|
scaleing||scaling
|
||||||
scaned||scanned
|
scaned||scanned
|
||||||
@ -1558,6 +1573,7 @@ tunning||tuning
|
|||||||
ture||true
|
ture||true
|
||||||
tyep||type
|
tyep||type
|
||||||
udpate||update
|
udpate||update
|
||||||
|
updtes||updates
|
||||||
uesd||used
|
uesd||used
|
||||||
unknwon||unknown
|
unknwon||unknown
|
||||||
uknown||unknown
|
uknown||unknown
|
||||||
@ -1614,6 +1630,7 @@ unuseful||useless
|
|||||||
unvalid||invalid
|
unvalid||invalid
|
||||||
upate||update
|
upate||update
|
||||||
upsupported||unsupported
|
upsupported||unsupported
|
||||||
|
upto||up to
|
||||||
useable||usable
|
useable||usable
|
||||||
usefule||useful
|
usefule||useful
|
||||||
usefull||useful
|
usefull||useful
|
||||||
|
@ -264,10 +264,12 @@ exuberant()
|
|||||||
--$CTAGS_EXTRA=+fq --c-kinds=+px --fields=+iaS --langmap=c:+.h \
|
--$CTAGS_EXTRA=+fq --c-kinds=+px --fields=+iaS --langmap=c:+.h \
|
||||||
"${regex[@]}"
|
"${regex[@]}"
|
||||||
|
|
||||||
setup_regex exuberant kconfig
|
KCONFIG_ARGS=()
|
||||||
all_kconfigs | xargs $1 -a \
|
if ! $1 --list-languages | grep -iq kconfig; then
|
||||||
--langdef=kconfig --language-force=kconfig "${regex[@]}"
|
setup_regex exuberant kconfig
|
||||||
|
KCONFIG_ARGS=(--langdef=kconfig --language-force=kconfig "${regex[@]}")
|
||||||
|
fi
|
||||||
|
all_kconfigs | xargs $1 -a "${KCONFIG_ARGS[@]}"
|
||||||
}
|
}
|
||||||
|
|
||||||
emacs()
|
emacs()
|
||||||
|
@ -811,7 +811,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
|
|||||||
priv->card.num_links = 1;
|
priv->card.num_links = 1;
|
||||||
|
|
||||||
if (asrc_pdev) {
|
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].cpus->of_node = asrc_np;
|
||||||
priv->dai_link[1].platforms->of_node = asrc_np;
|
priv->dai_link[1].platforms->of_node = asrc_np;
|
||||||
priv->dai_link[2].codecs->dai_name = codec_dai_name;
|
priv->dai_link[2].codecs->dai_name = codec_dai_name;
|
||||||
|
Loading…
Reference in New Issue
Block a user