|
12 | 12 | #include <linux/errno.h>
|
13 | 13 | #include <linux/init.h>
|
14 | 14 | #include <linux/kernel.h>
|
| 15 | +#include <linux/module.h> |
15 | 16 | #include <linux/mm.h>
|
16 | 17 | #include <linux/slab.h>
|
17 | 18 | #include <linux/smp.h>
|
18 | 19 | #include <linux/time_namespace.h>
|
19 | 20 | #include <linux/random.h>
|
20 | 21 | #include <vdso/datapage.h>
|
| 22 | +#include <asm/alternative.h> |
21 | 23 | #include <asm/vdso.h>
|
22 | 24 |
|
23 | 25 | extern char vdso64_start[], vdso64_end[];
|
@@ -250,8 +252,25 @@ static struct page ** __init vdso_setup_pages(void *start, void *end)
|
250 | 252 | return pagelist;
|
251 | 253 | }
|
252 | 254 |
|
| 255 | +static void vdso_apply_alternatives(void) |
| 256 | +{ |
| 257 | + const struct elf64_shdr *alt, *shdr; |
| 258 | + struct alt_instr *start, *end; |
| 259 | + const struct elf64_hdr *hdr; |
| 260 | + |
| 261 | + hdr = (struct elf64_hdr *)vdso64_start; |
| 262 | + shdr = (void *)hdr + hdr->e_shoff; |
| 263 | + alt = find_section(hdr, shdr, ".altinstructions"); |
| 264 | + if (!alt) |
| 265 | + return; |
| 266 | + start = (void *)hdr + alt->sh_offset; |
| 267 | + end = (void *)hdr + alt->sh_offset + alt->sh_size; |
| 268 | + apply_alternatives(start, end); |
| 269 | +} |
| 270 | + |
253 | 271 | static int __init vdso_init(void)
|
254 | 272 | {
|
| 273 | + vdso_apply_alternatives(); |
255 | 274 | vdso64_mapping.pages = vdso_setup_pages(vdso64_start, vdso64_end);
|
256 | 275 | if (IS_ENABLED(CONFIG_COMPAT))
|
257 | 276 | vdso32_mapping.pages = vdso_setup_pages(vdso32_start, vdso32_end);
|
|
0 commit comments