Am 25. Mai 2024 13:41:54 UTC schrieb Bernhard Beschow <shen...@gmail.com>:
>
>
>Am 5. März 2024 13:52:34 UTC schrieb Peter Maydell <peter.mayd...@linaro.org>:
>>From: Richard Henderson <richard.hender...@linaro.org>
>>
>>If translation is disabled, the default memory type is Device, which
>>requires alignment checking. This is more optimally done early via
>>the MemOp given to the TCG memory operation.
>>
>>Reviewed-by: Philippe Mathieu-Daudé <phi...@linaro.org>
>>Reported-by: Idan Horowitz <idan.horow...@gmail.com>
>>Signed-off-by: Richard Henderson <richard.hender...@linaro.org>
>>Message-id: 20240301204110.656742-6-richard.hender...@linaro.org
>>Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1204
>>Signed-off-by: Richard Henderson <richard.hender...@linaro.org>
>>Signed-off-by: Peter Maydell <peter.mayd...@linaro.org>
>
>Hi,
>
>This change causes an old 4.14.40 Linux kernel to panic on boot using the
>sabrelite machine:
>
>[snip]
>Alignment trap: init (1) PC=0x76f1e3d4 Instr=0x14913004 Address=0x76f34f3e FSR
>0x001
>Alignment trap: init (1) PC=0x76f1e3d8 Instr=0x148c3004 Address=0x7e8492bd FSR
>0x801
>Alignment trap: init (1) PC=0x76f0dab0 Instr=0x6823 Address=0x7e849fbb FSR
>0x001
>Alignment trap: init (1) PC=0x76f0dab2 Instr=0x6864 Address=0x7e849fbf FSR
>0x001
>scsi 0:0:0:0: Direct-Access QEMU QEMU HARDDISK 2.5+ PQ: 0 ANSI: 5
>fsl-asoc-card sound: ASoC: CODEC DAI sgtl5000 not registered
>imx-sgtl5000 sound: ASoC: CODEC DAI sgtl5000 not registered
>imx-sgtl5000 sound: snd_soc_register_card failed (-517)
>Alignment trap: init (1) PC=0x76eac95a Instr=0xf8dd5015 Address=0x7e849b05 FSR
>0x001
>Alignment trap: not handling instruction f8dd5015 at [<76eac95a>]
>Unhandled fault: alignment exception (0x001) at 0x7e849b05
>pgd = 9c59c000
>[7e849b05] *pgd=2c552831, *pte=109eb34f, *ppte=109eb83f
>Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000007
>
>---[ end Kernel panic - not syncing: Attempted to kill init!
>exitcode=0x00000007
>
>As you can see, some alignment exceptions are handled by the kernel, the last
>one isn't. I added some additional printk()'s and traced it down to this
>location in the kernel:
><https://github.com/torvalds/linux/blob/v4.14/arch/arm/mm/alignment.c#L762>
>which claims that ARMv6++ CPUs can handle up to word-sized unaligned accesses,
>thus no fixup is needed.
>
>I hope that this will be sufficient for a fix. Let me know if you need any
>additional information.
I'm performing a direct kernel boot. On real hardware, a bootloader is involved
which probably enables unaligned access. This may explain why it works there
but not in QEMU any longer.
To fix direct kernel boot, it seems as if the "built-in bootloader" would need
to be adapted/extended [1]. Any ideas?
Best regards,
Bernhard
[1]
https://stackoverflow.com/questions/68949890/how-does-qemu-emulate-a-kernel-without-a-bootloader
>
>Best regards,
>Bernhard
>
>>---
>> target/arm/tcg/hflags.c | 34 ++++++++++++++++++++++++++++++++--
>> 1 file changed, 32 insertions(+), 2 deletions(-)
>>
>>diff --git a/target/arm/tcg/hflags.c b/target/arm/tcg/hflags.c
>>index 8e5d35d9227..5da1b0fc1d4 100644
>>--- a/target/arm/tcg/hflags.c
>>+++ b/target/arm/tcg/hflags.c
>>@@ -26,6 +26,35 @@ static inline bool fgt_svc(CPUARMState *env, int el)
>> FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, SVC_EL1);
>> }
>>
>>+/* Return true if memory alignment should be enforced. */
>>+static bool aprofile_require_alignment(CPUARMState *env, int el, uint64_t
>>sctlr)
>>+{
>>+#ifdef CONFIG_USER_ONLY
>>+ return false;
>>+#else
>>+ /* Check the alignment enable bit. */
>>+ if (sctlr & SCTLR_A) {
>>+ return true;
>>+ }
>>+
>>+ /*
>>+ * If translation is disabled, then the default memory type is
>>+ * Device(-nGnRnE) instead of Normal, which requires that alignment
>>+ * be enforced. Since this affects all ram, it is most efficient
>>+ * to handle this during translation.
>>+ */
>>+ if (sctlr & SCTLR_M) {
>>+ /* Translation enabled: memory type in PTE via MAIR_ELx. */
>>+ return false;
>>+ }
>>+ if (el < 2 && (arm_hcr_el2_eff(env) & (HCR_DC | HCR_VM))) {
>>+ /* Stage 2 translation enabled: memory type in PTE. */
>>+ return false;
>>+ }
>>+ return true;
>>+#endif
>>+}
>>+
>> static CPUARMTBFlags rebuild_hflags_common(CPUARMState *env, int fp_el,
>> ARMMMUIdx mmu_idx,
>> CPUARMTBFlags flags)
>>@@ -121,8 +150,9 @@ static CPUARMTBFlags rebuild_hflags_a32(CPUARMState *env,
>>int fp_el,
>> {
>> CPUARMTBFlags flags = {};
>> int el = arm_current_el(env);
>>+ uint64_t sctlr = arm_sctlr(env, el);
>>
>>- if (arm_sctlr(env, el) & SCTLR_A) {
>>+ if (aprofile_require_alignment(env, el, sctlr)) {
>> DP_TBFLAG_ANY(flags, ALIGN_MEM, 1);
>> }
>>
>>@@ -223,7 +253,7 @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env,
>>int el, int fp_el,
>>
>> sctlr = regime_sctlr(env, stage1);
>>
>>- if (sctlr & SCTLR_A) {
>>+ if (aprofile_require_alignment(env, el, sctlr)) {
>> DP_TBFLAG_ANY(flags, ALIGN_MEM, 1);
>> }
>>