Update several example code for newer kernel
Known issues with current example code: If you using newer kernel(e.g linux 5.11.x) to compile the example code, you may meet following error: 1. syscall.c:83:50: error: ‘ksys_close’ undeclared; 2. cryptosk.c:17:24: error: field ‘sg’ has incomplete type 3. cryptosk.c:143:9: error: implicit declaration of function ‘get_random_bytes’ 4. error: macro "DECLARE_TASKLET" passed 3 arguments, but takes just 2 Solutions/workaround: 1. In syscall.c, replace #include <linux/syscalls.h> with #include <linux/fdtable.h> and replace ksys_close with close_fd if the kernel version >= 5.11. [1][2] 2. Add #include <linux/scatterlist.h> into cryptosk.c 3. Add #include <linux/random.h> into cryptosk.c 4. In bottomhalf.c and example_tasklet.c, replace DECLARE_TASKLET with DECLARE_TASKLET_OLD and dispose third argument(0L). [3] [1] - https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1572bfdf21d4d50e51941498ffe0b56c2289f783 [2] - https://www.mail-archive.com/meta-arago@arago-project.org//msg11939.html [3] - https://patchwork.kernel.org/project/kernel-hardening/patch/20200716030847.1564131-3-keescook@chromium.org/
This commit is contained in:
parent
bd8342bc14
commit
870b26fa2d
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -2,6 +2,7 @@
|
||||||
*.o
|
*.o
|
||||||
*.ko
|
*.ko
|
||||||
*cmd
|
*cmd
|
||||||
|
*.dwo
|
||||||
*.swp
|
*.swp
|
||||||
*.symvers
|
*.symvers
|
||||||
*.mod
|
*.mod
|
||||||
|
@ -31,4 +32,4 @@ lkmpg.pdf
|
||||||
*.xref
|
*.xref
|
||||||
|
|
||||||
# format checks
|
# format checks
|
||||||
expected-format
|
expected-format
|
2
Makefile
2
Makefile
|
@ -9,7 +9,7 @@ $(PROJ).pdf: lkmpg.tex
|
||||||
|
|
||||||
html: lkmpg.tex html.cfg
|
html: lkmpg.tex html.cfg
|
||||||
sed $ 's/\t/ /g' lkmpg.tex > lkmpg-for-ht.tex
|
sed $ 's/\t/ /g' lkmpg.tex > lkmpg-for-ht.tex
|
||||||
make4ht --shell-escape --utf8 --format html5 --config html.cfg --output-dir html lkmpg-for-ht.tex
|
make4ht --shell-escape --utf8 --format html5 --config html.cfg --output-dir html lkmpg-for-ht.tex "fn-in"
|
||||||
ln -sf lkmpg-for-ht.html html/index.html
|
ln -sf lkmpg-for-ht.html html/index.html
|
||||||
rm -f lkmpg-for-ht.tex lkmpg-for-ht.xref lkmpg-for-ht.tmp lkmpg-for-ht.html lkmpg-for-ht.css lkmpg-for-ht.4ct lkmpg-for-ht.4tc lkmpg-for-ht.dvi lkmpg-for-ht.lg lkmpg-for-ht.idv lkmpg*.svg lkmpg-for-ht.log lkmpg-for-ht.aux
|
rm -f lkmpg-for-ht.tex lkmpg-for-ht.xref lkmpg-for-ht.tmp lkmpg-for-ht.html lkmpg-for-ht.css lkmpg-for-ht.4ct lkmpg-for-ht.4tc lkmpg-for-ht.dvi lkmpg-for-ht.lg lkmpg-for-ht.idv lkmpg*.svg lkmpg-for-ht.log lkmpg-for-ht.aux
|
||||||
rm -rf _minted-$(PROJ) _minted-lkmpg-for-ht
|
rm -rf _minted-$(PROJ) _minted-lkmpg-for-ht
|
||||||
|
|
|
@ -14,6 +14,13 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
|
||||||
|
/* Macro DECLARE_TASKLET_OLD exists for compatibiity.
|
||||||
|
* See https://lwn.net/Articles/830964/
|
||||||
|
*/
|
||||||
|
#ifndef DECLARE_TASKLET_OLD
|
||||||
|
#define DECLARE_TASKLET_OLD(arg1, arg2) DECLARE_TASKLET(arg1, arg2, 0L)
|
||||||
|
#endif
|
||||||
|
|
||||||
static int button_irqs[] = {-1, -1};
|
static int button_irqs[] = {-1, -1};
|
||||||
|
|
||||||
/* Define GPIOs for LEDs.
|
/* Define GPIOs for LEDs.
|
||||||
|
@ -38,7 +45,7 @@ static void bottomhalf_tasklet_fn(unsigned long data)
|
||||||
pr_info("Bottom half tasklet ends\n");
|
pr_info("Bottom half tasklet ends\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
DECLARE_TASKLET(buttontask, bottomhalf_tasklet_fn, 0L);
|
DECLARE_TASKLET_OLD(buttontask, bottomhalf_tasklet_fn);
|
||||||
|
|
||||||
/* interrupt function triggered when a button is pressed */
|
/* interrupt function triggered when a button is pressed */
|
||||||
static irqreturn_t button_isr(int irq, void *data)
|
static irqreturn_t button_isr(int irq, void *data)
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#include <crypto/internal/skcipher.h>
|
#include <crypto/internal/skcipher.h>
|
||||||
#include <linux/crypto.h>
|
#include <linux/crypto.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/random.h>
|
||||||
|
#include <linux/scatterlist.h>
|
||||||
|
|
||||||
#define SYMMETRIC_KEY_LENGTH 32
|
#define SYMMETRIC_KEY_LENGTH 32
|
||||||
#define CIPHER_BLOCK_SIZE 16
|
#define CIPHER_BLOCK_SIZE 16
|
||||||
|
|
|
@ -6,6 +6,13 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
|
||||||
|
/* Macro DECLARE_TASKLET_OLD exists for compatibiity.
|
||||||
|
* See https://lwn.net/Articles/830964/
|
||||||
|
*/
|
||||||
|
#ifndef DECLARE_TASKLET_OLD
|
||||||
|
#define DECLARE_TASKLET_OLD(arg1, arg2) DECLARE_TASKLET(arg1, arg2, 0L)
|
||||||
|
#endif
|
||||||
|
|
||||||
static void tasklet_fn(unsigned long data)
|
static void tasklet_fn(unsigned long data)
|
||||||
{
|
{
|
||||||
pr_info("Example tasklet starts\n");
|
pr_info("Example tasklet starts\n");
|
||||||
|
@ -13,7 +20,7 @@ static void tasklet_fn(unsigned long data)
|
||||||
pr_info("Example tasklet ends\n");
|
pr_info("Example tasklet ends\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
DECLARE_TASKLET(mytask, tasklet_fn, 0L);
|
DECLARE_TASKLET_OLD(mytask, tasklet_fn);
|
||||||
|
|
||||||
static int example_tasklet_init(void)
|
static int example_tasklet_init(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/moduleparam.h> /* which will have params */
|
#include <linux/moduleparam.h> /* which will have params */
|
||||||
#include <linux/syscalls.h>
|
#include <linux/unistd.h> /* The list of system calls */
|
||||||
#include <linux/unistd.h> /* The list of system calls */
|
#include <linux/version.h>
|
||||||
|
|
||||||
/* For the current (process) structure, we need this to know who the
|
/* For the current (process) structure, we need this to know who the
|
||||||
* current user is.
|
* current user is.
|
||||||
|
@ -23,6 +23,15 @@
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
|
||||||
|
/* The in-kernel calls to the ksys_close() syscall were removed in Linux v5.11+.
|
||||||
|
*/
|
||||||
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0))
|
||||||
|
#include <linux/syscalls.h> /* ksys_close() wrapper for backward compatibility */
|
||||||
|
#define close_fd ksys_close
|
||||||
|
#else
|
||||||
|
#include <linux/fdtable.h> /* For close_fd */
|
||||||
|
#endif
|
||||||
|
|
||||||
unsigned long **sys_call_table;
|
unsigned long **sys_call_table;
|
||||||
unsigned long original_cr0;
|
unsigned long original_cr0;
|
||||||
|
|
||||||
|
@ -80,7 +89,7 @@ static unsigned long **aquire_sys_call_table(void)
|
||||||
while (offset < ULLONG_MAX) {
|
while (offset < ULLONG_MAX) {
|
||||||
sct = (unsigned long **) offset;
|
sct = (unsigned long **) offset;
|
||||||
|
|
||||||
if (sct[__NR_close] == (unsigned long *) ksys_close)
|
if (sct[__NR_close] == (unsigned long *) close_fd)
|
||||||
return sct;
|
return sct;
|
||||||
|
|
||||||
offset += sizeof(void *);
|
offset += sizeof(void *);
|
||||||
|
|
|
@ -1421,6 +1421,15 @@ Example tasklet starts
|
||||||
Example tasklet init continues...
|
Example tasklet init continues...
|
||||||
Example tasklet ends
|
Example tasklet ends
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
|
Although tasklet is easy to use, it comes with several defators, and developers are discussing about getting rid of tasklet in linux kernel.
|
||||||
|
The tasklet callback runs in atomic context, inside a software interrupt, meaning that it cannot sleep or access user-space data, so not all work can be done in a tasklet handler.
|
||||||
|
Also, the kernel only allows one instance of any given tasklet to be running at any given time; multiple different tasklet callbacks can run in parallel.
|
||||||
|
|
||||||
|
In recent kernels, tasklets can be replaced by workqueues, timers, or threaded interrupts.\footnote{The goal of threaded interrupts is to push more of the work to separate threads, so that the minimum needed for acknowledging an interrupt is reduced, and therefore the time spent handling the interrupt (where it can't handle any other interrupts at the same time) is reduced.
|
||||||
|
See https://lwn.net/Articles/302043/}
|
||||||
|
While the removal of tasklets remains a longer-term goal, the current kernel contains more than a hundred uses of tasklets.
|
||||||
|
Now developers are proceeding with the API changes and the macro \cpp|DECLARE_TASKLET_OLD| exists for compatibiity.
|
||||||
|
For further information, see \url{https://lwn.net/Articles/830964/}.
|
||||||
|
|
||||||
\subsection{Work queues}
|
\subsection{Work queues}
|
||||||
\label{sec:workqueue}
|
\label{sec:workqueue}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user