Skip to content

Commit 2cc42ba

Browse files
jbeulichBoris Ostrovsky
authored andcommitted
x86-64/Xen: eliminate W+X mappings
A few thousand such pages are usually left around due to the re-use of L1 tables having been provided by the hypervisor (Dom0) or tool stack (DomU). Set NX in the direct map variant, which needs to be done in L2 due to the dual use of the re-used L1s. For x86_configure_nx() to actually do what it is supposed to do, call get_cpu_cap() first. This was broken by commit 4763ed4 ("x86, mm: Clean up and simplify NX enablement") when switching away from the direct EFER read. Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Juergen Gross <jgross@suse.com> Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
1 parent c4f9d9c commit 2cc42ba

File tree

2 files changed

+15
-0
lines changed

2 files changed

+15
-0
lines changed

arch/x86/xen/enlighten_pv.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@
8787
#include "multicalls.h"
8888
#include "pmu.h"
8989

90+
#include "../kernel/cpu/cpu.h" /* get_cpu_cap() */
91+
9092
void *xen_initial_gdt;
9193

9294
static int xen_cpu_up_prepare_pv(unsigned int cpu);
@@ -1249,6 +1251,7 @@ asmlinkage __visible void __init xen_start_kernel(void)
12491251
__userpte_alloc_gfp &= ~__GFP_HIGHMEM;
12501252

12511253
/* Work out if we support NX */
1254+
get_cpu_cap(&boot_cpu_data);
12521255
x86_configure_nx();
12531256

12541257
/* Get mfn list */

arch/x86/xen/mmu_pv.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1916,6 +1916,18 @@ void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn)
19161916
/* Graft it onto L4[511][510] */
19171917
copy_page(level2_kernel_pgt, l2);
19181918

1919+
/*
1920+
* Zap execute permission from the ident map. Due to the sharing of
1921+
* L1 entries we need to do this in the L2.
1922+
*/
1923+
if (__supported_pte_mask & _PAGE_NX) {
1924+
for (i = 0; i < PTRS_PER_PMD; ++i) {
1925+
if (pmd_none(level2_ident_pgt[i]))
1926+
continue;
1927+
level2_ident_pgt[i] = pmd_set_flags(level2_ident_pgt[i], _PAGE_NX);
1928+
}
1929+
}
1930+
19191931
/* Copy the initial P->M table mappings if necessary. */
19201932
i = pgd_index(xen_start_info->mfn_list);
19211933
if (i && i < pgd_index(__START_KERNEL_map))

0 commit comments

Comments
 (0)