xen/arm: Fold mmu_init_secondary_cpu() to head.S

Currently mmu_init_secondary_cpu() only enforces the page table
should not contain mapping that are both Writable and eXecutables
after boot. To ease the arch/arm/mm.c split work, fold this function
to head.S.

For arm32, the WXN bit cannot be set early because at the point when
the MMU is enabled, the page-tables may still contain mapping which
are writable and executable. Therefore, introduce an assembly macro
pt_enforce_wxn. The macro is called before secondary CPUs jumping
into the C world.

For arm64, set the SCTLR_Axx_ELx_WXN flag right when the MMU is
enabled. This would avoid the extra TLB flush and SCTLR dance.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
Co-authored-by: Julien Grall <jgrall@amazon.com>
Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
Reviewed-by: Julien Grall <jgrall@amazon.com>
Signed-off-by: Julien Grall <jgrall@amazon.com>
This commit is contained in:
Henry WangandJulien Grall authored and Julien Grall committed 2023-11-20 19:07:45 +00:00
1 parent 210e83ae56
commit ea59db96a4
5 files changed
+32 -17

No files matched your search

+20
View File
@@ -83,6 +83,25 @@
isb
.endm
/*
* Enforce Xen page-tables do not contain mapping that are both
* Writable and eXecutables.
*
* This should be called on each secondary CPU.
*/
.macro pt_enforce_wxn tmp
mrc CP32(\tmp, HSCTLR)
orr \tmp, \tmp, #SCTLR_Axx_ELx_WXN
dsb
mcr CP32(\tmp, HSCTLR)
/*
* The TLBs may cache SCTLR_EL2.WXN. So ensure it is synchronized
* before flushing the TLBs.
*/
isb
flush_xen_tlb_local \tmp
.endm
/*
* Common register usage in this file:
* r0 -
@@ -249,6 +268,7 @@ secondary_switched:
dsb
isb
flush_xen_tlb_local r0
pt_enforce_wxn r0
#ifdef CONFIG_EARLY_PRINTK
/* Use a virtual address to access the UART. */
+12 -7
View File
@@ -269,11 +269,13 @@ ENDPROC(create_page_tables)
*
* Inputs:
* x0 : Physical address of the page tables.
* x1 : Extra flags of the SCTLR.
*
* Clobbers x0 - x4
* Clobbers x0 - x5
*/
enable_mmu:
mov x4, x0
mov x5, x1
PRINT("- Turning on paging -\r\n")
/*
@@ -289,6 +291,7 @@ enable_mmu:
mrs x0, SCTLR_EL2
orr x0, x0, #SCTLR_Axx_ELx_M /* Enable MMU */
orr x0, x0, #SCTLR_Axx_ELx_C /* Enable D-cache */
orr x0, x0, x5 /* Enable extra flags */
dsb sy /* Flush PTE writes and finish reads */
msr SCTLR_EL2, x0 /* now paging is enabled */
isb /* Now, flush the icache */
@@ -303,16 +306,17 @@ ENDPROC(enable_mmu)
* Inputs:
* lr : Virtual address to return to.
*
* Clobbers x0 - x5
* Clobbers x0 - x6
*/
ENTRY(enable_secondary_cpu_mm)
mov x5, lr
mov x6, lr
load_paddr x0, init_ttbr
ldr x0, [x0]
mov x1, #SCTLR_Axx_ELx_WXN /* Enable WxN from the start */
bl enable_mmu
mov lr, x5
mov lr, x6
/* Return to the virtual address requested by the caller. */
ret
@@ -326,14 +330,15 @@ ENDPROC(enable_secondary_cpu_mm)
* Inputs:
* lr : Virtual address to return to.
*
* Clobbers x0 - x5
* Clobbers x0 - x6
*/
ENTRY(enable_boot_cpu_mm)
mov x5, lr
mov x6, lr
bl create_page_tables
load_paddr x0, boot_pgtable
mov x1, #0 /* No extra SCTLR flags */
bl enable_mmu
/*
@@ -343,7 +348,7 @@ ENTRY(enable_boot_cpu_mm)
ldr x0, =1f
br x0
1:
mov lr, x5
mov lr, x6
/*
* The 1:1 map may clash with other parts of the Xen virtual memory
* layout. As it is not used anymore, remove it completely to
-2
View File
@@ -214,8 +214,6 @@ extern void remove_early_mappings(void);
/* Allocate and initialise pagetables for a secondary CPU. Sets init_ttbr to the
* new page table */
extern int init_secondary_pagetables(int cpu);
/* Switch secondary CPUS to its own pagetables and finalise MMU setup */
extern void mmu_init_secondary_cpu(void);
/*
* For Arm32, set up the direct-mapped xenheap: up to 1GB of contiguous,
* always-mapped memory. Base must be 32MB aligned and size a multiple of 32MB.
-6
View File
@@ -326,12 +326,6 @@ void __init setup_pagetables(unsigned long boot_phys_offset)
#endif
}
/* MMU setup for secondary CPUS (which already have paging enabled) */
void mmu_init_secondary_cpu(void)
{
xen_pt_enforce_wnx();
}
#ifdef CONFIG_ARM_32
/*
* Set up the direct-mapped xenheap:
-2
View File
@@ -361,8 +361,6 @@ void start_secondary(void)
*/
update_system_features(&current_cpu_data);
mmu_init_secondary_cpu();
gic_init_secondary_cpu();
set_current(idle_vcpu[cpuid]);
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.