diff options
Diffstat (limited to 'arch/x86/mm/init.c')
| -rw-r--r-- | arch/x86/mm/init.c | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index bc11dedffc45..74b157ac078d 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c | |||
| @@ -780,8 +780,30 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) | |||
| 780 | */ | 780 | */ |
| 781 | void free_kernel_image_pages(void *begin, void *end) | 781 | void free_kernel_image_pages(void *begin, void *end) |
| 782 | { | 782 | { |
| 783 | free_init_pages("unused kernel image", | 783 | unsigned long begin_ul = (unsigned long)begin; |
| 784 | (unsigned long)begin, (unsigned long)end); | 784 | unsigned long end_ul = (unsigned long)end; |
| 785 | unsigned long len_pages = (end_ul - begin_ul) >> PAGE_SHIFT; | ||
| 786 | |||
| 787 | |||
| 788 | free_init_pages("unused kernel image", begin_ul, end_ul); | ||
| 789 | |||
| 790 | /* | ||
| 791 | * PTI maps some of the kernel into userspace. For performance, | ||
| 792 | * this includes some kernel areas that do not contain secrets. | ||
| 793 | * Those areas might be adjacent to the parts of the kernel image | ||
| 794 | * being freed, which may contain secrets. Remove the "high kernel | ||
| 795 | * image mapping" for these freed areas, ensuring they are not even | ||
| 796 | * potentially vulnerable to Meltdown regardless of the specific | ||
| 797 | * optimizations PTI is currently using. | ||
| 798 | * | ||
| 799 | * The "noalias" prevents unmapping the direct map alias which is | ||
| 800 | * needed to access the freed pages. | ||
| 801 | * | ||
| 802 | * This is only valid for 64bit kernels. 32bit has only one mapping | ||
| 803 | * which can't be treated in this way for obvious reasons. | ||
| 804 | */ | ||
| 805 | if (IS_ENABLED(CONFIG_X86_64) && cpu_feature_enabled(X86_FEATURE_PTI)) | ||
| 806 | set_memory_np_noalias(begin_ul, len_pages); | ||
| 785 | } | 807 | } |
| 786 | 808 | ||
| 787 | void __ref free_initmem(void) | 809 | void __ref free_initmem(void) |
