Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 156af8c

Browse files
committed
take into a/c that kernels >= 5.8.0 removed the pgprot arg from the __vmalloc()
1 parent 83ad4dc commit 156af8c

File tree

1 file changed

+44
-17
lines changed

1 file changed

+44
-17
lines changed

ch9/vmalloc_demo/vmalloc_demo.c

Lines changed: 44 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@
2323
#include <linux/mm.h>
2424
#include <linux/slab.h>
2525
#include <linux/vmalloc.h>
26-
27-
#define OURMODNAME "vmalloc_demo"
26+
#include <linux/version.h>
2827

2928
MODULE_AUTHOR("Kaiwan N Billimoria");
3029
MODULE_DESCRIPTION("LKP book:ch9/vmalloc_demo/: simple vmalloc() and friends demo lkm");
@@ -38,7 +37,10 @@ MODULE_PARM_DESC(kvnum, "number of bytes to allocate with the kvmalloc(); (defau
3837
#define KVN_MIN_BYTES 16
3938
#define DISP_BYTES 16
4039

41-
static void *vptr_rndm, *vptr_init, *kv, *kvarr, *vrx;
40+
static void *vptr_rndm, *vptr_init, *kv, *kvarr;
41+
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)
42+
static void *vrx;
43+
#endif
4244

4345
static int vmalloc_try(void)
4446
{
@@ -51,8 +53,7 @@ static int vmalloc_try(void)
5153
pr_warn("vmalloc failed\n");
5254
goto err_out1;
5355
}
54-
pr_info("1. vmalloc(): vptr_rndm = 0x%pK (actual=0x%px)\n",
55-
vptr_rndm, vptr_rndm);
56+
pr_info("1. vmalloc(): vptr_rndm = 0x%pK (actual=0x%px)\n", vptr_rndm, vptr_rndm);
5657
print_hex_dump_bytes(" content: ", DUMP_PREFIX_NONE, vptr_rndm, DISP_BYTES);
5758

5859
/* 2. vzalloc(); mem contents are set to zeroes */
@@ -61,25 +62,24 @@ static int vmalloc_try(void)
6162
pr_warn("vzalloc failed\n");
6263
goto err_out2;
6364
}
64-
pr_info("2. vzalloc(): vptr_init = 0x%pK (actual=0x%px)\n",
65-
vptr_init, vptr_init);
65+
pr_info("2. vzalloc(): vptr_init = 0x%pK (actual=0x%px)\n", vptr_init, vptr_init);
6666
print_hex_dump_bytes(" content: ", DUMP_PREFIX_NONE, vptr_init, DISP_BYTES);
6767

68-
/* 3. kvmalloc(): allocate 'kvnum' bytes with the kvmalloc(); if kvnum is
69-
* large (enough), this will become a vmalloc() under the hood, else
70-
* it fals back to a kmalloc()
68+
/* 3. kvmalloc(): allocate 'kvnum' bytes (5MB by default) with the kvmalloc();
69+
* if kvnum is large (enough), this will become a vmalloc() under the hood,
70+
* else it falls back to a kmalloc()
7171
*/
7272
kv = kvmalloc(kvnum, GFP_KERNEL);
7373
if (!kv) {
7474
pr_warn("kvmalloc failed\n");
7575
goto err_out3;
7676
}
7777
pr_info("3. kvmalloc() : kv = 0x%pK (actual=0x%px)\n"
78-
" (for %d bytes)\n", kv, kv, kvnum);
78+
" (for %d bytes)\n", kv, kv, kvnum);
7979
print_hex_dump_bytes(" content: ", DUMP_PREFIX_NONE, kv, KVN_MIN_BYTES);
8080

81-
/* 4. kcalloc(): allocate an array of 1000 64-bit quantities and zero
82-
* out the memory */
81+
/* 4. kcalloc(): allocate an array of 1000 64-bit quantities and zero out the memory
82+
*/
8383
kvarr = kcalloc(1000, sizeof(u64), GFP_KERNEL);
8484
if (!kvarr) {
8585
pr_warn("kcalloc failed\n");
@@ -92,7 +92,14 @@ static int vmalloc_try(void)
9292
#undef WR2ROMEM_BUG
9393
/* #define WR2ROMEM_BUG */
9494
/* 'Normal' usage: keep this commented out, else
95-
* we will crash! Read the book, Ch 9, for details :-) */
95+
* we will crash! Read the book, Ch 9, for details ;-)
96+
*/
97+
/*
98+
* In 5.8.0, commit 88dca4c 'mm: remove the pgprot argument to __vmalloc'
99+
* has removed the pgprot arg from the __vmalloc(). So, only attempt this
100+
* when we're on kernels < 5.8.0
101+
*/
102+
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)
96103
vrx = __vmalloc(42 * PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_RO);
97104
if (!vrx) {
98105
pr_warn("__vmalloc failed\n");
@@ -103,13 +110,30 @@ static int vmalloc_try(void)
103110
/* Try reading the memory, should be fine */
104111
print_hex_dump_bytes(" content: ", DUMP_PREFIX_NONE, vrx, DISP_BYTES);
105112
#ifdef WR2ROMEM_BUG
106-
/* Try writing to the RO memory! We find that the kernel crashes
107-
* (emits an Oops!) */
113+
/* Try writing to the RO memory! We should, of course, find that the kernel
114+
* crashes (emits an Oops!)
115+
*/
116+
pr_info("6. Attempting to now write into a kernel vmalloc-ed region that's RO!\n");
108117
*(u64 *) (vrx + 4) = 0xba;
118+
#endif /* WR2ROMEM_BUG */
119+
#else
120+
/*
121+
* Logically, should now use the __vmalloc_node_range() BUT, whoops, it isn't exported!
122+
* void *__vmalloc_node_range(unsigned long size, unsigned long align,
123+
* unsigned long start, unsigned long end, gfp_t gfp_mask,
124+
* pgprot_t prot, unsigned long vm_flags, int node,
125+
* const void *caller)
126+
*/
127+
pr_info
128+
("5. >= 5.8.0 : __vmalloc(): no page prot param; can use __vmalloc_node_range() but it's not exported..");
129+
pr_cont(" so, simply skip this case\n");
109130
#endif
131+
110132
return 0; /* success */
133+
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)
111134
err_out5:
112135
vfree(kvarr);
136+
#endif
113137
err_out4:
114138
vfree(kv);
115139
err_out3:
@@ -123,7 +147,8 @@ static int vmalloc_try(void)
123147
static int __init vmalloc_demo_init(void)
124148
{
125149
if (kvnum < KVN_MIN_BYTES) {
126-
pr_info("kvnum must be >= %d bytes (curr it's %d bytes)\n", KVN_MIN_BYTES, kvnum);
150+
pr_info("kvnum must be >= %d bytes (curr it's %d bytes)\n", KVN_MIN_BYTES,
151+
kvnum);
127152
return -EINVAL;
128153
}
129154
pr_info("inserted\n");
@@ -133,7 +158,9 @@ static int __init vmalloc_demo_init(void)
133158

134159
static void __exit vmalloc_demo_exit(void)
135160
{
161+
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)
136162
vfree(vrx);
163+
#endif
137164
kvfree(kvarr);
138165
kvfree(kv);
139166
vfree(vptr_init);

0 commit comments

Comments
 (0)