__ro_after_init was introduced recently to prevent modifying
some variables after init.
At the moment, on Arm, the variables will still be accessible
because the region permission is not updated.
Address that by moving the sections .data.ro_after_init
out of .data and then map the region read-only once we finish
to boot.
Signed-off-by: Julien Grall <jgrall@amazon.com>
Reviewed-by: Penny Zheng <penny.zheng@arm.com>
Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
Tested-by: Henry Wang <Henry.Wang@arm.com>
int map_range_to_domain(const struct dt_device_node *dev,
u64 addr, u64 len, void *data);
+extern const char __ro_after_init_start[], __ro_after_init_end[];
+
#endif
/*
* Local variables:
static __used void init_done(void)
{
+ int rc;
+
/* Must be done past setting system_state. */
unregister_init_virtual_region();
free_init_memory();
+
+ /*
+ * We have finished booting. Mark the section .data.ro_after_init
+ * read-only.
+ */
+ rc = modify_xen_mappings((unsigned long)&__ro_after_init_start,
+ (unsigned long)&__ro_after_init_end,
+ PAGE_HYPERVISOR_RO);
+ if ( rc )
+ panic("Unable to mark the .data.ro_after_init section read-only (rc = %d)\n",
+ rc);
+
startup_cpu_idle_loop();
}
_erodata = .; /* End of read-only data */
. = ALIGN(PAGE_SIZE);
+ .data.ro_after_init : {
+ __ro_after_init_start = .;
+ *(.data.ro_after_init)
+ . = ALIGN(PAGE_SIZE);
+ __ro_after_init_end = .;
+ } : text
+
.data.read_mostly : {
/* Exception table */
__start___ex_table = .;