[PATCH] powerpc: Fix preserved memory size for int-vectors
Guozihua (Scott)
guozihua at huawei.com
Sat Jan 13 18:40:10 AEDT 2024
On 2024/1/9 17:59, Christophe Leroy wrote:
>
>
> Le 09/01/2024 à 04:38, GUO Zihua a écrit :
>> [Vous ne recevez pas souvent de courriers de guozihua at huawei.com. Découvrez pourquoi ceci est important à https://aka.ms/LearnAboutSenderIdentification ]
>>
>> The first 32k of memory is reserved for interrupt vectors, however for
>> powerpc64 this might not be enough. Fix this by reserving the maximum
>> size between 32k and the real size of interrupt vectors.
>
> You say "this might not be enough". Do you have exemples of when it is
> not enough, or is it just hypothetycal ?
Hi Christophe,
The problem is discovered when I am trying to test ppc64 kaslr
(developed by Yan, ref: https://lwn.net/Articles/811686/) on QEMU. On
QEMU it seems that the size of interrupt vectors is way larger than
0x8000, resulting in the interrupt vectors code overriding memory
allocated for PACAs during do_final_fixups().
>
>>
>> Signed-off-by: GUO Zihua <guozihua at huawei.com>
>> ---
>> arch/powerpc/kernel/prom.c | 11 ++++++++++-
>> 1 file changed, 10 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
>> index 0b5878c3125b..f374487513b3 100644
>> --- a/arch/powerpc/kernel/prom.c
>> +++ b/arch/powerpc/kernel/prom.c
>> @@ -758,6 +758,7 @@ static inline void save_fscr_to_task(void) {}
>> void __init early_init_devtree(void *params)
>> {
>> phys_addr_t limit;
>> + size_t int_vector_size;
>
> Why size_t ?
>
> memblock_reserve() takes a phys_addr_t
Will fix that.
>
>>
>> DBG(" -> early_init_devtree(%px)\n", params);
>>
>> @@ -810,9 +811,17 @@ void __init early_init_devtree(void *params)
>> setup_initial_memory_limit(memstart_addr, first_memblock_size);
>> /* Reserve MEMBLOCK regions used by kernel, initrd, dt, etc... */
>> memblock_reserve(PHYSICAL_START, __pa(_end) - PHYSICAL_START);
>> +#ifdef CONFIG_PPC64
>> + /* If relocatable, reserve at least 32k for interrupt vectors etc. */
>> + int_vector_size = (size_t)((uintptr_t)__end_interrupts -
>> + (uintptr_t)_stext);
>
> Why do you need so many casts ? When I look into function
> overlaps_interrupt_vector_text() it seems to work well without cast at all.
I'll look into it.
>
>> + int_vector_size = max_t(size_t, 0x8000, int_vector_size);
>
> Use SZ_32K instead of 0x8000
>
>> +#else
>> /* If relocatable, reserve first 32k for interrupt vectors etc. */
>> + int_vector_size = 0x8000;
>
> Use SZ_32K
Sure.
>
>> +#endif
>> if (PHYSICAL_START > MEMORY_START)
>> - memblock_reserve(MEMORY_START, 0x8000);
>> + memblock_reserve(MEMORY_START, int_vector_size);
>> reserve_kdump_trampoline();
>> #if defined(CONFIG_FA_DUMP) || defined(CONFIG_PRESERVE_FA_DUMP)
>> /*
>> --
>> 2.34.1
>>
--
Best
GUO Zihua
More information about the Linuxppc-dev
mailing list