Opened 9 months ago

Last modified 9 months ago

#18520 assigned bug

Undefined instruction exception on arch_cpu_idle() call in QEMU with KVM (ARM image)

Reported by: Illen Owned by: davidkaroly
Priority: normal Milestone: Unscheduled
Component: System/Kernel Version: R1/Development
Keywords: Cc:
Blocked By: Blocking:
Platform: arm

Description

This happens only with qemu-system-aarch64 running with KVM accelerator (not qemu-system-arm with emulated cortex-a15 core).

Host: Lenovo Vibe K5 running postmarketOS with Linux 6.3.0

Host CPU: Qualcomm Snapdragon 415 (MSM8929)

QEMU command:

qemu-system-aarch64
-bios AAVMF32_CODE.fd -enable-kvm
-M virt -cpu host,aarch64=off -m 1024
-device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0
-drive file="haiku-mmc.image",if=none,format=raw,id=x0
-device ramfb -usb -device qemu-xhci,id=xhci 
-device usb-mouse -device usb-kbd -serial stdio -vnc :0

EDK2 firmware taken from qemu-efi-arm package from Debian Buster.

Stack trace:

usb xhci -1: starting XHCI host controller
Exception: Undefined Instruction
R00=00000001 R01=600000d3 R02=00000001 R03=00000000
R04=801efc40 R05=00000000 R06=801cc104 R07=801f0b24
R08=801f0b20 R09=30c5183d R10=7fa88c9c R11=82684fdc
R12=801cd8ac SPs=82684fd8 LRs=80065228 PC =80065268
             SPu=00000000 LRu=00000000 CPSR=60000053
PANIC: not handled!
Welcome to Kernel Debugging Land...
Thread 1 "idle thread 1" running on CPU 0
iframe 0x82684f8c (end = 0x82684fd8)
stack trace for thread 0x1 "idle thread 1"
    kernel stack: 0x82681000 to 0x82685000
frame            caller     <image>:function + offset
 0 82684e7c (+  52) 80164898   <kernel_arm> arch_debug_call_with_fault_handler() + 0x1c
 1 82684eb0 (+  56) 800c1d1c   <kernel_arm> _ZL20kernel_debugger_loopPKcS0_St9__va_listi() + 0x140
 2 82684ee8 (+  80) 800c2240   <kernel_arm> _ZL24kernel_debugger_internalPKcS0_St9__va_listi() + 0x1bc
 3 82684f38 (+  24) 800c25a0   <kernel_arm> panic() + 0x48
 4 82684f50 (+  56) 80163350   <kernel_arm> arch_arm_undefined() + 0xec
 5 82684f88 (+   4) 80162808   <kernel_arm> arm_undefined() + 0x60
iframe at 0x82684f8c
   R00 0x00000001    R01 0x600000d3    R02 0x00000001    R03 0x00000000
   R04 0x801efc40    R05 0x00000000    R06 0x801cc104    R07 0x801f0b24
   R08 0x801f0b20    R09 0x30c5183d    R10 0x7fa88c9c    R11 0x82684fdc
   R12 0x801cd8ac    SPs 0x82684fd8    LRs 0x80065228    PC  0x80065268
                     SPu 0x00000000    LRu 0x00000000   SPSR 0x60000053
 6 82684f8c (+  80) 80065268   <kernel_arm> cpu_idle() + 0x4c
 7 82684fdc (+  32) 80071f98   <kernel_arm> _start() + 0x274
 8 82684ffc (+   0) 7c15c048   

Haiku hrev57156 ARM

According to ARMv7 Reference Manual, on ARMv7 and later "Wait for Interrupt" is supported through WFI instruction (not a CP15 c7 function like done here, probably for older ARM CPUs).

Since from what I see Haiku ARM port targets ARMv7 CPU anyway, it probably makes more sense to just use WFI.

This seems to fix the problem:

diff --git a/headers/private/kernel/arch/arm/arch_cpu.h b/headers/private/kernel/arch/arm/arch_cpu.h
index a165f1ca09..b80e650425 100644
--- a/headers/private/kernel/arch/arm/arch_cpu.h
+++ b/headers/private/kernel/arch/arm/arch_cpu.h
@@ -122,9 +122,7 @@ arch_cpu_pause(void)
 static inline void
 arch_cpu_idle(void)
 {
-       uint32 Rd = 0;
-       asm volatile("mcr p15, 0, %[c7format], c7, c0, 4"
-               : : [c7format] "r" (Rd) );
+       asm volatile("wfi");
 }

Change History (3)

comment:1 by waddlesplash, 9 months ago

Owner: changed from nobody to davidkaroly
Status: newassigned

comment:2 by tqh, 9 months ago

Summary: Undefined instruction exception on arch_cpu_idle() call in QEMU with KVMUndefined instruction exception on arch_cpu_idle() call in QEMU with KVM (ARM image)

Just adding a mention that it is related to the arm image. Thanks for reporting!

comment:3 by davidkaroly, 9 months ago

Yes, wfi sounds like a good idea. We're already using ARMv7 memory barrier instructions isb and dsb instead of the respective ARMv6 cp15 instructions.

Note: See TracTickets for help on using tickets.