[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v5 04/16] arm: poison initmem when it is freed.
The current byte sequence is '0xcc' which makes sense on x86, but on ARM it is: cccccccc stclgt 12, cr12, [ip], {204} ; 0xcc Picking something more ARM applicable such as: efefefef svc 0x00efefef Creates a nice crash if one executes that code: (XEN) CPU1: Unexpected Trap: Supervisor Call But unfortunately that may not be a good choice either as in the future we may want to implement support for it. Julien suggested that we use a 4-byte insn instruction instead of trying to work with one byte. To make sure nothing goes bad we also require that the __init_[begin|end] be aligned properly. As such on ARM 32 we use the udf instruction (see A8.8.247 in ARM DDI 0406C.c) and on ARM 64 use the AARCH64_BREAK_FAULT instruction (aka brk instruction). We don't have to worry about Thumb code so this instruction is a safe to execute. Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> --- Cc: Julien Grall <julien.grall@xxxxxxx> Cc: Stefano Stabellini <sstabellini@xxxxxxxxxx> v3: New submission v4: Instead of using 0xef, use specific insn for architectures. v5: Add BUILD_BUG_ON Fix the loop to cover the full 'len' instead of 1/4 of it (used __init_begin which is a char instead of uint32_t). --- xen/arch/arm/mm.c | 15 ++++++++++++++- xen/arch/arm/xen.lds.S | 6 ++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c index 07e2037..99588a3 100644 --- a/xen/arch/arm/mm.c +++ b/xen/arch/arm/mm.c @@ -994,8 +994,21 @@ void free_init_memory(void) { paddr_t pa = virt_to_maddr(__init_begin); unsigned long len = __init_end - __init_begin; + uint32_t insn; + unsigned int i, nr = len / sizeof(insn); + uint32_t *p; + set_pte_flags_on_range(__init_begin, len, mg_rw); - memset(__init_begin, 0xcc, len); +#ifdef CONFIG_ARM_32 + /* udf instruction i.e (see A8.8.247 in ARM DDI 0406C.c) */ + insn = 0xe7f000f0; +#else + insn = AARCH64_BREAK_FAULT; +#endif + p = (uint32_t *)__init_begin; + for ( i = 0; i < nr; i++ ) + *(p + i) = insn; + set_pte_flags_on_range(__init_begin, len, mg_clear); init_domheap_pages(pa, pa + len); printk("Freed %ldkB init memory.\n", (long)(__init_end-__init_begin)>>10); diff --git a/xen/arch/arm/xen.lds.S b/xen/arch/arm/xen.lds.S index 47b910d..ddef595 100644 --- a/xen/arch/arm/xen.lds.S +++ b/xen/arch/arm/xen.lds.S @@ -221,3 +221,9 @@ SECTIONS * code running on the boot time identity map cannot cross a section boundary. */ ASSERT( _end_boot - start <= PAGE_SIZE, "Boot code is larger than 4K") +/* + * __init_[begin|end] MUST be at word size boundary otherwise we cannot + * write fault instructions in the space properly. + */ +ASSERT(IS_ALIGNED(__init_begin, 4), "__init_begin is misaligned") +ASSERT(IS_ALIGNED(__init_end, 4), "__init_end is misaligned") -- 2.4.11 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |