xen/arm64: smpboot: Directly switch to the runtime page-tables

Switching TTBR while the MMU is on is not safe. Now that the identity
mapping will not clash with the rest of the memory layout, we can avoid
creating temporary page-tables every time a CPU is brought up.

The arm32 code will use a different approach. So this issue is for now
only resolved on arm64.

Signed-off-by: Julien Grall <jgrall@amazon.com>
Reviewed-by: Luca Fancellu <luca.fancellu@arm.com>
Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
Tested-by: Henry Wang <Henry.Wang@arm.com>
This commit is contained in:
Julien Grall committed 2023-04-19 19:39:58 +01:00
1 parent c4b72c4a54
commit dff17457c4
5 files changed
+29 -21

No files matched your search

+4
View File
@@ -21,6 +21,10 @@ int arch_cpu_up(int cpu)
return platform_cpu_up(cpu);
}
void arch_cpu_up_finish(void)
{
}
/*
* Local variables:
* mode: C
+9 -20
View File
@@ -308,6 +308,7 @@ real_start_efi:
bl check_cpu_mode
bl cpu_init
bl create_page_tables
load_paddr x0, boot_pgtable
bl enable_mmu
/* We are still in the 1:1 mapping. Jump to the runtime Virtual Address. */
@@ -365,29 +366,14 @@ GLOBAL(init_secondary)
#endif
bl check_cpu_mode
bl cpu_init
bl create_page_tables
load_paddr x0, init_ttbr
ldr x0, [x0]
bl enable_mmu
/* We are still in the 1:1 mapping. Jump to the runtime Virtual Address. */
ldr x0, =secondary_switched
br x0
secondary_switched:
/*
* Non-boot CPUs need to move on to the proper pagetables, which were
* setup in init_secondary_pagetables.
*
* XXX: This is not compliant with the Arm Arm.
*/
ldr x4, =init_ttbr /* VA of TTBR0_EL2 stashed by CPU 0 */
ldr x4, [x4] /* Actual value */
dsb sy
msr TTBR0_EL2, x4
dsb sy
isb
tlbi alle2
dsb sy /* Ensure completion of TLB flush */
isb
#ifdef CONFIG_EARLY_PRINTK
/* Use a virtual address to access the UART. */
ldr x23, =EARLY_UART_VIRTUAL_ADDRESS
@@ -672,9 +658,13 @@ ENDPROC(create_page_tables)
* mapping. In other word, the caller is responsible to switch to the runtime
* mapping.
*
* Clobbers x0 - x3
* Inputs:
* x0 : Physical address of the page tables.
*
* Clobbers x0 - x4
*/
enable_mmu:
mov x4, x0
PRINT("- Turning on paging -\r\n")
/*
@@ -685,8 +675,7 @@ enable_mmu:
dsb nsh
/* Write Xen's PT's paddr into TTBR0_EL2 */
load_paddr x0, boot_pgtable
msr TTBR0_EL2, x0
msr TTBR0_EL2, x4
isb
mrs x0, SCTLR_EL2
+14 -1
View File
@@ -106,10 +106,23 @@ int __init arch_cpu_init(int cpu, struct dt_device_node *dn)
int arch_cpu_up(int cpu)
{
int rc;
if ( !smp_enable_ops[cpu].prepare_cpu )
return -ENODEV;
return smp_enable_ops[cpu].prepare_cpu(cpu);
update_identity_mapping(true);
rc = smp_enable_ops[cpu].prepare_cpu(cpu);
if ( rc )
update_identity_mapping(false);
return rc;
}
void arch_cpu_up_finish(void)
{
update_identity_mapping(false);
}
/*
+1
View File
@@ -25,6 +25,7 @@ extern void noreturn stop_cpu(void);
extern int arch_smp_init(void);
extern int arch_cpu_init(int cpu, struct dt_device_node *dn);
extern int arch_cpu_up(int cpu);
extern void arch_cpu_up_finish(void);
int cpu_up_send_sgi(int cpu);
+1
View File
@@ -500,6 +500,7 @@ int __cpu_up(unsigned int cpu)
init_data.cpuid = ~0;
smp_up_cpu = MPIDR_INVALID;
clean_dcache(smp_up_cpu);
arch_cpu_up_finish();
if ( !cpu_online(cpu) )
{
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.