# mshv

Microsoft Hypervisor wrappers. This repository provides two crates which are
mshv-bindings and mshv-ioctls. These crates will provide the APIs and
definitions to create a VMM on Microsoft Hypervisor along with other rust-vmm
crates.

## Supported Platforms

The mshv-{ioctls, bindings} can be used on x86_64 only.

## Build

```shell
cargo build
```

## How to Update the Generated Bindings

1. Install the bindgen command line interface (this command also updates to the latest version if bindgen is already installed):
```shell
cargo install bindgen-cli
```
2. Verify that the installed version matches (or exceeds) the version specified at the top of the current bindings.rs files:
```
$ bindgen -V
bindgen 0.72.1
$ head -1 mshv-bindings/src/arm64/bindings.rs mshv-bindings/src/x86_64/bindings.rs
==> mshv-bindings/src/arm64/bindings.rs <==
/* automatically generated by rust-bindgen 0.72.1 */

==> mshv-bindings/src/x86_64/bindings.rs <==
/* automatically generated by rust-bindgen 0.72.1 */
```
3. Ensure the kernel source is available locally, as it contains the required `mshv.h` uapi header.
4. Any changes to hypervisor definitions (`hv_*`) should be made in this repository under `/hv-headers/*.h`.[^1]
5. Generate the bindings for both x86_64 and arm64 architectures:
```shell
./scripts/generate_binding.py -k /path/to/kernel --a x86 --bindgen="--with-derive-eq --with-derive-partialeq --with-derive-ord"
./scripts/generate_binding.py -k /path/to/kernel --a arm64 --bindgen="--with-derive-eq --with-derive-partialeq --with-derive-ord"
```
6. By convention, changes to `/hv-headers` and the generated bindings should be committed together in a single commit, separate from any other changes.[^2]

[^1]: These definitions were previously located in the kernel's uapi but have since been moved. A separate version is maintained here and does not need to mirror the kernel version, as they serve different purposes. For example, the kernel only accesses suspend registers and does not require all register definitions, whereas userspace code (such as a VMM) may need to set various registers on a VP.

[^2]: In theory, changing or removing a definition could break existing code in mshv-ioctls, causing that commit to fail compilation. If this occurs, this policy should be revisited. This guideline is not a strict rule, and the goal is for all commits to compile successfully.

## Running the tests

Test (/dev/mshv requires root):
```shell
sudo -E ~/.cargo/bin/cargo test
```

## Release Process

Versioning follows [semver](https://semver.org/). As mshv is currently pre-1.0, minor version increments indicate both new features and breaking changes.

Generally follow the guidelines [here](https://github.com/rust-vmm/community/blob/main/docs/crate_release.md)

`mshv-ioctls` and `mshv-bindings` version numbers stay in sync; they are identical.

1. Update each Cargo.toml and add the relevant changes in each CHANGELOG.md
2. Create PR for the release with the changes from (1)
3. Once the PR is merged, create and push tags for the release:
```
    $ ./scripts/tag_release.py --crate mshv-ioctls
    Created tag: mshv-ioctls-v0.6.0
    $ ./scripts/tag_release.py --crate mshv-bindings
    Created tag: mshv-bindings-v0.6.0
```
4. Check the tags look okay, and push them
```
    git show mshv-ioctls-v0.6.0
    git show mshv-bindings-v0.6.0
    git push --tags
```
5. Create a release on github, use the generated release notes.
6. Create a release on crates.io
```
    cargo login
    cargo publish --package mshv-bindings
    cargo publish --package mshv-ioctls
```
7. Bump the mshv version in upstream [vfio](https://github.com/rust-vmm/vfio)
8. Bump the mshv version in upstream [Cloud Hypervisor](https://github.com/cloud-hypervisor/cloud-hypervisor)
