mbox series

[v8,00/17] Introduce a unified API for SCMI Server testing

Message ID 20230118121426.492864-1-cristian.marussi@arm.com (mailing list archive)
Headers show
Series Introduce a unified API for SCMI Server testing | expand

Message

Cristian Marussi Jan. 18, 2023, 12:14 p.m. UTC
Hi all,

This series aims to introduce a new SCMI unified userspace interface meant
to ease testing an SCMI Server implementation for compliance, fuzzing etc.,
from the perspective of the OSPM agent (non-secure world only ...)

It is proposed as a testing/development facility, it is NOT meant to be a
feature to use in production, but only enabled in Kconfig for test
deployments.

Currently an SCMI Compliance Suite like the one at [1] can only work by
injecting SCMI messages at the SCMI transport layer using the mailbox test
driver (CONFIG_MAILBOX_TEST) via its few debugfs entries and looking at
the related replies from the SCMI backend Server.

This approach has a few drawbacks:

- the SCMI Server under test MUST be reachable through a mailbox based
  SCMI transport: any other SCMI Server placement is not possible (like in
  a VM reachable via SCMI Virtio). In order to cover other placements in
  the current scenario we should write some sort of test driver for each
  and every existent SCMI transport and for any future additional transport
  ...this clearly does not scale.

- even in the mailbox case the userspace Compliance suite cannot simply
  send and receive bare SCMI messages BUT it has to properly lay them out
  into the shared memory exposed by the mailbox test driver as expected by
  the transport definitions. In other words such a userspace test
  application has to, not only use a proper transport driver for the system
  at hand, but it also has to have a comprehensive knowledge of the
  internals of the underlying transport in order to operate.

- last but not least, the system under test has to be specifically
  configured and built, in terms of Kconfig and DT, to perform such kind of
  testing, it cannot be used for anything else, which is unfortunate for
  CI/CD deployments.

This series introduces a new SCMI Raw mode support feature that, when
configured and enabled exposes a new interface in debugfs through which:

- a userspace application can inject bare SCMI binary messages into the
  SCMI core stack; such messages will be routed by the SCMI regular kernel
  stack to the backend Server using the currently configured transport
  transparently: in other words you can test the SCMI server, no matter
  where it is placed, as long as it is reachable from the currently
  configured SCMI stack.
  Same goes the other way around on the reading path: any SCMI server reply
  can be read as a bare SCMI binary message from the same debugfs path.

- as a direct consequence of this way of injecting bare messages in the
  middle of the SCMI stack (instead of beneath it at the transport layer)
  the user application has to handle only bare SCMI messages without having
  to worry about the specific underlying transport internals that will be
  taken care of by the SCMI core stack itself using its own machinery,
  without duplicating such logic.

- a system under test, once configured with SCMI Raw support enabled in
  Kconfig, can be booted without any particular DT change.

Latest V6 additions: 

 - improved scmi traces for msg dumps to include used channels
 - added a new common SCMI debugfs root fs
 - reworked SCMI Raw debugfs layout
 - added support of a new additional per-channel API that allows a user to
   select a specific egress channel for the message injection (when more
   than one channel is available)

A quick and trivial example from the shell...reading from a sensor by
injecting a properly crafted packet in raw mode (letting the stack select
the channel):

	# INJECT THE SENSOR_READING MESSAGE FOR SENSOR ID=1 (binary little endian)
	root@deb-buster-arm64:~# echo -e -n \\x06\\x54\\x00\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00 > /sys/kernel/debug/scmi/0/raw/message

	# READING BACK THE REPLY...
	root@deb-buster-arm64:~# cat /sys/kernel/debug/scmi/0/raw/message | od --endian=little -t x4
	0000000 00005406 00000000 00000335 00000000
	0000020

while doing that, since Raw mode makes (partial) use of the regular SCMI
stack, you can observe the messages going through the SCMI stack with the
usual traces:

              bash-329     [000] ..... 14183.446808: scmi_msg_dump: id=0 ch=10 pt=15 t=cmnd msg_id=06 seq=0000 s=0 pyld=0100000000000000
   irq/35-mhu_db_l-81      [000] ..... 14183.447809: scmi_msg_dump: id=0 ch=10 pt=15 t=resp msg_id=06 seq=0000 s=0 pyld=3503000000000000

..trying to read in async when the backend server does NOT supports asyncs:

	# AN ASYNC SENSOR READING REQUEST...
	root@deb-buster-arm64:~# echo -e -n \\x06\\x54\\x00\\x00\\x01\\x00\\x00\\x00\\x01\\x00\\x00\\x00 > /sys/kernel/debug/scmi/0/raw/message_async

              bash-329     [000] ..... 16415.938739: scmi_msg_dump: id=0 ch=10 pt=15 t=cmnd msg_id=06 seq=0000 s=0 pyld=0100000001000000
   irq/35-mhu_db_l-81      [000] ..... 16415.944129: scmi_msg_dump: id=0 ch=10 pt=15 t=resp msg_id=06 seq=0000 s=-1 pyld=

	# RETURNS A STATUS -1 FROM THE SERVER NOT SUPPORTING IT
	root@deb-buster-arm64:~# cat /sys/kernel/debug/scmi/0/raw/message | od --endian=little -t x4
	0000000 00005406 ffffffff
	0000010

Note that the above example was on a JUNO, BUT exactly the same steps can
be used to reach an SCMI Server living on a VM reachable via virtio as
long as the system under test if properly configured to work with a
virtio transport.

In a nutshell the exposed API is as follows:

/sys/kernel/debug/scmi/
`-- 0
    |-- atomic_threshold_us
    |-- instance_name
    |-- raw
    |   |-- channels
    |   |   |-- 0x10
    |   |   |   |-- message
    |   |   |   `-- message_async
    |   |   `-- 0x13
    |   |       |-- message
    |   |       `-- message_async
    |   |-- errors
    |   |-- message
    |   |-- message_async
    |   |-- notification
    |   `-- reset
    `-- transport
        |-- is_atomic
        |-- max_msg_size
        |-- max_rx_timeout_ms
        |-- rx_max_msg
        |-- tx_max_msg
        `-- type

... where at the top level:

 - <N>: a progressive sequence number identifying this SCMI instance, in
   case there are multiple SCMI instance defined
   
 - instance_name: can be used (by CI) to identify the SCMI instance <N>
   that you are using through this Raw accessors: it corresponds to the SCMI
   DT top node full name of the underlying SCMI instance


... rooted under /transport:

 - a bunch of configuration info useful to setup the user application
   expectations in terms of timeouts and message characteristics.


... rooted at /raw (the real SCMI Raw interface :D):

 - message*: used to send sync/async commands and read back immediate and
   delayed responses (if any)
 - errors: used to report timeout and unexpected replies
 - reset: used to reset the SCMI Raw stack, flushing all queues from
   received messages still pending to be read out (useful to be sure to
   cleanup between test suite runs...)
 - notification: used to read any notification being spit by the system
   (if previously enabled by the user app)


... rooted at /raw/channels/<M>/:

 - message*: used to send sync/async commands and read back immediate and
   delayed responses (if any), using a SPECIFIC transport channel <M>
   (instead of letting the system choose for you based on transport config
    and the rotocol embedded in the injected message)
   NOTE THAT these entries are optional, created only if there is more than
   transport channel defined on the system.

Each write corresponds to one command request and the replies or delayed
response are read back one message at time (receiving an EOF at each
message boundary).

The user application running the test is in charge of handling timeouts
and properly choosing SCMI sequence numbers for the outgoing requests: note
that the same fixed number can be re-used (...though discouraged...) as
long as the suite does NOT expect to send multiple in-flight commands
concurrently.

Since the SCMI core regular stack is partially used to deliver and collect
the messages, late replies after timeouts and any other sort of unexpected
message sent by the SCMI server platform back can be identified by the SCMI
core as usual and it will be reported under /errors for later analysis.
(a userspace test-app will have anyway properly detected the timeout on
 /message* ...)

All of the above has been roughly tested against a standard JUNO SCP SCMI
Server (mailbox trans) and an emulated SCMI Server living in a VM (virtio
trans) using a custom experimental version of the scmi-tests Compliance
suite patched to support Raw mode and posted at [2]. (still in development
...merge requests are in progress...for now it is just a mean for me to
test the testing API ... O_o)

This V8 series is based on v6.2-rc1 PLUS another series which reworked a
bit the SCMI core stack init/probe [3]; to ease testing a V8 properly
based can be picked up from [4].

Having said that (in such a concise and brief way :P) ...
	
...any feedback/comments are welcome !

Thanks,
Cristian

---
v7 --> v8 
- fixed a few bad handling on error path
- ignoring debugfs_ retvals as supposed to
- using XArray for per-channel queus instead of IDRs
- refactored debugfs setup calls

v6 --> v7
- fixed one sparse error
- removed redundant info.num_chans/channels fields: enumerate them dyamically
  once needed.

v5 --> v6
- exported symbol debugfs_create_str 
- rebased on top of v6.2-rc1 plus series at [3]
- redesigned SCMI debugfs layout with a bunch of common entries
  enabled by implicit CONFIG_ARM_SCMI_NEED_DEBUGFS
- refactored SCMI Raw internal queues handling
- added SCMI Raw per-channel injection support
- added channels info on SCMI msg_dump traces
- fix debugfs multiple writers cases
- added DEBUG_FS dependency to Raw mode
- select CONFIG_ARM_SCMI_NEED_DEBUGFS when Raw mode is compiled

v4 --> v5
- rebased on sudeep/for-next/scmi
- added multiple SCMI instances support
- added optional Raw full-cohexistence mode
- use custom tags to distinguish Raw msg_dump traces
- add circular handling of raw buffers queues for errors and notifications

V3 --> v4
- rebased on v6.1-rc1
- addedd missing support for 'polled' transports and transport lacking a
  completion_irq (like smc/optee)
- removed a few inlines
- refactored SCMI Raw RX patch to make use more extensively of the regular
  non-Raw RX path
- fix handling of O_NONBLOCK raw_mode read requests

v2 --> v3
- fixed some sparse warning on LE and __poll_t
- reworked and simplified deferred worker in charge of xfer delayed waiting
- allow for injection of DT-unknown protocols messages when in Raw mode
  (needed for any kind of fuzzing...)

v1 --> v2
- added comments and debugfs docs
- added dedicated transport devices for channels initialization
- better channels handling in Raw mode
- removed runtime enable, moved to static compile time exclusion
  of SCMI regular stack

[1]: https://gitlab.arm.com/tests/scmi-tests
[2]: https://gitlab.arm.com/tests/scmi-tests/-/commits/raw_mode_support_devel/
[3]: https://lore.kernel.org/all/20221222185049.737625-1-cristian.marussi@arm.com/
[4]: https://gitlab.arm.com/linux-arm/linux-cm/-/commits/scmi_raw_mode_V8/


Cristian Marussi (17):
  firmware: arm_scmi: Refactor xfer in-flight registration routines
  firmware: arm_scmi: Refactor polling helpers
  firmware: arm_scmi: Refactor scmi_wait_for_message_response
  firmware: arm_scmi: Add flags field to xfer
  firmware: arm_scmi: Add xfer Raw helpers
  firmware: arm_scmi: Move errors defs and code to common.h
  firmware: arm_scmi: Add internal platform/channel IDs
  include: trace: Add platform and channel instance references
  debugfs: Export debugfs_create_str symbol
  firmware: arm_scmi: Populate a common SCMI debugsfs root
  firmware: arm_scmi: Add debugfs ABI documentation for common entries
  firmware: arm_scmi: Add core Raw transmission support
  firmware: arm_scmi: Add debugfs ABI documentation for Raw mode
  firmware: arm_scmi: Reject SCMI drivers while in Raw mode
  firmware: arm_scmi: Call Raw mode hooks from the core stack
  firmware: arm_scmi: Add Raw mode coexistence support
  firmware: arm_scmi: Add per-channel Raw injection support

 Documentation/ABI/testing/debugfs-scmi     |   70 +
 Documentation/ABI/testing/debugfs-scmi-raw |  109 ++
 drivers/firmware/arm_scmi/Kconfig          |   32 +
 drivers/firmware/arm_scmi/Makefile         |    1 +
 drivers/firmware/arm_scmi/bus.c            |    7 +
 drivers/firmware/arm_scmi/common.h         |   75 +
 drivers/firmware/arm_scmi/driver.c         |  638 +++++++--
 drivers/firmware/arm_scmi/protocols.h      |    7 +
 drivers/firmware/arm_scmi/raw_mode.c       | 1443 ++++++++++++++++++++
 drivers/firmware/arm_scmi/raw_mode.h       |   31 +
 fs/debugfs/file.c                          |    1 +
 include/trace/events/scmi.h                |   18 +-
 12 files changed, 2292 insertions(+), 140 deletions(-)
 create mode 100644 Documentation/ABI/testing/debugfs-scmi
 create mode 100644 Documentation/ABI/testing/debugfs-scmi-raw
 create mode 100644 drivers/firmware/arm_scmi/raw_mode.c
 create mode 100644 drivers/firmware/arm_scmi/raw_mode.h

Comments

Sudeep Holla Jan. 19, 2023, 7:32 p.m. UTC | #1
On Wed, 18 Jan 2023 12:14:09 +0000, Cristian Marussi wrote:
> This series aims to introduce a new SCMI unified userspace interface meant
> to ease testing an SCMI Server implementation for compliance, fuzzing etc.,
> from the perspective of the OSPM agent (non-secure world only ...)
> 
> It is proposed as a testing/development facility, it is NOT meant to be a
> feature to use in production, but only enabled in Kconfig for test
> deployments.
> 
> [...]

Applied to sudeep.holla/linux (for-next/scmi), thanks!

[01/17] firmware: arm_scmi: Refactor xfer in-flight registration routines
        https://git.kernel.org/sudeep.holla/c/9374324e8d78
[02/17] firmware: arm_scmi: Refactor polling helpers
        https://git.kernel.org/sudeep.holla/c/d5552a45c828
[03/17] firmware: arm_scmi: Refactor scmi_wait_for_message_response
        https://git.kernel.org/sudeep.holla/c/ac49e46c453a
[04/17] firmware: arm_scmi: Add flags field to xfer
        https://git.kernel.org/sudeep.holla/c/0eb24e5a0ead
[05/17] firmware: arm_scmi: Add xfer Raw helpers
        https://git.kernel.org/sudeep.holla/c/aaa9d521b01a
[06/17] firmware: arm_scmi: Move errors defs and code to common.h
        https://git.kernel.org/sudeep.holla/c/5e15c2197fc7
[07/17] firmware: arm_scmi: Add internal platform/channel IDs
        https://git.kernel.org/sudeep.holla/c/5b6034808c96
[08/17] include: trace: Add platform and channel instance references
        https://git.kernel.org/sudeep.holla/c/bd752cc79916
[09/17] debugfs: Export debugfs_create_str symbol
        https://git.kernel.org/sudeep.holla/c/cade53b60a04
[10/17] firmware: arm_scmi: Populate a common SCMI debugsfs root
        https://git.kernel.org/sudeep.holla/c/f5bc54a5041b
[11/17] firmware: arm_scmi: Add debugfs ABI documentation for common entries
        https://git.kernel.org/sudeep.holla/c/b5dc013d98b4
[12/17] firmware: arm_scmi: Add core Raw transmission support
        https://git.kernel.org/sudeep.holla/c/e789a8ab15b0
[13/17] firmware: arm_scmi: Add debugfs ABI documentation for Raw mode
        https://git.kernel.org/sudeep.holla/c/25376d813405
[14/17] firmware: arm_scmi: Reject SCMI drivers while in Raw mode
        https://git.kernel.org/sudeep.holla/c/9e834da670ce
[15/17] firmware: arm_scmi: Call Raw mode hooks from the core stack
        https://git.kernel.org/sudeep.holla/c/a6fb9dc05c8c
[16/17] firmware: arm_scmi: Add Raw mode coexistence support
        https://git.kernel.org/sudeep.holla/c/145f03626257
[17/17] firmware: arm_scmi: Add per-channel Raw injection support
        https://git.kernel.org/sudeep.holla/c/eeb087fa365a

--
Regards,
Sudeep
Florian Fainelli Jan. 19, 2023, 9:47 p.m. UTC | #2
Hi Christian,

On 1/18/23 04:14, Cristian Marussi wrote:
> Hi all,
> 
> This series aims to introduce a new SCMI unified userspace interface meant
> to ease testing an SCMI Server implementation for compliance, fuzzing etc.,
> from the perspective of the OSPM agent (non-secure world only ...)
> 
> It is proposed as a testing/development facility, it is NOT meant to be a
> feature to use in production, but only enabled in Kconfig for test
> deployments.
> 
> Currently an SCMI Compliance Suite like the one at [1] can only work by
> injecting SCMI messages at the SCMI transport layer using the mailbox test
> driver (CONFIG_MAILBOX_TEST) via its few debugfs entries and looking at
> the related replies from the SCMI backend Server.

Took a while but finally:

Tested-by: Florian Fainelli <f.fainelli@gmail.com>

Any idea when the raw_mode_support or the acs_raw_mode_support will hit 
your master branch in the scmi-tests repository?
Vincent Guittot Jan. 20, 2023, 8:11 a.m. UTC | #3
On Wed, 18 Jan 2023 at 13:15, Cristian Marussi <cristian.marussi@arm.com> wrote:
>
> Hi all,
>
> This series aims to introduce a new SCMI unified userspace interface meant
> to ease testing an SCMI Server implementation for compliance, fuzzing etc.,
> from the perspective of the OSPM agent (non-secure world only ...)
>
> It is proposed as a testing/development facility, it is NOT meant to be a
> feature to use in production, but only enabled in Kconfig for test
> deployments.
>
> Currently an SCMI Compliance Suite like the one at [1] can only work by
> injecting SCMI messages at the SCMI transport layer using the mailbox test
> driver (CONFIG_MAILBOX_TEST) via its few debugfs entries and looking at
> the related replies from the SCMI backend Server.
>
> This approach has a few drawbacks:
>
> - the SCMI Server under test MUST be reachable through a mailbox based
>   SCMI transport: any other SCMI Server placement is not possible (like in
>   a VM reachable via SCMI Virtio). In order to cover other placements in
>   the current scenario we should write some sort of test driver for each
>   and every existent SCMI transport and for any future additional transport
>   ...this clearly does not scale.
>
> - even in the mailbox case the userspace Compliance suite cannot simply
>   send and receive bare SCMI messages BUT it has to properly lay them out
>   into the shared memory exposed by the mailbox test driver as expected by
>   the transport definitions. In other words such a userspace test
>   application has to, not only use a proper transport driver for the system
>   at hand, but it also has to have a comprehensive knowledge of the
>   internals of the underlying transport in order to operate.
>
> - last but not least, the system under test has to be specifically
>   configured and built, in terms of Kconfig and DT, to perform such kind of
>   testing, it cannot be used for anything else, which is unfortunate for
>   CI/CD deployments.
>
> This series introduces a new SCMI Raw mode support feature that, when
> configured and enabled exposes a new interface in debugfs through which:
>
> - a userspace application can inject bare SCMI binary messages into the
>   SCMI core stack; such messages will be routed by the SCMI regular kernel
>   stack to the backend Server using the currently configured transport
>   transparently: in other words you can test the SCMI server, no matter
>   where it is placed, as long as it is reachable from the currently
>   configured SCMI stack.
>   Same goes the other way around on the reading path: any SCMI server reply
>   can be read as a bare SCMI binary message from the same debugfs path.
>
> - as a direct consequence of this way of injecting bare messages in the
>   middle of the SCMI stack (instead of beneath it at the transport layer)
>   the user application has to handle only bare SCMI messages without having
>   to worry about the specific underlying transport internals that will be
>   taken care of by the SCMI core stack itself using its own machinery,
>   without duplicating such logic.
>
> - a system under test, once configured with SCMI Raw support enabled in
>   Kconfig, can be booted without any particular DT change.
>
> Latest V6 additions:
>
>  - improved scmi traces for msg dumps to include used channels
>  - added a new common SCMI debugfs root fs
>  - reworked SCMI Raw debugfs layout
>  - added support of a new additional per-channel API that allows a user to
>    select a specific egress channel for the message injection (when more
>    than one channel is available)
>
> A quick and trivial example from the shell...reading from a sensor by
> injecting a properly crafted packet in raw mode (letting the stack select
> the channel):
>
>         # INJECT THE SENSOR_READING MESSAGE FOR SENSOR ID=1 (binary little endian)
>         root@deb-buster-arm64:~# echo -e -n \\x06\\x54\\x00\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00 > /sys/kernel/debug/scmi/0/raw/message
>
>         # READING BACK THE REPLY...
>         root@deb-buster-arm64:~# cat /sys/kernel/debug/scmi/0/raw/message | od --endian=little -t x4
>         0000000 00005406 00000000 00000335 00000000
>         0000020
>
> while doing that, since Raw mode makes (partial) use of the regular SCMI
> stack, you can observe the messages going through the SCMI stack with the
> usual traces:
>
>               bash-329     [000] ..... 14183.446808: scmi_msg_dump: id=0 ch=10 pt=15 t=cmnd msg_id=06 seq=0000 s=0 pyld=0100000000000000
>    irq/35-mhu_db_l-81      [000] ..... 14183.447809: scmi_msg_dump: id=0 ch=10 pt=15 t=resp msg_id=06 seq=0000 s=0 pyld=3503000000000000
>
> ..trying to read in async when the backend server does NOT supports asyncs:
>
>         # AN ASYNC SENSOR READING REQUEST...
>         root@deb-buster-arm64:~# echo -e -n \\x06\\x54\\x00\\x00\\x01\\x00\\x00\\x00\\x01\\x00\\x00\\x00 > /sys/kernel/debug/scmi/0/raw/message_async
>
>               bash-329     [000] ..... 16415.938739: scmi_msg_dump: id=0 ch=10 pt=15 t=cmnd msg_id=06 seq=0000 s=0 pyld=0100000001000000
>    irq/35-mhu_db_l-81      [000] ..... 16415.944129: scmi_msg_dump: id=0 ch=10 pt=15 t=resp msg_id=06 seq=0000 s=-1 pyld=
>
>         # RETURNS A STATUS -1 FROM THE SERVER NOT SUPPORTING IT
>         root@deb-buster-arm64:~# cat /sys/kernel/debug/scmi/0/raw/message | od --endian=little -t x4
>         0000000 00005406 ffffffff
>         0000010
>
> Note that the above example was on a JUNO, BUT exactly the same steps can
> be used to reach an SCMI Server living on a VM reachable via virtio as
> long as the system under test if properly configured to work with a
> virtio transport.
>
> In a nutshell the exposed API is as follows:
>
> /sys/kernel/debug/scmi/
> `-- 0
>     |-- atomic_threshold_us
>     |-- instance_name
>     |-- raw
>     |   |-- channels
>     |   |   |-- 0x10
>     |   |   |   |-- message
>     |   |   |   `-- message_async
>     |   |   `-- 0x13
>     |   |       |-- message
>     |   |       `-- message_async
>     |   |-- errors
>     |   |-- message
>     |   |-- message_async
>     |   |-- notification
>     |   `-- reset
>     `-- transport
>         |-- is_atomic
>         |-- max_msg_size
>         |-- max_rx_timeout_ms
>         |-- rx_max_msg
>         |-- tx_max_msg
>         `-- type
>
> ... where at the top level:
>
>  - <N>: a progressive sequence number identifying this SCMI instance, in
>    case there are multiple SCMI instance defined
>
>  - instance_name: can be used (by CI) to identify the SCMI instance <N>
>    that you are using through this Raw accessors: it corresponds to the SCMI
>    DT top node full name of the underlying SCMI instance
>
>
> ... rooted under /transport:
>
>  - a bunch of configuration info useful to setup the user application
>    expectations in terms of timeouts and message characteristics.
>
>
> ... rooted at /raw (the real SCMI Raw interface :D):
>
>  - message*: used to send sync/async commands and read back immediate and
>    delayed responses (if any)
>  - errors: used to report timeout and unexpected replies
>  - reset: used to reset the SCMI Raw stack, flushing all queues from
>    received messages still pending to be read out (useful to be sure to
>    cleanup between test suite runs...)
>  - notification: used to read any notification being spit by the system
>    (if previously enabled by the user app)
>
>
> ... rooted at /raw/channels/<M>/:

I haven't seen a description of the <M>. I figured out that this is
the protocol id to which the channel was associated in DT while
testing it but it could be good to describe this somewhere.
Apart from this minor thing, I have tested it with an scmi server
embedded in OPTEE and run the scmi compliance tests. Everything works
fine using the default mode or using one specific channel.

FWIW
Tested-by: Vincent Guittot <vincent.guittot@linaro.org>

Thanks

>
>  - message*: used to send sync/async commands and read back immediate and
>    delayed responses (if any), using a SPECIFIC transport channel <M>
>    (instead of letting the system choose for you based on transport config
>     and the rotocol embedded in the injected message)
>    NOTE THAT these entries are optional, created only if there is more than
>    transport channel defined on the system.
>
> Each write corresponds to one command request and the replies or delayed
> response are read back one message at time (receiving an EOF at each
> message boundary).
>
> The user application running the test is in charge of handling timeouts
> and properly choosing SCMI sequence numbers for the outgoing requests: note
> that the same fixed number can be re-used (...though discouraged...) as
> long as the suite does NOT expect to send multiple in-flight commands
> concurrently.
>
> Since the SCMI core regular stack is partially used to deliver and collect
> the messages, late replies after timeouts and any other sort of unexpected
> message sent by the SCMI server platform back can be identified by the SCMI
> core as usual and it will be reported under /errors for later analysis.
> (a userspace test-app will have anyway properly detected the timeout on
>  /message* ...)
>
> All of the above has been roughly tested against a standard JUNO SCP SCMI
> Server (mailbox trans) and an emulated SCMI Server living in a VM (virtio
> trans) using a custom experimental version of the scmi-tests Compliance
> suite patched to support Raw mode and posted at [2]. (still in development
> ...merge requests are in progress...for now it is just a mean for me to
> test the testing API ... O_o)
>
> This V8 series is based on v6.2-rc1 PLUS another series which reworked a
> bit the SCMI core stack init/probe [3]; to ease testing a V8 properly
> based can be picked up from [4].
>
> Having said that (in such a concise and brief way :P) ...
>
> ...any feedback/comments are welcome !
>
> Thanks,
> Cristian
>
> ---
> v7 --> v8
> - fixed a few bad handling on error path
> - ignoring debugfs_ retvals as supposed to
> - using XArray for per-channel queus instead of IDRs
> - refactored debugfs setup calls
>
> v6 --> v7
> - fixed one sparse error
> - removed redundant info.num_chans/channels fields: enumerate them dyamically
>   once needed.
>
> v5 --> v6
> - exported symbol debugfs_create_str
> - rebased on top of v6.2-rc1 plus series at [3]
> - redesigned SCMI debugfs layout with a bunch of common entries
>   enabled by implicit CONFIG_ARM_SCMI_NEED_DEBUGFS
> - refactored SCMI Raw internal queues handling
> - added SCMI Raw per-channel injection support
> - added channels info on SCMI msg_dump traces
> - fix debugfs multiple writers cases
> - added DEBUG_FS dependency to Raw mode
> - select CONFIG_ARM_SCMI_NEED_DEBUGFS when Raw mode is compiled
>
> v4 --> v5
> - rebased on sudeep/for-next/scmi
> - added multiple SCMI instances support
> - added optional Raw full-cohexistence mode
> - use custom tags to distinguish Raw msg_dump traces
> - add circular handling of raw buffers queues for errors and notifications
>
> V3 --> v4
> - rebased on v6.1-rc1
> - addedd missing support for 'polled' transports and transport lacking a
>   completion_irq (like smc/optee)
> - removed a few inlines
> - refactored SCMI Raw RX patch to make use more extensively of the regular
>   non-Raw RX path
> - fix handling of O_NONBLOCK raw_mode read requests
>
> v2 --> v3
> - fixed some sparse warning on LE and __poll_t
> - reworked and simplified deferred worker in charge of xfer delayed waiting
> - allow for injection of DT-unknown protocols messages when in Raw mode
>   (needed for any kind of fuzzing...)
>
> v1 --> v2
> - added comments and debugfs docs
> - added dedicated transport devices for channels initialization
> - better channels handling in Raw mode
> - removed runtime enable, moved to static compile time exclusion
>   of SCMI regular stack
>
> [1]: https://gitlab.arm.com/tests/scmi-tests
> [2]: https://gitlab.arm.com/tests/scmi-tests/-/commits/raw_mode_support_devel/
> [3]: https://lore.kernel.org/all/20221222185049.737625-1-cristian.marussi@arm.com/
> [4]: https://gitlab.arm.com/linux-arm/linux-cm/-/commits/scmi_raw_mode_V8/
>
>
> Cristian Marussi (17):
>   firmware: arm_scmi: Refactor xfer in-flight registration routines
>   firmware: arm_scmi: Refactor polling helpers
>   firmware: arm_scmi: Refactor scmi_wait_for_message_response
>   firmware: arm_scmi: Add flags field to xfer
>   firmware: arm_scmi: Add xfer Raw helpers
>   firmware: arm_scmi: Move errors defs and code to common.h
>   firmware: arm_scmi: Add internal platform/channel IDs
>   include: trace: Add platform and channel instance references
>   debugfs: Export debugfs_create_str symbol
>   firmware: arm_scmi: Populate a common SCMI debugsfs root
>   firmware: arm_scmi: Add debugfs ABI documentation for common entries
>   firmware: arm_scmi: Add core Raw transmission support
>   firmware: arm_scmi: Add debugfs ABI documentation for Raw mode
>   firmware: arm_scmi: Reject SCMI drivers while in Raw mode
>   firmware: arm_scmi: Call Raw mode hooks from the core stack
>   firmware: arm_scmi: Add Raw mode coexistence support
>   firmware: arm_scmi: Add per-channel Raw injection support
>
>  Documentation/ABI/testing/debugfs-scmi     |   70 +
>  Documentation/ABI/testing/debugfs-scmi-raw |  109 ++
>  drivers/firmware/arm_scmi/Kconfig          |   32 +
>  drivers/firmware/arm_scmi/Makefile         |    1 +
>  drivers/firmware/arm_scmi/bus.c            |    7 +
>  drivers/firmware/arm_scmi/common.h         |   75 +
>  drivers/firmware/arm_scmi/driver.c         |  638 +++++++--
>  drivers/firmware/arm_scmi/protocols.h      |    7 +
>  drivers/firmware/arm_scmi/raw_mode.c       | 1443 ++++++++++++++++++++
>  drivers/firmware/arm_scmi/raw_mode.h       |   31 +
>  fs/debugfs/file.c                          |    1 +
>  include/trace/events/scmi.h                |   18 +-
>  12 files changed, 2292 insertions(+), 140 deletions(-)
>  create mode 100644 Documentation/ABI/testing/debugfs-scmi
>  create mode 100644 Documentation/ABI/testing/debugfs-scmi-raw
>  create mode 100644 drivers/firmware/arm_scmi/raw_mode.c
>  create mode 100644 drivers/firmware/arm_scmi/raw_mode.h
>
> --
> 2.34.1
>
Cristian Marussi Jan. 20, 2023, 9:53 a.m. UTC | #4
On Thu, Jan 19, 2023 at 01:47:04PM -0800, Florian Fainelli wrote:
> Hi Christian,
> 
Hi Florian,

> On 1/18/23 04:14, Cristian Marussi wrote:
> > Hi all,
> > 
> > This series aims to introduce a new SCMI unified userspace interface meant
> > to ease testing an SCMI Server implementation for compliance, fuzzing etc.,
> > from the perspective of the OSPM agent (non-secure world only ...)
> > 
> > It is proposed as a testing/development facility, it is NOT meant to be a
> > feature to use in production, but only enabled in Kconfig for test
> > deployments.
> > 
> > Currently an SCMI Compliance Suite like the one at [1] can only work by
> > injecting SCMI messages at the SCMI transport layer using the mailbox test
> > driver (CONFIG_MAILBOX_TEST) via its few debugfs entries and looking at
> > the related replies from the SCMI backend Server.
> 
> Took a while but finally:
> 
> Tested-by: Florian Fainelli <f.fainelli@gmail.com>
> 

Thanks for giving it a go.

> Any idea when the raw_mode_support or the acs_raw_mode_support will hit your
> master branch in the scmi-tests repository?

I was holding off waiting for this series to be merged to be sure the
debugfs ABI was not changing anymore, so now, soon-ish, I'll move to request
merge the Raw support in the ACS too; the only further delay regarding this,
that I can think of, could be that I know QA is also adding v3.1 tests to the
ACS and they are too going for the MR in these days, so this could delay a bit
further the Raw support merge.

Thanks,
Cristian
Cristian Marussi Jan. 20, 2023, 9:56 a.m. UTC | #5
On Fri, Jan 20, 2023 at 09:11:24AM +0100, Vincent Guittot wrote:
> On Wed, 18 Jan 2023 at 13:15, Cristian Marussi <cristian.marussi@arm.com> wrote:
> >
> > Hi all,
> >
> > This series aims to introduce a new SCMI unified userspace interface meant
> > to ease testing an SCMI Server implementation for compliance, fuzzing etc.,
> > from the perspective of the OSPM agent (non-secure world only ...)
> >
> > It is proposed as a testing/development facility, it is NOT meant to be a
> > feature to use in production, but only enabled in Kconfig for test
> > deployments.
> >
> > Currently an SCMI Compliance Suite like the one at [1] can only work by
> > injecting SCMI messages at the SCMI transport layer using the mailbox test
> > driver (CONFIG_MAILBOX_TEST) via its few debugfs entries and looking at
> > the related replies from the SCMI backend Server.
> >
> > This approach has a few drawbacks:
> >
> > - the SCMI Server under test MUST be reachable through a mailbox based
> >   SCMI transport: any other SCMI Server placement is not possible (like in
> >   a VM reachable via SCMI Virtio). In order to cover other placements in
> >   the current scenario we should write some sort of test driver for each
> >   and every existent SCMI transport and for any future additional transport
> >   ...this clearly does not scale.
> >
> > - even in the mailbox case the userspace Compliance suite cannot simply
> >   send and receive bare SCMI messages BUT it has to properly lay them out
> >   into the shared memory exposed by the mailbox test driver as expected by
> >   the transport definitions. In other words such a userspace test
> >   application has to, not only use a proper transport driver for the system
> >   at hand, but it also has to have a comprehensive knowledge of the
> >   internals of the underlying transport in order to operate.
> >
> > - last but not least, the system under test has to be specifically
> >   configured and built, in terms of Kconfig and DT, to perform such kind of
> >   testing, it cannot be used for anything else, which is unfortunate for
> >   CI/CD deployments.
> >
> > This series introduces a new SCMI Raw mode support feature that, when
> > configured and enabled exposes a new interface in debugfs through which:
> >
> > - a userspace application can inject bare SCMI binary messages into the
> >   SCMI core stack; such messages will be routed by the SCMI regular kernel
> >   stack to the backend Server using the currently configured transport
> >   transparently: in other words you can test the SCMI server, no matter
> >   where it is placed, as long as it is reachable from the currently
> >   configured SCMI stack.
> >   Same goes the other way around on the reading path: any SCMI server reply
> >   can be read as a bare SCMI binary message from the same debugfs path.
> >
> > - as a direct consequence of this way of injecting bare messages in the
> >   middle of the SCMI stack (instead of beneath it at the transport layer)
> >   the user application has to handle only bare SCMI messages without having
> >   to worry about the specific underlying transport internals that will be
> >   taken care of by the SCMI core stack itself using its own machinery,
> >   without duplicating such logic.
> >
> > - a system under test, once configured with SCMI Raw support enabled in
> >   Kconfig, can be booted without any particular DT change.
> >
> > Latest V6 additions:
> >
> >  - improved scmi traces for msg dumps to include used channels
> >  - added a new common SCMI debugfs root fs
> >  - reworked SCMI Raw debugfs layout
> >  - added support of a new additional per-channel API that allows a user to
> >    select a specific egress channel for the message injection (when more
> >    than one channel is available)
> >
> > A quick and trivial example from the shell...reading from a sensor by
> > injecting a properly crafted packet in raw mode (letting the stack select
> > the channel):
> >
> >         # INJECT THE SENSOR_READING MESSAGE FOR SENSOR ID=1 (binary little endian)
> >         root@deb-buster-arm64:~# echo -e -n \\x06\\x54\\x00\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00 > /sys/kernel/debug/scmi/0/raw/message
> >
> >         # READING BACK THE REPLY...
> >         root@deb-buster-arm64:~# cat /sys/kernel/debug/scmi/0/raw/message | od --endian=little -t x4
> >         0000000 00005406 00000000 00000335 00000000
> >         0000020
> >
> > while doing that, since Raw mode makes (partial) use of the regular SCMI
> > stack, you can observe the messages going through the SCMI stack with the
> > usual traces:
> >
> >               bash-329     [000] ..... 14183.446808: scmi_msg_dump: id=0 ch=10 pt=15 t=cmnd msg_id=06 seq=0000 s=0 pyld=0100000000000000
> >    irq/35-mhu_db_l-81      [000] ..... 14183.447809: scmi_msg_dump: id=0 ch=10 pt=15 t=resp msg_id=06 seq=0000 s=0 pyld=3503000000000000
> >
> > ..trying to read in async when the backend server does NOT supports asyncs:
> >
> >         # AN ASYNC SENSOR READING REQUEST...
> >         root@deb-buster-arm64:~# echo -e -n \\x06\\x54\\x00\\x00\\x01\\x00\\x00\\x00\\x01\\x00\\x00\\x00 > /sys/kernel/debug/scmi/0/raw/message_async
> >
> >               bash-329     [000] ..... 16415.938739: scmi_msg_dump: id=0 ch=10 pt=15 t=cmnd msg_id=06 seq=0000 s=0 pyld=0100000001000000
> >    irq/35-mhu_db_l-81      [000] ..... 16415.944129: scmi_msg_dump: id=0 ch=10 pt=15 t=resp msg_id=06 seq=0000 s=-1 pyld=
> >
> >         # RETURNS A STATUS -1 FROM THE SERVER NOT SUPPORTING IT
> >         root@deb-buster-arm64:~# cat /sys/kernel/debug/scmi/0/raw/message | od --endian=little -t x4
> >         0000000 00005406 ffffffff
> >         0000010
> >
> > Note that the above example was on a JUNO, BUT exactly the same steps can
> > be used to reach an SCMI Server living on a VM reachable via virtio as
> > long as the system under test if properly configured to work with a
> > virtio transport.
> >
> > In a nutshell the exposed API is as follows:
> >
> > /sys/kernel/debug/scmi/
> > `-- 0
> >     |-- atomic_threshold_us
> >     |-- instance_name
> >     |-- raw
> >     |   |-- channels
> >     |   |   |-- 0x10
> >     |   |   |   |-- message
> >     |   |   |   `-- message_async
> >     |   |   `-- 0x13
> >     |   |       |-- message
> >     |   |       `-- message_async
> >     |   |-- errors
> >     |   |-- message
> >     |   |-- message_async
> >     |   |-- notification
> >     |   `-- reset
> >     `-- transport
> >         |-- is_atomic
> >         |-- max_msg_size
> >         |-- max_rx_timeout_ms
> >         |-- rx_max_msg
> >         |-- tx_max_msg
> >         `-- type
> >
> > ... where at the top level:
> >
> >  - <N>: a progressive sequence number identifying this SCMI instance, in
> >    case there are multiple SCMI instance defined
> >
> >  - instance_name: can be used (by CI) to identify the SCMI instance <N>
> >    that you are using through this Raw accessors: it corresponds to the SCMI
> >    DT top node full name of the underlying SCMI instance
> >
> >
> > ... rooted under /transport:
> >
> >  - a bunch of configuration info useful to setup the user application
> >    expectations in terms of timeouts and message characteristics.
> >
> >
> > ... rooted at /raw (the real SCMI Raw interface :D):
> >
> >  - message*: used to send sync/async commands and read back immediate and
> >    delayed responses (if any)
> >  - errors: used to report timeout and unexpected replies
> >  - reset: used to reset the SCMI Raw stack, flushing all queues from
> >    received messages still pending to be read out (useful to be sure to
> >    cleanup between test suite runs...)
> >  - notification: used to read any notification being spit by the system
> >    (if previously enabled by the user app)
> >
> >
> > ... rooted at /raw/channels/<M>/:
> 

Hi Vincent,

thanks for trying this out.

> I haven't seen a description of the <M>. I figured out that this is
> the protocol id to which the channel was associated in DT while
> testing it but it could be good to describe this somewhere.

Ah, damn yes, I had made a note to myself to add an explicit description
of how the channel number IDs are chosen, then I forgot :P

I'll add a follow-on patch once is queued.

> Apart from this minor thing, I have tested it with an scmi server
> embedded in OPTEE and run the scmi compliance tests. Everything works
> fine using the default mode or using one specific channel.
> 
> FWIW
> Tested-by: Vincent Guittot <vincent.guittot@linaro.org>
> 

Thanks,
Cristian
Sudeep Holla Jan. 20, 2023, 11:38 a.m. UTC | #6
On Fri, Jan 20, 2023 at 09:56:32AM +0000, Cristian Marussi wrote:
> On Fri, Jan 20, 2023 at 09:11:24AM +0100, Vincent Guittot wrote:
> 
> Hi Vincent,
> 
> thanks for trying this out.
> 
> > I haven't seen a description of the <M>. I figured out that this is
> > the protocol id to which the channel was associated in DT while
> > testing it but it could be good to describe this somewhere.
> 
> Ah, damn yes, I had made a note to myself to add an explicit description
> of how the channel number IDs are chosen, then I forgot :P
> 
> I'll add a follow-on patch once is queued.
>

Please post it ASAP so that I can include it before I tag, just trying
to avoid missing it now and sending it as fix later :).

> > Apart from this minor thing, I have tested it with an scmi server
> > embedded in OPTEE and run the scmi compliance tests. Everything works
> > fine using the default mode or using one specific channel.
> > 
> > FWIW
> > Tested-by: Vincent Guittot <vincent.guittot@linaro.org>

Thanks Vincent and Florian. I just pulled and merged this last night, will
update to include your Tested-by tags.

--
Regards,
Sudeep
Sudeep Holla Jan. 20, 2023, 11:52 a.m. UTC | #7
On Wed, 18 Jan 2023 12:14:09 +0000, Cristian Marussi wrote:
> This series aims to introduce a new SCMI unified userspace interface meant
> to ease testing an SCMI Server implementation for compliance, fuzzing etc.,
> from the perspective of the OSPM agent (non-secure world only ...)
> 
> It is proposed as a testing/development facility, it is NOT meant to be a
> feature to use in production, but only enabled in Kconfig for test
> deployments.
> 
> [...]

Re-applied to sudeep.holla/linux (for-next/scmi) with Tested-by tags now, thanks!

[01/17] firmware: arm_scmi: Refactor xfer in-flight registration routines
        https://git.kernel.org/sudeep.holla/c/b0e924a955cb
[02/17] firmware: arm_scmi: Refactor polling helpers
        https://git.kernel.org/sudeep.holla/c/f21c2b0ba8f3
[03/17] firmware: arm_scmi: Refactor scmi_wait_for_message_response
        https://git.kernel.org/sudeep.holla/c/07cdfc44f1a4
[04/17] firmware: arm_scmi: Add flags field to xfer
        https://git.kernel.org/sudeep.holla/c/37057bf2b509
[05/17] firmware: arm_scmi: Add xfer Raw helpers
        https://git.kernel.org/sudeep.holla/c/3095a3e25d8f
[06/17] firmware: arm_scmi: Move errors defs and code to common.h
        https://git.kernel.org/sudeep.holla/c/936a2b91c2e8
[07/17] firmware: arm_scmi: Add internal platform/channel IDs
        https://git.kernel.org/sudeep.holla/c/75c86dc72dc8
[08/17] include: trace: Add platform and channel instance references
        https://git.kernel.org/sudeep.holla/c/8b2bd71119dd
[09/17] debugfs: Export debugfs_create_str symbol
        https://git.kernel.org/sudeep.holla/c/d60b59b96795
[10/17] firmware: arm_scmi: Populate a common SCMI debugsfs root
        https://git.kernel.org/sudeep.holla/c/c3d4aed763ce
[11/17] firmware: arm_scmi: Add debugfs ABI documentation for common entries
        https://git.kernel.org/sudeep.holla/c/0f62ed0092ec
[12/17] firmware: arm_scmi: Add core Raw transmission support
        https://git.kernel.org/sudeep.holla/c/3c3d818a9317
[13/17] firmware: arm_scmi: Add debugfs ABI documentation for Raw mode
        https://git.kernel.org/sudeep.holla/c/74225707b334
[14/17] firmware: arm_scmi: Reject SCMI drivers while in Raw mode
        https://git.kernel.org/sudeep.holla/c/ba80acb0dfca
[15/17] firmware: arm_scmi: Call Raw mode hooks from the core stack
        https://git.kernel.org/sudeep.holla/c/7063887b5386
[16/17] firmware: arm_scmi: Add Raw mode coexistence support
        https://git.kernel.org/sudeep.holla/c/9c54633e4e3d
[17/17] firmware: arm_scmi: Add per-channel Raw injection support
        https://git.kernel.org/sudeep.holla/c/7860701d1e6e

--
Regards,
Sudeep