<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/138019>138019</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
arm64 Linux kernel boot failure after b326cb6792b3951881d63d5a02ea163921da18d9
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
nathanchance
</td>
</tr>
</table>
<pre>
After https://github.com/llvm/llvm-project/commit/b326cb6792b3951881d63d5a02ea163921da18d9, arm64 Linux kernel builds fail to boot on certain platforms ([initially reported on LKML](https://lore.kernel.org/CA+G9fYve7+nXJNoV48TksXoMeVjgJuP8Gs=+1br+Qur1DPWV4A@mail.gmail.com/), [downstream report](https://github.com/ClangBuiltLinux/linux/issues/2082)). As this happens early in boot (before the serial driver) and the only platform I have access to is an FVP (so limited debug options), I was able to narrow this hang to a change in `create_init_idmap()` in [`arch/arm64/kernel/pi/map_range.c`](https://elixir.bootlin.com/linux/v6.15-rc4/source/arch/arm64/kernel/pi/map_range.c#L93) with the help of [a hack patch to undo that change dynamically](https://gist.github.com/nathanchance/6a219cb868a3c6098debb82896d82612).
[map_range.i.txt](https://github.com/user-attachments/files/19983705/map_range.i.txt)
[map_range.unopt.ll.txt](https://github.com/user-attachments/files/19983706/map_range.unopt.ll.txt)
[good-map_range.opt.ll.txt](https://github.com/user-attachments/files/19983708/good-map_range.opt.ll.txt)
[bad-map_range.opt.ll.txt](https://github.com/user-attachments/files/19983709/bad-map_range.opt.ll.txt)
The diff of the optimized IR:
```diff
diff --git a/good-map_range.opt.ll.txt b/bad-map_range.opt.ll.txt
index 9eef147..e98844b 100644
--- a/good-map_range.opt.ll.txt
+++ b/bad-map_range.opt.ll.txt
@@ -141,23 +141,24 @@ entry:
%add = add i64 %0, 4096
store i64 %add, ptr %ptep, align 8
%1 = load i8, ptr @arm64_use_ng_mappings, align 1, !range !11, !noundef !12
- %loadedv = trunc nuw i8 %1 to i1
- %or = select i1 %loadedv, i64 2051, i64 3
- %2 = call i64 asm "mrs $0, tcr_el1", "=r"() #3, !srcloc !8
- %and.i = and i64 %2, 576460752303423488
+ %2 = zext nneg i8 %1 to i64
+ %cond = shl nuw nsw i64 %2, 11
+ %3 = call i64 asm "mrs $0, tcr_el1", "=r"() #3, !srcloc !8
+ %and.i = and i64 %3, 576460752303423488
%tobool.i.not = icmp eq i64 %and.i, 0
%cond1 = select i1 %tobool.i.not, i64 768, i64 0
- %or2 = or disjoint i64 %cond1, %or
- %or6 = or disjoint i64 %or2, 29273397577909248
- %or8 = or disjoint i64 %or2, 18014398509483136
+ %or = or disjoint i64 %cond1, %cond
+ %or6 = or disjoint i64 %or, 29273397577909251
+ %and = and i64 %or6, 18014398509485827
+ %or8 = or disjoint i64 %and, 128
%not = xor i64 %clrmask, -1
%and22 = and i64 %or8, %not
%and25 = and i64 %or6, %not
call void @map_range(ptr noundef nonnull %ptep, i64 noundef ptrtoint (ptr @_stext to i64), i64 noundef ptrtoint (ptr @__initdata_begin to i64), i64 noundef ptrtoint (ptr @_stext to i64), i64 %and22, i32 noundef 0, ptr noundef %pg_dir, i1 noundef false, i64 noundef 0) #4
call void @map_range(ptr noundef nonnull %ptep, i64 noundef ptrtoint (ptr @__initdata_begin to i64), i64 noundef ptrtoint (ptr @_end to i64), i64 noundef ptrtoint (ptr @__initdata_begin to i64), i64 %and25, i32 noundef 0, ptr noundef %pg_dir, i1 noundef false, i64 noundef 0) #4
- %3 = load i64, ptr %ptep, align 8
+ %4 = load i64, ptr %ptep, align 8
call void @llvm.lifetime.end.p0(i64 8, ptr nonnull %ptep) #5
- ret i64 %3
+ ret i64 %4
}
; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
```
The object file diff:
```diff
diff --git a/tmp/.psub.9lwVS5WRhB b/tmp/.psub.RgCvbpYhdV
index 7c4d9d9..c046c52 100644
--- a/tmp/.psub.9lwVS5WRhB
+++ b/tmp/.psub.RgCvbpYhdV
@@ -1,5 +1,5 @@
-build/linux/good/arch/arm64/kernel/pi/map_range.o: file format elf64-littleaarch64
+build/linux/bad/arch/arm64/kernel/pi/map_range.o: file format elf64-littleaarch64
Disassembly of section .init.text:
@@ -128,52 +128,47 @@ create_init_idmap>:
d10103ff sub sp, sp, #0x40
90000008 adrp x8, 0x0 <map_range>
00000000000001dc: R_AARCH64_ADR_PREL_PG_HI21 arm64_use_ng_mappings
- 52810069 mov w9, #0x803 // =2051
- d538204a mrs x10, TCR_EL1
+ d5382049 mrs x9, TCR_EL1
+ f245013f tst x9, #0x800000000000000
39400108 ldrb w8, [x8]
00000000000001e8: R_AARCH64_LDST8_ABS_LO12_NC arm64_use_ng_mappings
- d280900b mov x11, #0x480 // =1152
+ 52806009 mov w9, #0x300 // =768
a90257f6 stp x22, x21, [sp, #0x20]
- f2e0080b movk x11, #0x40, lsl #48
+ 9a9f0129 csel x9, x9, xzr, eq
a9034ff4 stp x20, x19, [sp, #0x30]
aa0103f3 mov x19, x1
- 7100011f cmp w8, #0x0
- 52800068 mov w8, #0x3 // =3
+ aa082d28 orr x8, x9, x8, lsl #11
+ d2808069 mov x9, #0x403 // =1027
aa0003f4 mov x20, x0
- 9a881128 csel x8, x9, x8, ne
- f245015f tst x10, #0x800000000000000
- 52806009 mov w9, #0x300 // =768
- 9a9f0129 csel x9, x9, xzr, eq
+ f2e00d09 movk x9, #0x68, lsl #48
90000015 adrp x21, 0x0 <map_range>
- 000000000000021c: R_AARCH64_ADR_PREL_PG_HI21 __initdata_begin
+ 0000000000000210: R_AARCH64_ADR_PREL_PG_HI21 __initdata_begin
910002b5 add x21, x21, #0x0
- 0000000000000220: R_AARCH64_ADD_ABS_LO12_NC __initdata_begin
- aa080128 orr x8, x9, x8
- d2808009 mov x9, #0x400 // =1024
+ 0000000000000214: R_AARCH64_ADD_ABS_LO12_NC __initdata_begin
+ aa090116 orr x22, x8, x9
+ 91400408 add x8, x0, #0x1, lsl #12 // =0x1000
90000001 adrp x1, 0x0 <map_range>
- 000000000000022c: R_AARCH64_ADR_PREL_PG_HI21 _stext
+ 0000000000000220: R_AARCH64_ADR_PREL_PG_HI21 _stext
91000021 add x1, x1, #0x0
- 0000000000000230: R_AARCH64_ADD_ABS_LO12_NC _stext
- f2e00d09 movk x9, #0x68, lsl #48
- 9140040a add x10, x0, #0x1, lsl #12 // =0x1000
- aa090116 orr x22, x8, x9
- aa0b0108 orr x8, x8, x11
+ 0000000000000224: R_AARCH64_ADD_ABS_LO12_NC _stext
+ 924af2c9 and x9, x22, #0xffc7ffffffffffff
+ a90023ff stp xzr, x8, [sp]
+ b2790128 orr x8, x9, #0x80
910023e0 add x0, sp, #0x8
- 8a330104 bic x4, x8, x19
aa1503e2 mov x2, x21
+ 8a330104 bic x4, x8, x19
aa0103e3 mov x3, x1
2a1f03e5 mov w5, wzr
aa1403e6 mov x6, x20
2a1f03e7 mov w7, wzr
a9017bfd stp x29, x30, [sp, #0x10]
910043fd add x29, sp, #0x10
- a9002bff stp xzr, x10, [sp]
- 94000000 bl 0x26c <create_init_idmap+0x94>
- 000000000000026c: R_AARCH64_CALL26 map_range
+ 94000000 bl 0x258 <create_init_idmap+0x80>
+ 0000000000000258: R_AARCH64_CALL26 map_range
90000002 adrp x2, 0x0 <map_range>
- 0000000000000270: R_AARCH64_ADR_PREL_PG_HI21 _end
+ 000000000000025c: R_AARCH64_ADR_PREL_PG_HI21 _end
91000042 add x2, x2, #0x0
- 0000000000000274: R_AARCH64_ADD_ABS_LO12_NC _end
+ 0000000000000260: R_AARCH64_ADD_ABS_LO12_NC _end
910023e0 add x0, sp, #0x8
8a3302c4 bic x4, x22, x19
aa1503e1 mov x1, x21
@@ -182,8 +177,8 @@ create_init_idmap>:
aa1403e6 mov x6, x20
2a1f03e7 mov w7, wzr
f90003ff str xzr, [sp]
- 94000000 bl 0x298 <create_init_idmap+0xc0>
- 0000000000000298: R_AARCH64_CALL26 map_range
+ 94000000 bl 0x284 <create_init_idmap+0xac>
+ 0000000000000284: R_AARCH64_CALL26 map_range
a9434ff4 ldp x20, x19, [sp, #0x30]
f94007e0 ldr x0, [sp, #0x8]
a94257f6 ldp x22, x21, [sp, #0x20]
```
If I replace `arch/arm64/kernel/pi/map_range.o` by running `llc --filetype obj` on either the good optimized IR or the unoptimized IR, the kernel boots fine. As soon as I use the bad optimized IR, there is a hang. My initial suspicion is that `PAGE_KERNEL_ROX` is not getting optimized correctly but my assembly knowledge is not very good so I might be misunderstanding something.
The command to generate the `.o` from the `.i` if necessary.
```
clang --target=aarch64-linux-gnu -fintegrated-as -mlittle-endian -std=gnu11 -fshort-wchar -funsigned-char -fno-common -fno-PIE -fno-strict-aliasing -mgeneral-regs-only -Wno-psabi -fno-asynchronous-unwind-tables -fno-unwind-tables -mbranch-protection=pac-ret+bti -Wa,-march=armv8.5-a -fno-delete-null-pointer-checks -O2 -fstack-protector-strong -fno-omit-frame-pointer -fno-optimize-sibling-calls -ftrivial-auto-var-init=zero -fno-stack-clash-protection -falign-functions=4 -fstrict-flex-arrays=3 -fno-strict-overflow -fno-stack-check -fno-builtin-wcslen -Wall -Wundef -Werror=implicit-function-declaration -Werror=implicit-int -Werror=return-type -Werror=strict-prototypes -Wno-format-security -Wno-trigraphs -Wno-frame-address -Wno-address-of-packed-member -Wmissing-declarations -Wmissing-prototypes -Wframe-larger-than=2048 -Wno-gnu -Wno-format-overflow-non-kprintf -Wno-format-truncation-non-kprintf -Wvla -Wno-pointer-sign -Wcast-function-type -Wimplicit-fallthrough -Werror=date-time -Werror=incompatible-pointer-types-Wenum-conversion -Wextra -Wunused -Wno-unused-but-set-variable -Wno-unused-const-variable -Wno-format-overflow -Wno-override-init -Wno-pointer-to-enum-cast -Wno-tautological-constant-out-of-range-compare -Wno-unaligned-access -Wno-enum-compare-conditional -Wno-missing-field-initializers -Wno-type-limits -Wno-shift-negative-value -Wno-enum-enum-conversion -Wno-sign-compare -Wno-unused-parameter -mstack-protector-guard=sysreg -mstack-protector-guard-reg=sp_el0 -mstack-protector-guard-offset=1240 -fpie -Os -mbranch-protection=none -fno-stack-protector -ffreestanding -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-addrsig -mstrict-align -c map_range.i
```
Please feel free to give this issue a more descriptive title if necessary.
cc @andjo403 @nikic @dtcxzyw
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJy0Wl1z4yjW_jXqGwoXoA9LF7nIR2e2dzMz_fZMdc9euZCEZCYItIASu3_9W4Aky06cuHdnXN2JIsH5eM5zDgcZagxvJWNXUXoTpXcf6GC3Sl9JardUVu4_-1Cqen913Vimwdba3kTxdUTuI3LfcrsdylWluojcC_E0_YK9Vn-yykbkvlJdx91FGZOsKrN1Qcq4SHGe4zqL65QiwijO4oLgmuK8LiJyC6jusgQ8cDnswCPTkglQDlzUBjSUC2AVKJWyQElQMW0pl6AX1DZKdwZEJI_SGy655VSIPdCsV9qy2o1--NfPD1F6F5H82A-hNFsFRSul24jc315H5Oanovn3E1tH5Eb-8c9f1Nck__3R_KF-Zl__bP85fM5_MlF8F5EbXOqI3PzfoPHd529fk-soQR3lYtX6nwGdiHjPovSmVs_SWM1oN9r2mkVHyN4KKtubgQvrIXEGj7-5MQMzEbknKCdeRbEC1wbYLTdgS_ueSQMY1WIPuAygRSQvWaM0A3bLgGGaUwFqzZ-YjkgBqKz9AyXFfkYVfAJb-sQArSpmjMOfG0AluP_62ckzCgjecQdyzcqhBaq3XEkz-vwJPFMDaCmYmymp1up5slC27h4Fjmktc0ZGGao0o5ZtXAw3vO5o72JKiihDfkB6E2WI6mobkXvPlIjch-BF5L7nEbnvaL_RTuCqijL0Gr5M8B3XK4eI4HJi8IjqU7bCKdSVE2zUoCvmNV2okMQPReygfOZ267HcMtED1TjLKdjS6hH01FZb5_kgawXsltoJgXovaccrR93XeWHs6ogcy0yNyH1GCS6qMs9yGlcZKvKalWVO8iKrc5JhR5JVhK7dv_TmYDZf2d37RBwM05BaS6ttx6R1xGu48ATERZHHa5QegRGkkuJU2yBVb1dC_EVKsyOlR8In3a1SNTyM-UvV527KWfmTBSX92wwoXHk9Jz7oR9e_bxmoedM4IvoE7y3v-HdWg09fnOLAiQyFf25khK79BAhbbgF9y0tQvmUCuuayZjtQMNbgZL1asSLPk6QEGKEsSSJ0DSF8W4GzjdyEf-8pixIUJQhAnOCI3JIYuBIdrhMwPmTS6n1wGwAQkZTWNYjiO-B-8yxxt5ArXgkqsjDIWFc0x2e0rt3T3mr3V29Z79ctwVsJ8lko9iKFojXg-Tw-Qb6IbAbDNrLddLTvuWzNQQD2KwXB3jd3gac7Ug2yZo2_RxxuXo1TwOonr8zqQVZADs-A58EEV63xPFZpP8wwwSoLOF7MdzqcewSleLqO54nEz3OFyT-gpgMRIZ12K27iobKV3jCBI0KCtSSK77T_y1VvEJE4Ht0wuhKqclf5LJ_KesVDCOQcAi8pXWdJhtYpiVGckDjJ88CGhVnf2c4CKVl75HWWLAZWSoYIm63w-EjzfKQG48Xo-G_zdtLwqr_xWX8DoawqlRIrvpJuJY_vAK-6HrD_zLR0Qp0MNE9xfuOXMV9KmoK9zvLpEi0IEyBWGtTc_Km4tJM2Lzo4mSq9mJGdm6G0R4sUZB3HxTpdrwtUkCRfzM3fmYtzhJO4yFNUJHmM42yB6Ujud0x110eT3jD3FWtTfBzF0xgqnb2wM83J-kjlWS-p9IUFk0PQp1jvlJ7dEbqj5tGNhPhQw2RNyEtz8tFvF-nl0PSM5cuhPgOeFK-Bb2rHehuR3FWyqRpJJeUgxLISOonT495q610cp0UJ2hjrMnZM0tAmvjfF94M1tXRTspbLH5t8Rt8Emv87JrMINBXrQ8FN-3ZTc08Ijuf7DRWGnRqAxgKQ_L0Y_k-AMNfn_6XwT6z6-7CEi9IcFlVnwBur8JRvyeVTTuPltrMrwRtmecdWTNarHkUkdybmB8dOYuctToPFmtlDdR9NWtzzHInWd_6X-x_fgPtBVm4DBa6t1a4rBFI5o0q3dZCq0YwBqczeLfRqkM9c1sD0rBoEtX6b9cyF0MwOWoKOdUrvI5JLJdncDM593qE3VKXbsQPXWvo-8dKe0HZ9RO5XvRnKVSGev_6WfvuyDT3a8tGX9vap7P-9rb_O7eC6SuqiLlarCiVZlZKX7eDrsl_0gmf1zJ1gRG5T3waGC397RBz6NwuL3Z_rQS_f7ymPU-Fhc1tlagETTZZAwa0VjDoxUx9yqqmkf4ciT6M7bqgxrCvF3jX8hgVCrVwSr1wtHHvfJUiucbl1DRW5CdfJemqXX-7I449T91xjhFHcNMB9IlSYoXQ_fV6FnxGJ0S4AXiD_yafBtNZ9hIqdzyW0QyCKbw8lMv4YbCwiNE4cP7iuXFp82Vxff7n9R5Zsru--bD5_-fiw-fzT5h-fCHaiX22yXU6mJHdUKyYjOvUUoeK5mG3NUQyOPmFb5qqIb46dkDqNc4ISOgvRxjmCfbn7_fbL5uPD1CiMQ4vFsOLlqIYkKcLxjKM1dh45WnX0cdDERYIQPsApau3Af87Hd0273G0vz2DI8mMMH-5--z3fXN_8tnn4FZPNL7dvgliT3AksDwDupm2Ki3aOzgCIcUpGj1OSowyh83GIEVrMdO2pIxwtEEnXTTYTznoKhVV8R_Do-4J7BAUYIGgIQyifrX48NdtHTxjhl5xpCSlo0SBMZjsrw8QcmvHnd7-asf84C2mB4qRpklMDvfAdLl4aGI8GAkCpz6b4GJNx0i5Qb41d-PDMlKrrD0F34tBEc4RQlp_AexgWL8Cd1iZKUU5qMk9SWs_5ObqaLzCaN02ODvmLnFqwNzmfUxj57tg7j1B8AG4UMgIXvCponmNM8mUgXlgn2Rhtl1LpaUqFHD2TU_AyWp5xJXAUHijzPl1C7jOE6iOVj8fwZfkpM8daitPTWhoy4PViCl8pBAS_X0xP279xDX5NGPpvhAFQOFKTcuFNfXBmyuqZ3K9pJl7zkeq7k3L2imboKY_wO5SfSl7-ghhHHEfHtE7ewCk5xekCY8cMLRDG2Ym5Y_mbrB4rF04QSpbLbX1w7ZAFeJnR5IjQaIfHtWZau_GSaz9KNXIB1fxe7Txw5AKCTSJGWiGCTxDAYzl9l1TxBaSatMFDHl-Yw3CKED21D70dolcCBC9mhh9ZLvuGI8qHn1NlfzUEyeWgeBqShDak8rBQWR-K4fTyLEa7pqnWzeIzsb1wQVh0l2EtDfVzlx-WUr9--h0BWRdvp_NY-Wd-kJihE_zRSfcagpXTOEYYzetTySs3OFnCVowrGU5RzMjpSjYVs2DqLO8dWa4lYKctQTx3BAAQihsUs_RkyfJ78efvejIpQTHLTsRkwSS0lLM-kbM-klMgvC6betnZhGjG6GVng-fOxiGdxE19WuCLE6jxSGYX-PJc4DE6iTwErhV2nzk4btFFO5JVrji98p3iDdoVyRu1KjupVbfXDw8kc6jMhW6k9xnNaX5ec46C5jMZluYX6J5LMnnRAvxgWV5fUFPZ9Nb0VXsvqOtBwFSSE3JKhEDE90vy-v2V801bsxfOnpn_Q9UhJDOpXi8OYw0-rg74tMlfVIdpU567ibnfk6_X4fL9LfkPpfqZNG8K34sv8k8f8u-ixCveoH-F3mBjcQn530q8PDmvmVZvJl6eXJR4tEiOtniivniL1zir1wdOiVrPnDqeks-bwiI52vFO2t7f8b581_epAZ-AZr2gFQOXH6RQUYZAuQd6kJLL1s0UogIQNlwwu-_9C0Q3RknAuN0y7b9lbpWqj75qBio88N_SH76AJrf-7nTYRylrQMMl86dZjFISUAM-gcGEYyslPZY6ztfMH0zx50pW4Oc9GI8BATOYnldcSffcH7eIMvT5-qePm399_PLLx4fNl1__8MdLDJDKgpZZ65w8qKiU1qyyYg_KwYJuD-a3a49SPQtWt2ya_MT0PvhtFPgEOt5uLSgZ6LgZZM20sVTWTrpRHbNbLtvV4S1spbqOhlfzLZNMUxscjjIUQtBo1c13uLe5AZJVzBiq96uXIa8ElS2A0FLdMhvFd-ObQujfQsJWDgA2XFrWOmU1pAbALrxThEzWnEoAja2j-K6VA8YANmartIXP1ZZqAJtB-gNkNRz_lgo6J5QM158_fQwXxmpeWUgFp8Z5D7vgoICatQb680bwm1SwN7TkYQ41e1lttZJqMDC86Ib-DbcJz09udaWmstrCXisbXnhG8V1PK6iZjchNaTmA32hEbmHnWR_fUd095asU0iCvZoJZBuUgBOyVA0XDasuqRwPgr8S5bmn1OMlX2jmlnC9usuq4hY2mHZvmjvdHEkHDS8FlCysqhHPAav7EqYB0sAo-UQ0dW6P47jvTasLMqasENUunAGz89xUO-yoctIrvEm-dh7gRbAep1nTvHsRH8Ksnphuhno_kOw_DjXLgwnIJnysjmHRoCQHgt_BVDPzGtFY6iu941wteOXdHC2DNKkE1Dea9HMelXdwOX01AXzUOd0cLnZ_KPTKBDuFdNzSsGjS3I0es5q2m_XYa41Gnda2ZGW-Nf0DVwJ5Wj6yGHetKF5NvHTeOgUubzeL2kQFBsnC5o6HdUulfASd5UOKTZ2HkhC6USsLHXnNpm6MB_nSG13gy5EnQkf0j7VxSAfitomaB8ojYAX4qhN1qNbTbBZA1tQxa3i3B5bJSXU8tL8VMTy_OwG9MDh2slHxi2ozx21lNfdwHw-pgWLiG5eBiYR1fuf-uafmwUtKcPjqBJtx0f2leM0_5Y8etgsEgasYn1iWIUC2vqAgqqLRQDdYF169O0DunZ2N8erhaFs4r-rujl36ck1JzBykV4ekU_IYzUcNx2eDfmR5nO6igP-Q43jBb3lgoWUstf2LwiYqBLRS9xNTNcUl7YqrHraeOZr5idKclph2odtXX7I1m7bkBroi6Qf2GCXR2kGoa49cATFxz2fScAfjrucoplWTLOjFLA7BpNGPzQvbf1OpmzFHDg0_T4uBYX4HFEcKXHcxnwahhoGFMAP9dqFss-RMLZ0r9kVhAQac0AzUzlea99U-5Fey11bKq_JksWf-pEhS7a8kfub9Z22r3ff_8ob6K6yIu6Ad2hddJhpIErYsP2ytWF2VGWUHjGq_jEmdVjekarTEqCIlZ9oFfEURSlMSI-OMgqzVZJ3WesYTkeM3iLEoQ88eE_RfNSrcfvANXOM4RLj4IWjJh_OFsQiR7Du5FhETp3Qd95Q9bl0NrogQJbqw5iPHuXr12klop689RD5oB6k91X3o2-8OgxdUPHwGfDymPPj1dkf8PAAD__-36bjk">