Thread (9 messages) read the whole thread 9 messages, 3 authors, 2025-03-04

Re: [PATCH] arm64: kaslr: consider parange is bigger than linear_region_size

From: Keun-O Park <hidden>
Date: 2025-02-25 04:48:03
Also in: lkml

On Mon, Feb 24, 2025 at 10:21 AM Keun-O Park [off-list ref] wrote:
quoted hunk ↗ jump to hunk
From: Keuno Park <redacted>

On systems using 4KB pages and having 39 VA_BITS, linear_region_size
gets 256GiB space. It was observed that some SoCs such as Qualcomm
QCM8550 returns 40bits of PA range from MMFR0_EL1. This leads range
value to have minus as the variable range is s64, so that all the
calculations for randomizing linear address space are skpped.
As a result of this, the kernel's linear region is not randomized.
For this case, this patch sets the range by calculating memblock
DRAM range to randomize the linear region of kernel.

Change-Id: Ib29e45f44928937881d514fb87b4cac828b5a3f5
Fixes: 97d6786e0669 ("arm64: mm: account for hotplug memory when randomizing the linear region")
Signed-off-by: Keuno Park <redacted>
---
 arch/arm64/mm/init.c | 5 +++++
 1 file changed, 5 insertions(+)
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 9c0b8d9558fc..2ee657e2d60f 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -290,6 +290,11 @@ void __init arm64_memblock_init(void)
                s64 range = linear_region_size -
                            BIT(id_aa64mmfr0_parange_to_phys_shift(parange));

+               if (range < 0) {
+                       range = linear_region_size -
+                               (memblock_end_of_DRAM() - memblock_start_of_DRAM());
+               }
+
                /*
                 * If the size of the linear region exceeds, by a sufficient
                 * margin, the size of the region that the physical memory can
--
2.34.1
36bit: linear_region_size=0x800000000 32 GB
39bit: linear_region_size=0x4000000000 256 GB
42bit: linear_region_size=0x20000000000 2048 GB, 2 TB
47bit: linear_region_size=0x400000000000 65536 GB, 64 TB
48bit: linear_region_size=0x800000000000 131072 GB, 128 TB
52bit: linear_region_size=0xf800000000000 4063232 GB, 3968 TB

The problem happens only when linear_region_size is smaller than
BIT(id_aa64mmfr0_parange_to_phys_shift(parange)).
In my case, SoC returns 2 as parange value. (va_bits is 39bit, so the
linear_region_size gets 0x4000000000, 256GB.)
#define ID_AA64MMFR0_PARANGE_40         0x2
BIT(id_aa64mmfr0_parange_to_phys_shift(parange)) == 0x10000000000, 1TB

                s64 range = linear_region_size -
                            BIT(id_aa64mmfr0_parange_to_phys_shift(parange));
As a result, range gets a negative value. 0xffffff4000000000 in here.
So this makes randomization code bypass as range is smaller than
ARM64_MEMSTART_ALIGN.

                if (memstart_offset_seed > 0 && range >=
(s64)ARM64_MEMSTART_ALIGN) {

In most cases, the hotplug memory code will be working the same as before.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help