Skip to content

arm64: dts: qcom: shikra: crypto@1b3a000 probe takes fatal external abort (SError) on QCE version read with Ubuntu/Debian builds #1135

Description

@nivasnaik

Ubuntu/Debian builds fail to boot to shell on Shikra device with qcom-next kernel whereas no issue is seen on Yocto builds.
This device reboots when qcrypto module is loaded/probe happens. On Yocto this probe never happens.
After blacklisting qcrpto module the device to boot to shell on Ubutu.
Attaching the Claude analysis on this below.

On Shikra EVK, loading the qcrypto module panics the board. qce_crypto_probe()
reaches qce_get_version(), whose first register read of the crypto block takes an
external abort. Boot dies at ~10.8 s, every cycle, before userspace comes up.

The block appears not to be clocked (or not assigned to the HLOS VM under Gunyah)
at the moment QCE probes it. crypto@1b3a000 votes only the memory interconnect
path and takes no clock or power-domain reference, and on Shikra — unlike other
SoCs using the same compatible — the RPM_SMD_CE1_CLK handle lives on the
firmware/scm node, where it is enabled only transiently around SCM calls.

As far as we can tell the block has never been successfully probed on this SoC:
the only userspace that boots does so because cryptobam has no driver bound, so
QCE parks in deferred probe and never touches the registers (see "Reproducer").

Affected

  • Branch: qcom-next @ d49c33864d06 (= tag qcom-next-7.2-20260826)
  • Running kernel string: 7.2.0-01462-gd49c33864d06
  • File: arch/arm64/boot/dts/qcom/shikra.dtsi
    • crypto: crypto@1b3a000 — line 1348
    • firmware/scm CE1 clock — line 192
  • Board: Shikra EVK (shikra-iqs-evk, also present in -cqs/-cqm)
  • Not reproducible on main, which has no crypto node yet.

Failure signature

Asynchronous delivery (fatal):

[   10.798068] SError Interrupt on CPU3, code 0x00000000be000000
[   10.798237] Kernel panic - not syncing: Asynchronous SError Interrupt
  CPU: 3 PID: 271 Comm: (udev-worker) Tainted: G   M
  pc : qce_get_version+0x44/0xf0 [qcrypto]
  lr : qce_crypto_probe+0x228/0x4a0 [qcrypto]

Synchronous delivery of the same fault, on a different boot:

[   10.923435] Internal error: synchronous external abort: 0000000096000010 [#1]
  Modules linked in: ... qcrypto(+) ...
  CPU: 0 PID: 262 Comm: (udev-worker)
  pc : qce_get_version+0x3c/0xf0 [qcrypto]

ESR 0xbe000000 has AET = uncontainable, so arm64_is_fatal_ras_serror() must
panic. ESR 0x96000010 is DFSC 0x10, sync external abort not on a table walk.
Same register, same udev worker, same ~10.8-10.9 s — whether it arrives sync
(oops) or async (fatal panic) appears to be a timing race.

Why the read aborts

qce_get_version() is a bare register read — the driver's first touch of the
block (drivers/crypto/qce/common.c:556):

void qce_get_version(struct qce_device *qce, u32 *major, u32 *minor, u32 *step)
{
	u32 val;

	val = qce_read(qce, REG_VERSION);
	...
}

Probe acquires clocks with devm_clk_get_optional() (drivers/crypto/qce/core.c:214-224),
so absent clocks yield NULL rather than an error; probe continues, votes only
devm_of_icc_get(dev, "memory"), and then reads. Nothing in that path guarantees
the CE is powered/clocked or HLOS-owned.

The Shikra-specific discrepancy

To be clear about what is not wrong: a clockless QCE node is correct for this
compatible. Documentation/devicetree/bindings/crypto/qcom-qce.yaml sets, for
qcom,sm8150-qce:

  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,sm8150-qce
    then:
      properties:
        clocks: false
        clock-names: false

qcom,shikra-qce is documented on the enum branch that ends in
- const: qcom,sm8150-qce / - const: qcom,qce, so adding clocks to
crypto@1b3a000 would violate the binding.
sm8150.dtsi and sm8550.dtsi
likewise carry no clocks or power-domains on their crypto nodes and work.

The difference is where the CE clock handle sits:

crypto node firmware/scm node
sm8150 no clocks no clocks
sm8550 no clocks no clocks (interconnects only)
shikra no clocks clocks = <&rpmcc RPM_SMD_CE1_CLK>; clock-names = "core";

RPM_SMD_CE1_CLK appears exactly once in all of shikra.dtsi — only on the
scm node, added by c32ee6365330 ("shikra: add SCM clock and reset-cells to
firmware node") for SCM's own crypto operations. qcom_scm_clk_enable()
(drivers/firmware/qcom/qcom_scm.c:179) prepares/enables that clock only around
specific SCM calls, not permanently.

So the QCE driver assumes an always-on RPM-managed CE, while Shikra's only handle
on that clock belongs to a driver that toggles it transiently. cryptobam is
qcom,controlled-remotely on Shikra exactly as on sm8150/sm8550, so the BAM is
not the differing factor.

Proposed fix

Until QCE is validated on this SoC, disable the node:

 		crypto: crypto@1b3a000 {
 			compatible = "qcom,shikra-qce", "qcom,sm8150-qce", "qcom,qce";
 			reg = <0x0 0x01b3a000 0x0 0x6000>;
 			dmas = <&cryptobam 4>, <&cryptobam 5>;
 			dma-names = "rx", "tx";
 			iommus = <&apps_smmu 0x84 0x0011>,
 				 <&apps_smmu 0x86 0x0011>,
 				 <&apps_smmu 0x92 0x0>,
 				 <&apps_smmu 0x94 0x0011>,
 				 <&apps_smmu 0x96 0x0011>,
 				 <&apps_smmu 0x98 0x0001>,
 				 <&apps_smmu 0x9F 0x0>;
 			interconnects = <&system_noc MASTER_CRYPTO_CORE0 0
 					 &mc_virt SLAVE_EBI_CH0 0>;
 			interconnect-names = "memory";
+			status = "disabled";
 		};

Alternatively, if CE is meant to be usable from the HLOS on Shikra, the block
needs a dependency the QCE node can actually hold — a power-domain, or an
always-on CE1 vote that is not scoped to SCM calls.

  1. Is CE1 assigned to the HLOS VM under Gunyah on Shikra, or reserved to
    firmware/TZ? If reserved, status = "disabled" is the correct end state, not a
    workaround.
  2. Was crypto@1b3a000 ever exercised on this SoC, or added by pattern from
    sm8150 alongside the scm CE1 clock in c32ee6365330?
  3. If it should work, should the CE1 vote move/duplicate to a form the QCE node
    can reference within the clocks: false constraint of the binding?

Reproducer

Any rootfs that binds QCE to crypto@1b3a000 triggers it. Two userspaces on the
same board and the same kernel commit (d49c33864d06) differ only in which
modules they ship:

qcrypto bam_dma QCE outcome
Debian loaded loaded probe proceeds to version read -> abort at ~10.8 s
Yocto loaded not shipped probe returns -EPROBE_DEFER, never reads registers -> boots

The distinguishing factor is bam_dma, not qcrypto. The QCE node declares
dmas = <&cryptobam 4>, <&cryptobam 5>, so devm_qce_dma_request()
(drivers/crypto/qce/core.c:244) is reached before qce_check_version(). With
no driver bound to cryptobam, that call defers and probe unwinds before the
fatal qce_read(qce, REG_VERSION).

In the passing Yocto boot both devices register and then nothing further is ever
logged for either — no qce probe message appears anywhere in the log:

[    0.333976] platform 1b04000.dma-controller: Adding to iommu group 1
[    0.334218] platform 1b3a000.crypto: Adding to iommu group 1

That the block is genuinely unreachable — rather than merely unprobed — is
reinforced by the other crypto node on the same SoC, which has no BAM
dependency and probes without incident in the same boot:

[    0.324802] qcom-ice 4748000.crypto: Found QC Inline Crypto Engine (ICE) v3.2.0

Confirming without a kernel rebuild:

# panics at ~10.8 s
(default cmdline, full module set)

# boots
modprobe.blacklist=qcrypto

Suggested confirmation on a booted Yocto image — this should reproduce the
panic on the known-good userspace, closing the loop on the mechanism:

modprobe bam_dma      # binds cryptobam -> unblocks QCE probe -> expect abort

(Not yet run; stated as a prediction, not a result.)

Verification notes

Confirmed by inspection of qcom-next @ d49c33864d06 and of the DTB actually
shipped in the failing image (extracted from the FIT in dtb.bin):

crypto@1b3a000 {
    compatible = "qcom,shikra-qce", "qcom,sm8150-qce", "qcom,qce";
    reg = <0x0 0x01b3a000 0x0 0x6000>;
    dmas = <...>;  dma-names = "rx", "tx";
    iommus = <...>;
    interconnects = <...>;
    interconnect-names = "memory";
};

No clocks, no power-domains in the shipped binary — matching the source.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions