Hi Ulf,
Ilias told me you were the eMMC guru so your might be best placed to advise on this problem.
It has been pointed out that a lot of RPMB devices are handled in eMMC storage stacks. A naive implementation of a virtio-rpmb device driver has to fake-up a number of responses for higher in the stack to convince the stack there is a zero length eMMC block device which provides an RPMB partition. One potential approach would be to pass-through the eMMC commands typically done during such probing to the virtio-rpmb backend.
This would avoid each individual driver making up different things but at the cost of the backend having to fake up a bunch of information instead.
It could also be argued that this just indicates the virtio-rpmb driver is sitting in the wrong place of the guest OS stack. This may be the view of the virtio-dev developers and indeed earlier drafts of the spec suggested handling of JDEC and NVME style frames which eventually got dropped before being adopted into the current draft.
However to test that view we need to come up with a draft for the extension. So far my draft is something like:
--8<---------------cut here---------------start------------->8--- virtio-rpmb.tex: define optional EMMC probe pass through support
Guest drivers commonly exist in an existing eMMC stack and although the virtio-rpmb device itself does not support normal eMMC storage it makes driver design simpler if start-up probe commands can be handled by the backend. This avoids having guest drivers invent their own fake data for the stack in a way that might differ from guest to guest.
Signed-off-by: Alex Bennée alex.bennee@linaro.org
1 file changed, 25 insertions(+), 3 deletions(-) virtio-rpmb.tex | 28 +++++++++++++++++++++++++---
modified virtio-rpmb.tex @@ -18,7 +18,9 @@ \subsection{Virtqueues}\label{sec:Device Types / RPMB Device / Virtqueues}
\subsection{Feature bits}\label{sec:Device Types / RPMB Device / Feature bits}
-None. +\begin{description} +\item[VIRTIO_RPMB_F_EMMC (0)] Device handles EMMC probe command packets. +\end{description}
\subsection{Device configuration layout}\label{sec:Device Types / RPMB Device / Device configuration layout}
@@ -64,12 +66,14 @@ \subsection{Device Operation}\label{sec:Device Types / RPMB Device / Device Oper #define VIRTIO_RPMB_REQ_DATA_WRITE 0x0003 #define VIRTIO_RPMB_REQ_DATA_READ 0x0004 #define VIRTIO_RPMB_REQ_RESULT_READ 0x0005 +#define VIRTIO_RPMB_REQ_EMMC_CMD 0x0040
/* RPMB Response Types */ #define VIRTIO_RPMB_RESP_PROGRAM_KEY 0x0100 #define VIRTIO_RPMB_RESP_GET_COUNTER 0x0200 #define VIRTIO_RPMB_RESP_DATA_WRITE 0x0300 #define VIRTIO_RPMB_RESP_DATA_READ 0x0400 +#define VIRTIO_RPMB_RESP_EMMC_CMD 0x4000 \end{lstlisting}
\begin{description} @@ -96,6 +100,16 @@ \subsection{Device Operation}\label{sec:Device Types / RPMB Device / Device Oper It is used following with VIRTIO_RPMB_REQ_PROGRAM_KEY or VIRTIO_RPMB_REQ_DATA_WRITE request types for a returned result in one or multiple RPMB frames. If it's not requested, the device will not return result frame to the driver. + + \item[\field{VIRTIO_RPMB_REQ_EMMC_CMD}] passes through an eMMC probe command. + This is intended to simplify drivers which are already part of an + eMMC driver stack. Rather than have the device driver fake + responses to an eMMC probe it can pass the commands to the backend + to respond on it's behalf. Normal eMMC read/writes will not be + possible and access to the RPMB storage MUST only use the existing + VIRTIO_RPMB_REQ commands. + + (confirm do all eMMC commands have implicit responses?) \end{description}
@@ -106,7 +120,10 @@ \subsubsection{Device Operation: Request Queue}\label{sec:Device Types / RPMB De
\begin{lstlisting} struct virtio_rpmb_frame { - u8 stuff[196]; + union { + u8 stuff[196]; + u8 emmc_cmd_resp[8] + } stuff; u8 key_mac[32]; u8 data[256]; u8 nonce[16]; @@ -126,11 +143,16 @@ \subsubsection{Device Operation: Request Queue}\label{sec:Device Types / RPMB De #define VIRTIO_RPMB_RES_WRITE_FAILURE 0x0005 #define VIRTIO_RPMB_RES_READ_FAILURE 0x0006 #define VIRTIO_RPMB_RES_NO_AUTH_KEY 0x0007 +#define VIRTIO_RPMB_RES_EMMC 0x0040 #define VIRTIO_RPMB_RES_WRITE_COUNTER_EXPIRED 0x0080 \end{lstlisting}
\begin{description} -\item[\field{stuff}] Padding for the frame. +\item[\field{stuff}] For normal RPMB operations this is simply padding + for the frame. When the VIRTIO_RPMB_F_EMMC feature has been + negotiated this contains the embedded EMMC probe command (when + \field{req_resp} is VIRTIO_RPMB_REQ_EMMC_CMD) or the response (when + \field{req_resp} is VIRTIO_RPMB_RESP_EMMC_CMD).
\item[\field{key_mac}] is the authentication key or the message authentication code (MAC) depending on the request/response type.
--8<---------------cut here---------------end--------------->8---
However I'm wary of adding an open ended pass-through definition, especially anything that might tempt an implementer to start trying to read and write data using eMMC commands instead of the proper virtio commands.
- What eMMC commands are needed for a probe? - What are the bounds of frame sizes for those commands? - I'm currently overloading the wasted stuff[196] bytes to the encapsulation and it would get complicated if we extended into the used fields. - Should we mandate certain responses? - e.g. 0 "normal" size, eMMC version 4.1 etc
Thanks,
stratos-dev@op-lists.linaro.org