Skip to content

RISC-V SBI MPXY fixes and boot integration - #7970

Open
maroueneboubakri wants to merge 5 commits into
OP-TEE:masterfrom
maroueneboubakri:dev-riscv-mpxy-fix
Open

RISC-V SBI MPXY fixes and boot integration#7970
maroueneboubakri wants to merge 5 commits into
OP-TEE:masterfrom
maroueneboubakri:dev-riscv-mpxy-fix

Conversation

@maroueneboubakri

@maroueneboubakri maroueneboubakri commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

This series fixes several issues in the RISC-V SBI MPXY driver and wires it into the boot path so that MPXY shared memory is actually registered and RPMI channels are actually discovered. Currently sbi_mpxy.c and sbi_mpxy_rpmi.c are built but never called.

This PR:

  • Fixes the SET_SHMEM ecall, which passes the physical address in the shmem_size argument slot. It also uses the size returned by GET_SHMEM_SIZE instead of a hardcoded 4 KiB and adds a disable path.

  • Adds bounds checks on caller-supplied and firmware-reported lengths against the shared memory size, and replaces a magic "+ 16" with sizeof() of the notification header.

  • Adds sbi_mpxy_init(), which probes the extension and registers per-hart shared memory, with stubs when CFG_RISCV_SBI_MPXY=n.

  • Calls it from the primary and secondary hart boot paths and probes the RPMI channels on the primary hart.

  • Adds a helper to map SBI error codes to TEE_Result for the upcoming MPXY-based TEE<->REE transport.

Built for PLATFORM=virt with CFG_RISCV_SBI_MPXY[_RPMI]=y

The SBI v3.0 MPXY SET_SHMEM function takes
(shmem_size, shmem_phys_lo, shmem_phys_hi, flags). The current code
passes the physical address as the first argument, i.e. in the
shmem_size slot, with everything else zero. A spec-compliant SBI
implementation will reject this or, worse, register a bogus region.

Also stop hardcoding 4 KiB: query the required size with
GET_SHMEM_SIZE, check it is a 4 KiB multiple and power of two as the
spec requires, and allocate it aligned to its own size. Record the size
in the per-hart context so later callers can bounds-check against it,
zero the buffer before registering it, and reset the context if the
ecall fails so a retry starts clean.

Add sbi_mpxy_disable_shmem() to release the region on the current hart
by passing the all-ones "disable" address, and the lo/hi helper macros
needed for RV32.

Signed-off-by: Marouene Boubakri <marouene.boubakri@nxp.com>
The MPXY helpers copy caller-supplied data into the per-hart shared
memory and copy firmware-reported lengths back out without checking
either against the size of that shared memory. A caller passing an
oversized message, or a misbehaving SBI implementation returning a
bogus length, would overrun the buffer.

- Reject message/attribute lengths larger than the shared memory in
  sbi_mpxy_send_message_with_response(),
  sbi_mpxy_send_message_without_response(),
  sbi_mpxy_read_attributes() and sbi_mpxy_write_attributes().
- Reject response lengths reported by firmware that exceed the shared
  memory before copying, and initialise *response_len to 0 so callers
  never see a stale value on error.
- Replace the magic "+ 16" in sbi_mpxy_get_notification_events() with
  sizeof(struct sbi_mpxy_notification_data), and add a
  max_events_data_len parameter so the function knows how large the
  caller's buffer is.

Signed-off-by: Marouene Boubakri <marouene.boubakri@nxp.com>
Nothing currently probes whether the SBI implementation actually
provides the MPXY extension before issuing MPXY ecalls, and nothing
records that shared memory must be registered per hart.

Add sbi_mpxy_init(), meant to be called once per hart after the heap
is usable. The first call probes SBI_EXT_MPXY via the base extension;
every call then registers the calling hart's shared memory. Expose
sbi_mpxy_is_available() for callers that need to know whether MPXY can
be used, and make sbi_mpxy_get_shmem_size() fail with
SBI_ERR_NOT_SUPPORTED when the extension was not found. The remaining
entry points are already gated on shmem_active, which can only be set
after a successful probe.

Provide inline stubs when CFG_RISCV_SBI_MPXY is disabled so generic
boot code can call sbi_mpxy_init() unconditionally.

Signed-off-by: Marouene Boubakri <marouene.boubakri@nxp.com>
sbi_mpxy.c and sbi_mpxy_rpmi.c are built when CFG_RISCV_SBI_MPXY[_RPMI]
is enabled, but nothing in the boot path calls them, so no hart ever
registers MPXY shared memory and no RPMI channel is ever discovered.

Call sbi_mpxy_init() on the primary hart once the runtime is up (heap
available, thread core-local initialised) and on each secondary hart
after thread_init_per_cpu(). MPXY shared memory is per hart, so every
hart that may send a message needs its own registration.

On the primary hart, if MPXY is available, probe the RPMI channels so
that sbi_mpxy_rpmi_ctx is populated for later users (e.g. the OP-TEE
service group transport).

Add an inline stub for sbi_mpxy_rpmi_probe_channels() when
CFG_RISCV_SBI_MPXY_RPMI is disabled so boot.c stays free of #ifdefs.

Signed-off-by: Marouene Boubakri <marouene.boubakri@nxp.com>
The sbi_mpxy_* helpers return raw SBI error codes, matching the rest of
sbi.c. Code above the SBI layer (e.g. a TEE-to-REE transport built on
MPXY) reports TEE_Result, so provide a single mapping helper rather than
letting every caller invent its own.

Signed-off-by: Marouene Boubakri <marouene.boubakri@nxp.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant