Skip to content

kernel/protocols: Introduce OMP support - #1138

Open
n-ramacciotti wants to merge 14 commits into
coconut-svsm:mainfrom
n-ramacciotti:protocols/add_ocp
Open

n-ramacciotti wants to merge 14 commits into
coconut-svsm:mainfrom
n-ramacciotti:protocols/add_ocp

Conversation

@n-ramacciotti

@n-ramacciotti n-ramacciotti commented Jun 23, 2026 •

Copy link
Copy Markdown
Contributor

A guest OS, running inside a CVM does not know the state information, such as log data or memory usage, of the SVSM. These sources of information could be useful for the guest OS to understand the environment it is running in. It might also be useful for the guest OS to be able to configure some of these sources.

A new protocol, called Observability and Management Protocol (OMP), has been defined to enable information to be retrieved from an SVSM source, and to allow the configuration of sources in SVSM. All the sources and source categories available in SVSM can be listed using this protocol, and each of them can be read and potentially written.

In this PR the SVSM side of the protocol is implemented.

More details can be found in the commit messages.

Tested on a SNP machine. (Thanks @joergroedel )

/cc @stefano-garzarella @kraxel

This started as part of my work for Google Summer of code [1] based on the draft protocol posted in the mailing list [2]. An update version of the proposal is in one commit of this PR that updates the documentation.

[1] https://wiki.qemu.org/Google_Summer_of_Code_2026
[2] https://lore.kernel.org/coconut-svsm/aeiLnWdClMC6YuLi@sirius.home.kraxel.org/T/#t

@tlendacky

Copy link
Copy Markdown
Contributor

Is this meant to be a Coconut specific protocol or a general any SVSM implementation protocol. If the latter, then it needs to be worked out properly and added to the SVSM specification. If the former, then it will need to use one of the reserved reference implementation protocol numbers and needs to be documented for Coconut.

@n-ramacciotti

Copy link
Copy Markdown
Contributor Author

v2:

  • Introduced OcpSourceOperations trait: now each source must be implement it in order to be used in the protocol. It contains read, write and get_source_entry methods. The latter is useful to retrieve the information and interate over the array. read and write have default implementations which return an error.
  • Source name len is now up to 123 bytes. The last one is reserved for null terminator. If one source has a smaller name, the other bytes are padded with 0. It still panics on len discrepancies.
  • Changed ocp_list_request to take into consideration the new trait and get_source_entry_method. Tested with the linux PR.
  • Introduced SVSM_OCP_READ and SVSM_OCP_WRITE. Not yet tested with linux. Their structure is based on the new trait. They are basically a wrapper for the source trait implementation + input checks.
  • Introduce a [test] commit with a fake log buffer to test the list request.
  • For now, the SOURCE array is built at compile time in a static value of trait objects.
  • Each source should implement Sync for safe access.

@n-ramacciotti

n-ramacciotti commented Jun 29, 2026 •

Copy link
Copy Markdown
Contributor Author

Is this meant to be a Coconut specific protocol or a general any SVSM implementation protocol. If the latter, then it needs to be worked out properly and added to the SVSM specification. If the former, then it will need to use one of the reserved reference implementation protocol numbers and needs to be documented for Coconut.

@tlendacky This is part of my work for google summer of code in the coconut-svsm[1].

This is based on the draft proposal of @joergroedel posted in the mailing list [2].

I believe this will be general for any SVSM implementation protocol.

Sorry for not mentioning this earlier in the PR description. Now it's updated.

[1] https://wiki.qemu.org/Google_Summer_of_Code_2026
[2] https://lore.kernel.org/coconut-svsm/aeiLnWdClMC6YuLi@sirius.home.kraxel.org/T/#t

@00xc 00xc left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realize this is in RFC status still, so feel free to discard my comments if the code changes significantly.

Comment thread kernel/src/protocols/ocp.rs Outdated
Comment thread kernel/src/protocols/ocp.rs Outdated
Comment thread kernel/src/protocols/ocp.rs Outdated
Comment thread kernel/src/protocols/ocp.rs Outdated
@kraxel

kraxel commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

[2] https://lore.kernel.org/coconut-svsm/aeiLnWdClMC6YuLi@sirius.home.kraxel.org/T/#t

The discussion on the protocol died off without conclusion, so I'll use the opportunity to resume it here.

I still think it makes sense to include some information what type of data is returned by a source in the SVSM_OCP_LIST reply (i.e. what became struct OcpSource in this PR). Specifically I think the entries should include enough metadata that the linux kernel driver can proxy the data between svsm and linux userspace without additional knowledge about the sources. Also linux userspace should be able to collect and store metrics without additional knowledge about the source. Only when analyzing the collected data you need to know what the data you got from the svsm actually represents.

The other two ideas from my mail (SVSM_OCP_READ_REGISTER) + (SVSM_OCP_READ_BATCH) can be added to the protocol later on, so lets put those aside for now.

@n-ramacciotti

Copy link
Copy Markdown
Contributor Author

v3:

  • Addressed @00xc's comments:
    • improved panic message and comment when creating OcpSourceFlags
    • Introduced PerCPUMappingGuard and GuestPtr to avoid allocating on the heap. (For now only in SVSM_OCP_LIST handler)

@n-ramacciotti

Copy link
Copy Markdown
Contributor Author

v4:

  • Introduced a new read-only source, which returns the running version of SVSM
  • Introduced a new field kind, which indicates the type of data the source holds
  • Simplified SVSM_OCP_READ and SVSM_OCP_WRITE with removal of heap allocation. Now the copy is source dependent and must be done inside the trait implementation

@n-ramacciotti

n-ramacciotti commented Jul 6, 2026 •

Copy link
Copy Markdown
Contributor Author

v5:

  • Introduced max buffer size
  • Introduced testing in linux fork for read operation. It successfully prints coconut version.

Comment thread kernel/src/protocols/ocp.rs Outdated
Comment thread kernel/src/protocols/ocp.rs Outdated
@n-ramacciotti

n-ramacciotti commented Jul 8, 2026 •

Copy link
Copy Markdown
Contributor Author

v6:

  • moved type field as first element in OcpSource
  • introduced a test source for write operations. Read a counter and increase it multiple times. this will be dropped it's here for testing purposes. (can be tested with the linux PR in coconut fork)
  • rebased on latest main

Todo:

  • improve commit messages

@n-ramacciotti

n-ramacciotti commented Jul 15, 2026 •

Copy link
Copy Markdown
Contributor Author

v7:

  • Introduced multiple sources for each object
  • Used a BtreeMap instead of an array for keeping object.
  • Introduced two different list operations (which probably can be simplified as they are very similar):
    • one for objects details
    • one for sources in a given object
  • Add a test object for:
    • returning svsm version running
    • writing and reading an atomic value
  • Remove const from new of OcpSource as now sources are built at runtime and can use more features (like panic formatting and slice [.. ])

Todo:

  • Test on SNP -> this requires new linux driver version
  • Improve commit messages
  • Implement something similar to VsockDriver::get_first_free_port to store in an atomic variable and fetch a free (super) index?
  • gate the OCP behind a feature?

@stefano-garzarella stefano-garzarella added the in-review PR is under active review and not yet approved label Jul 17, 2026
@n-ramacciotti

n-ramacciotti commented Jul 28, 2026 •

Copy link
Copy Markdown
Contributor Author

v8:

  • Added documentation
  • Introduced feature
  • tested on snp
  • improved commits messages
  • added utility to get free index
  • refactored in multiple modules
  • introduced utilities to interact with the map

TODO:

  • Introduce log buffer. Since this PR is getting big, I'm not sure if it makes sense to add it in this PR or open a new draft based on this PR.

@n-ramacciotti

n-ramacciotti commented Jul 28, 2026 •

Copy link
Copy Markdown
Contributor Author

v9:

  • Introduced log buffer as source
  • Introduced GuestBuffer, similarly to UserBuffer, to read and write data to the guest through fs objects
  • Updated doc on log buffer
  • fixed typo in commit a69a1a3

note: there is a commit marked with test as:

  • I'm not sure where that specific code should be placed (also the SvsmObject name is a placeholder)
  • Part of that commit (the source with write permission) should be dropped

Other than that, the PR is ready for review.

@kraxel kraxel left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor comments, looks good to me overall.

Comment thread kernel/src/protocols/ocp/source.rs Outdated
Comment thread kernel/src/protocols/mod.rs Outdated
Comment thread kernel/src/protocols/ocp/requests.rs Outdated
@n-ramacciotti
n-ramacciotti marked this pull request as ready for review July 29, 2026 14:44
@n-ramacciotti

Copy link
Copy Markdown
Contributor Author

v16:

  • addressed @00xc's comments:
    • Improved comments
    • Changed OcpSource in OcpSourceInfo and used the former for the trait. Moved the trait in source.rs
    • Added utility to extract source and object from the guest provided gpa
    • Removed read and write methods from OcpObject trait.
    • Refactored list branches in two helpers
    • Improvement on ObjectName/SourceName names extraction.
  • Added utilities to check if the offset and size required are aligned to source type.
  • Renamed trait methods to reduce noise

TODO:

  • check object uniqueness
  • change get_sources to avoid Iter

Comment thread kernel/src/protocols/ocp/requests.rs Outdated
Comment thread kernel/src/protocols/ocp/requests.rs Outdated
Comment thread kernel/src/protocols/ocp/requests.rs Outdated
Comment thread kernel/src/protocols/ocp/requests.rs Outdated
Comment thread kernel/src/protocols/ocp/requests.rs Outdated
Comment thread kernel/src/ocp_test.rs Outdated
Comment thread kernel/src/protocols/ocp/source.rs Outdated
@n-ramacciotti
n-ramacciotti force-pushed the protocols/add_ocp branch 2 times, most recently from fffe718 to 48d4aff Compare September 21, 2026 14:09
@n-ramacciotti

n-ramacciotti commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor Author

v17:

  • addressed @00xc's comments:
    • Renamed OcpSource trait methods to write_to_guest and read_from_guest
    • Renamed ocp_source_entries in sources
    • Merged checks in single if where possible
    • Used read_from_guest instead of the manual counterpart
    • Avoided multiple map_err()
    • Now a failure when writing entries returns an error and the number of entries written up to that moment + total entries. The error is logged and the number of entries written is returned to the guest
    • Introduced take on iterator
  • Used checked_page_align_up instead of page_align_up

TODO:

Comment thread kernel/src/protocols/omp/requests.rs
Comment thread kernel/src/protocols/omp/requests.rs
Comment thread kernel/src/protocols/omp/requests.rs
@n-ramacciotti

Copy link
Copy Markdown
Contributor Author

v18:

  • addressed @00xc's comments:
    • added documentation for Result<(usize,usize),(SvsmReqError,usize,usize)> and divided the error branch in two parts in list_request
    • Introduced for_each_source instead of get_sources.
  • Introduced object uniqueness based on name

Comment thread kernel/src/protocols/ocp/source.rs Outdated
@n-ramacciotti

Copy link
Copy Markdown
Contributor Author

v19:

  • improved comments
  • added OcpSourceCallback type alias to address type complexity highlighted by clippy here.

@joergroedel

Copy link
Copy Markdown
Member

v19:

* improved comments

* added `OcpSourceCallback` type alias to address `type complexity` highlighted by clippy [here](https://github.com/coconut-svsm/svsm/actions/runs/35848083992/job/107139555502?pr=1138).

Thanks a lot for moving this forward! After some more discussion with the various stakeholders we made the decision to rename the protocol from OCP to OMP (Observeability and Management Protocol). Can you please use the new name in the PR?

The new observability and configuration protocol requires an additional
register `r9` to exchange data between svsm and the guest os.

Add it to the `RequestParams` structure to fulfill this requirement.

Signed-off-by: Nicola Ramacciotti <niko.ramak@gmail.com>
Link the new Observability and Management Protocol (OMP) to the correct
handler during request processing.

Since a different protocol name was introduced in a previous commit,
update the reserved name to the new version.

Fixes: a8c0fea ("kernel/protocols: Reserve OCP number")
Signed-off-by: Nicola Ramacciotti <niko.ramak@gmail.com>
Add a new structure, based on OMP protocol specifications.

A source entry has a 4-byte bitfield flag field, where the least
significant bit specifies if a sources is writable or not. The other
bits are reserved.

Also include a 2-byte `kind` field to store information on the source
type. This will help the guest understand which data is transmitted
and the dimension required for the buffer to store these values.

A 2-byte padding is added and each entry should be exactly 128-bytes,
so the remaining space is left for a human readable name (utf-8 encoded).

Introduce a new const constructor which can be used for initializing
a source. This function will fail if the name is greater than or equal
to all its reserved bytes, as we want the name to be null terminated.
If the name is less than that value, it will be padded with zeros. It
will also fail if the name contains a '/', as this is used in the protocol
calls to group objects and sources.

As these sources will be passed to the linux guest, it is useful to
derive `IntoBytes` and `Immutable` for the transfer.

Signed-off-by: Nicola Ramacciotti <niko.ramak@gmail.com>
Add two new traits, one for object and one for sources. Each object and
source must implement the corresponding one to be added to the protocol.

The traits include default implementations for the `read` and `write`
methods, as each object or source may not have that functionality, in
which case an error is returned.

The traits also include the `for_each_source` method to iterate over the
sources of an object and apply a callback to each of them. This can be
used for incrementally assembling the reply to the guest OS. As it may be
useful to stop the iteration early, the callback returns a boolean value
that the method can use for this purpose.

To keep `OmpObject` dyn-compatible, the callback in `for_each_source` must
avoid generics. Therefore, use dynamic dispatch with mutable state as it
may be useful to mutate it, such as the number of entries written.
Use a type alias for the callback to avoid the type complexity highlighted
by Clippy.

Require the `Sync` bound as we want to share objects between threads
safely. Require `Send` and `Debug` for completeness.

Signed-off-by: Nicola Ramacciotti <niko.ramak@gmail.com>
Add a vec to keep track of all the objects that implement the new trait.

Since most of the access are read, use `RWLock` to lock the access to
the vec. Add utilities to interact with objects.

Signed-off-by: Nicola Ramacciotti <niko.ramak@gmail.com>
The protocol uses OMP names to request sources or objects.

A single name is sufficient for objects, but sources require an identifier
composed of both the object and source names separated by '/'.

The guest OS puts the GPA of the name in the request parameters. Add two
utility functions to retrieve the name and extract the corresponding source
or object.

Signed-off-by: Nicola Ramacciotti <niko.ramak@gmail.com>
Add the new call identifier (`0`) to the OMP handler and implement
`SVSM_OMP_LIST` following the spec.

If some guest params are incorrect, like buffer alignment or zero bytes
requested, an appropriate error will be returned.

The buffer len is 4-bytes, so make sure to use only the low 32 bits.

Compute the number of entries required and use `GuestPtr<[T]>` to access
safely the untrusted guest region.

Once an entry is available, it is possible to copy it directly to the guest
memory without using temporary heap allocation to store all the entries
together.

As this call requires SVSM to provide a list of entries, use the new
helpers to extract objects and sources. Failing to write an entry in the
guest memory results in a log message, as other entries may have already
been written and the result can therefore be shared with the guest.

Signed-off-by: Nicola Ramacciotti <niko.ramak@gmail.com>
Add the new call identifier (`1`) to the OMP handler and implement
`SVSM_OMP_READ` following the spec.

Use the new utility to extract the source and check if the provided
parameters are correct.

Since each source is required to implement the `OmpSource` trait, the read
method can be used directly.

Signed-off-by: Nicola Ramacciotti <niko.ramak@gmail.com>
Add the new call identifier (`2`) to the OMP handler and implement
`SVSM_OMP_WRITE` following the spec.

Use the new utility to extract the source and check if the provided
parameters are correct.

Since each source is required to implement the `OmpSource` trait, the
write method can be used directly.

Signed-off-by: Nicola Ramacciotti <niko.ramak@gmail.com>
The query protocol is used to check the availability of a protocol at a
given version.

It should take into account every available protocol. Add the new OMP
protocol management.

Signed-off-by: Nicola Ramacciotti <niko.ramak@gmail.com>
Add `observability` feature to conditionally compile the new protocol.

Add it to `FEATURES_TEST` to enable it by default on test builds.

Signed-off-by: Nicola Ramacciotti <niko.ramak@gmail.com>
Add basic description of the new protocol.

Signed-off-by: Nicola Ramacciotti <niko.ramak@gmail.com>
OMP sources shares data with the guest. Some of them, like the log buffer,
are file based.

The `Buffer` trait let exchange data between a file and a buffer.

Add an implementation of the `Buffer` trait for accessing guest memory.

Signed-off-by: Nicola Ramacciotti <niko.ramak@gmail.com>
Introduce a new object which can contain some sources, implement the trait
and create a new instance which is inserted in the vec.

Introduce a read only source that only returns a static string containing the
current SVSM version.

Add a log buffer source to extract log messages.

This commit will be dropped and it used only to test the infrastructure.

Signed-off-by: Nicola Ramacciotti <niko.ramak@gmail.com>
@n-ramacciotti

Copy link
Copy Markdown
Contributor Author

v20:

  • renamed OCP to OMP @joergroedel
    • only in this PR for now (not in linux driver or userspace application), but the system should still work
  • reorderd "kernel/protocols: Introduce OMP protocol management" as second commit
  • used "[drop]" instead of "[test]" for the last commit
  • rebased on latest main

No functional changes

@n-ramacciotti n-ramacciotti changed the title kernel/protocols: Introduce OCP support kernel/protocols: Introduce OMP support Oct 9, 2026

This branch has not been deployed

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

Labels

in-review PR is under active review and not yet approved

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants