* SVSM Observability and Configuration Protocol draft
@ 2026-04-14 8:25 Jörg Rödel
2026-04-14 8:46 ` Nicolai Stange
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Jörg Rödel @ 2026-04-14 8:25 UTC (permalink / raw)
To: coconut-svsm; +Cc: Gerd Hoffmann
Hi all,
This is long overdue, but I finally put out a draft of the proposed SVSM
protocol for observability and configuration for review and discussion here:
https://github.com/joergroedel/svsm-specs/blob/main/SVSM_Observability_and_Configuration_Protocol.md
Please reply with your feedback to this email or post PRs against the
repository on GitHub, so we can have the discussion on the PR. The document is
also included inline below.
I will eventually move the repo to the COCONUT-SVSM org, but for now it is
experimental enough to better stay in my personal area.
Thanks,
Joerg
----
# **[DRAFT]** SVSM Observability and Configuration Protocol
The SVSM Observability and Configuration Protocol (OCP) is a new sub-protocol
of the SVSM specification and uses protocol ID value 5. The initial version of
the OCP is 1. Versioning is strictly additive, i.e., all calls present in a
protocol version must also be present in any later version.
The following enumerates the set of calls supported by version 1 of the OCP:
| Call ID | First version supported | Name | Function |
|--------:|------------------------:|------|----------|
| 0 | 1 | `SVSM_OCP_LIST` | Query a list of supported observability and configuration sources. |
| 1 | 1 | `SVSM_OCP_READ` | Read data from an observability source. |
| 2 | 1 | `SVSM_OCP_WRITE` | Write data to a configuration source. |
## SVSM_OCP_LIST Call
The call is used to query a list or sub-list of observability and configuration
sources of the SVSM. The SVSM maintains a list of these sources in an array and
specific sources are addressed via their index into that array. Any array index
is stable during the runtime of the SVSM, only new sources can be added, but no
sources can be removed.
### Registers
| Register | Size (Bytes) | Alignment | In/Out | Description |
|----------|-------------:|----------:|:------:|----------------------------------------|
| `RAX` | 4 | | OUT | Result value |
| `RCX` | 4 | | IN | First index to return from the array |
| `RCX` | 4 | | OUT | Number of array entries returned |
| `RDX` | 8 | 8 | IN | GPA of a buffer to store array entries |
| `R8` | 4 | | IN | Number of array entries to return |
The `SVSM_OCP_LIST` queries a subset of the sources array. The first index to
be returned is passed via the `RCX` register. The `RDX` register points to a
GPA where the SVSM will store the array of entries. The `R8` register
specifies a maximum number of array entries to return.
The number of entries returned by this call is stored in the `RCX` register. If
the returned value is less than the value of `RCX` passed in, then the end of
the array has been reached.
### Source entry layout
One entry in the array is 128 bytes in size and uses the following layout:
| Offset | Size (Bytes) | Description |
|-------:|-------------:|-------------------------------------|
| `0x00` | 4 | Flags |
| `0x04` | 124 | Name of the source encoded as UTF-8 |
The Flags stored in each entry are a bit field stored in little-endian byte
order. The defined flags are:
| Bit(s) | Name | Description |
|-------:|----------------|------------------------------------------------|
| 0 | `WRITEABLE` | The source supports the `SVSM_OCP_WRITE` call. |
| 31:1 | Reserved – MBZ | All other bits are reserved and must be zero. |
## SVSM_OCP_READ Call
This call reads data from a single observability or configuration source.
### Registers
| Register | Size (Bytes) | Alignment | In/Out | Description |
|----------|-------------:|----------:|:------:|-----------------------------------------------------------------------------------|
| `RAX` | 4 | | OUT | Result value |
| `RCX` | 4 | | IN | Array index of the source to read from |
| `RDX` | 8 | 8 | IN | GPA of buffer to copy data into |
| `R8` | 4 | | IN | Number of bytes to read |
| `R8` | 4 | | OUT | Number of bytes copied. If less than requested then end of data has been reached. |
| `R9` | 4 | | IN | Byte offset into data to start read from |
The `SVSM_OCP_READ` call will copy the requested amount of bytes specified in
`R8` from a source into a GPA provided by the caller in `RDX`. Reading starts
at the offset specified in `R9`.
If the specified source index in `RCX` does not exist, the call will return
`SVSM_ERR_INVALID_PARAMETER`.
## SVSM_OCP_WRITE Call
This call will attempt to write data into a specified observability or
configuration source.
### Registers
| Register | Size (Bytes) | Alignment | In/Out | Description |
|----------|-------------:|----------:|:------:|----------------------------------------------------|
| `RAX` | 4 | | OUT | Result value |
| `RCX` | 4 | | IN | Array index of the source to write to |
| `RDX` | 8 | 8 | IN | GPA of buffer with data to write |
| `R8 ` | 4 | | IN | Number of bytes to write |
| `R8` | 4 | | OUT | Number of bytes written |
| `R9` | 4 | | IN | Byte offset into data to start the write operation |
The `SVSM_OCP_WRITE` call attempts to write data from the GPA specified in
`RDX` to the observability or configuration source specified in `RCX`. The size
of the data to write is specified in `R8` and the offset to write the data to
in `R9`.
Sources can only be written to if the Flags field in the `SVSM_OCP_LIST` call
has the `WRITEABLE` bit set. If the source is not writable the call will return
`SVSM_ERR_INVALID_PARAMETER`.
The format of the data allowed to write is source dependent. If a given data
format is not understood by the source the call will also return
`SVSM_ERR_INVALID_PARAMETER`.
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: SVSM Observability and Configuration Protocol draft
2026-04-14 8:25 SVSM Observability and Configuration Protocol draft Jörg Rödel
@ 2026-04-14 8:46 ` Nicolai Stange
2026-04-14 9:07 ` Jörg Rödel
2026-04-14 9:38 ` Carlos López
2026-04-22 9:22 ` Gerd Hoffmann
2 siblings, 1 reply; 7+ messages in thread
From: Nicolai Stange @ 2026-04-14 8:46 UTC (permalink / raw)
To: Jörg Rödel; +Cc: coconut-svsm, Gerd Hoffmann
Hi,
Jörg Rödel <joro@8bytes.org> writes:
> ### Source entry layout
>
> One entry in the array is 128 bytes in size and uses the following layout:
>
> | Offset | Size (Bytes) | Description |
> |-------:|-------------:|-------------------------------------|
> | `0x00` | 4 | Flags |
> | `0x04` | 124 | Name of the source encoded as UTF-8 |
Just a generic comment: as in my understanding there's no central
authority managing the names, would it perhaps make sense to split the
Name from above into something like a 16 byte UUID + a human readable
name, the latter being only informative (or, alternatively, whose
semantics are defined only within the scope of the UUID)?
> The Flags stored in each entry are a bit field stored in little-endian byte
> order. The defined flags are:
>
> | Bit(s) | Name | Description |
> |-------:|----------------|------------------------------------------------|
> | 0 | `WRITEABLE` | The source supports the `SVSM_OCP_WRITE` call. |
> | 31:1 | Reserved – MBZ | All other bits are reserved and must be zero. |
>
<snip>
>
> ## SVSM_OCP_WRITE Call
>
> This call will attempt to write data into a specified observability or
> configuration source.
>
> ### Registers
>
> | Register | Size (Bytes) | Alignment | In/Out | Description |
> |----------|-------------:|----------:|:------:|----------------------------------------------------|
> | `RAX` | 4 | | OUT | Result value |
> | `RCX` | 4 | | IN | Array index of the source to write to |
> | `RDX` | 8 | 8 | IN | GPA of buffer with data to write |
> | `R8 ` | 4 | | IN | Number of bytes to write |
> | `R8` | 4 | | OUT | Number of bytes written |
> | `R9` | 4 | | IN | Byte offset into data to start the write operation |
>
> The `SVSM_OCP_WRITE` call attempts to write data from the GPA specified in
> `RDX` to the observability or configuration source specified in `RCX`. The size
> of the data to write is specified in `R8` and the offset to write the data to
> in `R9`.
>
> Sources can only be written to if the Flags field in the `SVSM_OCP_LIST` call
> has the `WRITEABLE` bit set. If the source is not writable the call will return
> `SVSM_ERR_INVALID_PARAMETER`.
>
> The format of the data allowed to write is source dependent. If a given data
> format is not understood by the source the call will also return
> `SVSM_ERR_INVALID_PARAMETER`.
I assume other errors would be allowed as well? I'm thinking of a
situation where a "source/configuration" is backed by storage, and
writes to that could fail.
Thanks,
Nicolai
--
SUSE Software Solutions Germany GmbH, Frankenstraße 146, 90461 Nürnberg, Germany
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich
(HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: SVSM Observability and Configuration Protocol draft
2026-04-14 8:46 ` Nicolai Stange
@ 2026-04-14 9:07 ` Jörg Rödel
0 siblings, 0 replies; 7+ messages in thread
From: Jörg Rödel @ 2026-04-14 9:07 UTC (permalink / raw)
To: Nicolai Stange; +Cc: coconut-svsm, Gerd Hoffmann
Hi Nicolai,
On Tue, Apr 14, 2026 at 10:46:33AM +0200, Nicolai Stange wrote:
> > | Offset | Size (Bytes) | Description |
> > |-------:|-------------:|-------------------------------------|
> > | `0x00` | 4 | Flags |
> > | `0x04` | 124 | Name of the source encoded as UTF-8 |
>
> Just a generic comment: as in my understanding there's no central
> authority managing the names, would it perhaps make sense to split the
> Name from above into something like a 16 byte UUID + a human readable
> name, the latter being only informative (or, alternatively, whose
> semantics are defined only within the scope of the UUID)?
I am not sure how much value UUIDs add because the read operations work on
indexes, but I agree that it makes sense to have a defined set of fixed sources
with their indexes as part of the spec. The question is what should be
pre-defined besides the log buffer?
> > The format of the data allowed to write is source dependent. If a given data
> > format is not understood by the source the call will also return
> > `SVSM_ERR_INVALID_PARAMETER`.
>
> I assume other errors would be allowed as well? I'm thinking of a
> situation where a "source/configuration" is backed by storage, and
> writes to that could fail.
True, maybe it makes sense to add some protocol-specific error codes in the
0x8000_0000-0xFFFF_FFFF range.
-Joerg
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: SVSM Observability and Configuration Protocol draft
2026-04-14 8:25 SVSM Observability and Configuration Protocol draft Jörg Rödel
2026-04-14 8:46 ` Nicolai Stange
@ 2026-04-14 9:38 ` Carlos López
2026-04-14 9:59 ` Jörg Rödel
2026-04-22 9:22 ` Gerd Hoffmann
2 siblings, 1 reply; 7+ messages in thread
From: Carlos López @ 2026-04-14 9:38 UTC (permalink / raw)
To: Jörg Rödel, coconut-svsm; +Cc: Gerd Hoffmann
Hi,
On 4/14/26 10:25 AM, Jörg Rödel wrote:
> # **[DRAFT]** SVSM Observability and Configuration Protocol
>
> The SVSM Observability and Configuration Protocol (OCP) is a new sub-protocol
> of the SVSM specification and uses protocol ID value 5. The initial version of
> the OCP is 1. Versioning is strictly additive, i.e., all calls present in a
> protocol version must also be present in any later version.
Maybe we could have a short rationale section with e.g. expected use
cases for the protocol.
>
> The following enumerates the set of calls supported by version 1 of the OCP:
>
> | Call ID | First version supported | Name | Function |
> |--------:|------------------------:|------|----------|
> | 0 | 1 | `SVSM_OCP_LIST` | Query a list of supported observability and configuration sources. |
> | 1 | 1 | `SVSM_OCP_READ` | Read data from an observability source. |
> | 2 | 1 | `SVSM_OCP_WRITE` | Write data to a configuration source. |
I could see some cases where the guest wants to continuously consume
data from the SVSM (e.g. event-like information). Would it make sense to
have another set of calls to set up a shared ring buffer with a
source-defined entry size? Or 2 separate ring buffers in the case of
read/write sources. This could avoid a lot of calling and copying
overhead between the SVSM and the lower VPML guest. If this adds too
much complexity, it could be gated behind a higher protocol version to
allow for simpler implementations.
Best,
Carlos
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: SVSM Observability and Configuration Protocol draft
2026-04-14 9:38 ` Carlos López
@ 2026-04-14 9:59 ` Jörg Rödel
2026-04-14 10:18 ` Carlos López
0 siblings, 1 reply; 7+ messages in thread
From: Jörg Rödel @ 2026-04-14 9:59 UTC (permalink / raw)
To: Carlos López; +Cc: coconut-svsm, Gerd Hoffmann
Hi Carlos,
On Tue, Apr 14, 2026 at 11:38:44AM +0200, Carlos López wrote:
> Maybe we could have a short rationale section with e.g. expected use
> cases for the protocol.
Good idea. The fundamental use-case is to expose the log buffer to the guest
OS. But a lot of others come to mind as well, like memory usage statistics and
more.
> I could see some cases where the guest wants to continuously consume
> data from the SVSM (e.g. event-like information). Would it make sense to
> have another set of calls to set up a shared ring buffer with a
> source-defined entry size? Or 2 separate ring buffers in the case of
> read/write sources. This could avoid a lot of calling and copying
> overhead between the SVSM and the lower VPML guest. If this adds too
> much complexity, it could be gated behind a higher protocol version to
> allow for simpler implementations.
What use-case(s) do you have in mind that would benefit from that? I have a
future extension in mind where the guest OS can register an IRQ which the SVSM
will send when a given source changes. The use-case would be to push a changed
root-hash of the cocoon-fs storage to the guest OS for logging and checking
purposes to make storage-replay attacks harder.
-Joerg
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: SVSM Observability and Configuration Protocol draft
2026-04-14 9:59 ` Jörg Rödel
@ 2026-04-14 10:18 ` Carlos López
0 siblings, 0 replies; 7+ messages in thread
From: Carlos López @ 2026-04-14 10:18 UTC (permalink / raw)
To: Jörg Rödel; +Cc: coconut-svsm, Gerd Hoffmann
On 4/14/26 11:59 AM, Jörg Rödel wrote:
>> I could see some cases where the guest wants to continuously consume
>> data from the SVSM (e.g. event-like information). Would it make sense to
>> have another set of calls to set up a shared ring buffer with a
>> source-defined entry size? Or 2 separate ring buffers in the case of
>> read/write sources. This could avoid a lot of calling and copying
>> overhead between the SVSM and the lower VPML guest. If this adds too
>> much complexity, it could be gated behind a higher protocol version to
>> allow for simpler implementations.
>
> What use-case(s) do you have in mind that would benefit from that? I have a
> future extension in mind where the guest OS can register an IRQ which the SVSM
> will send when a given source changes. The use-case would be to push a changed
> root-hash of the cocoon-fs storage to the guest OS for logging and checking
> purposes to make storage-replay attacks harder.
I don't have a particular use case in mind, but given the general idea
of the protocol, something like this could be used to have poll-based
notification instead of IRQ-based, if the guest desires so. I guess the
log buffer could already benefit from something like this, as it would
remove the need for the guest to call into the SVSM to check if there is
new available data.
Carlos
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: SVSM Observability and Configuration Protocol draft
2026-04-14 8:25 SVSM Observability and Configuration Protocol draft Jörg Rödel
2026-04-14 8:46 ` Nicolai Stange
2026-04-14 9:38 ` Carlos López
@ 2026-04-22 9:22 ` Gerd Hoffmann
2 siblings, 0 replies; 7+ messages in thread
From: Gerd Hoffmann @ 2026-04-22 9:22 UTC (permalink / raw)
To: Jörg Rödel; +Cc: coconut-svsm
> ## SVSM_OCP_LIST Call
>
> The call is used to query a list or sub-list of observability and configuration
> sources of the SVSM.
> ### Source entry layout
>
> One entry in the array is 128 bytes in size and uses the following layout:
>
> | Offset | Size (Bytes) | Description |
> |-------:|-------------:|-------------------------------------|
> | `0x00` | 4 | Flags |
> | `0x04` | 124 | Name of the source encoded as UTF-8 |
>
> The Flags stored in each entry are a bit field stored in little-endian byte
> order. The defined flags are:
>
> | Bit(s) | Name | Description |
> |-------:|----------------|------------------------------------------------|
> | 0 | `WRITEABLE` | The source supports the `SVSM_OCP_WRITE` call. |
> | 31:1 | Reserved – MBZ | All other bits are reserved and must be zero. |
The SVSM_OCP_READ call allows for arbitrary data being returned. So I
think it makes sense to include type information in the returned data
structure, and maybe also usage information.
Things coming to mind:
* u64_value -- integer value (example: number of free pages).
* u64_count -- integer counter (example: number of page faults).
* bool
* str -- variable length string (example: process name).
* str_once -- variable length string, data will be returned only once
(i.e. reading data clears it, example: log buffer).
* sha256 -- hash value (example: cocoonfs root hash).
We might also add the protocol number, so we can tag vtpm sources with
SVSM_VTPM_PROTOCOL, ...
> ## SVSM_OCP_READ Call
>
> This call reads data from a single observability or configuration source.
Idea #1: Add support for a SVSM_OCP_READ_REGISTER call. Supports
fixed-size sources with up to 8 bytes in size. Returns data in a
cpu register instead of a memory buffer (i.e. svsm can skip the guest
page mapping).
Idea #2: Add support for a SVSM_OCP_READ_BATCH call. Allows reading
multiple sources with a single call. Maybe also limit to fixed-size
sources.
take care,
Gerd
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-04-22 9:22 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-14 8:25 SVSM Observability and Configuration Protocol draft Jörg Rödel
2026-04-14 8:46 ` Nicolai Stange
2026-04-14 9:07 ` Jörg Rödel
2026-04-14 9:38 ` Carlos López
2026-04-14 9:59 ` Jörg Rödel
2026-04-14 10:18 ` Carlos López
2026-04-22 9:22 ` Gerd Hoffmann
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.