|
| 1 | +# Contributing to kvm-bindings |
| 2 | + |
| 3 | +## Dependencies |
| 4 | + |
| 5 | +### Bindgen |
| 6 | +The bindings are currently generated using |
| 7 | +[bindgen](https://crates.io/crates/bindgen) version 0.70.1: |
| 8 | +```bash |
| 9 | +cargo install bindgen-cli --vers 0.70.1 |
| 10 | +``` |
| 11 | + |
| 12 | +### Linux Kernel |
| 13 | +Generating bindings depends on the Linux kernel, so you need to have the |
| 14 | +repository on your machine: |
| 15 | + |
| 16 | +```bash |
| 17 | +git clone https://github.com/torvalds/linux.git |
| 18 | +``` |
| 19 | + |
| 20 | +## Updating bindings / adding a new architecture |
| 21 | + |
| 22 | +When adding a new architecture, the bindings must be generated for all existing |
| 23 | +versions for consistency reasons. |
| 24 | + |
| 25 | +### Example for arm64 and kernel version 6.9 |
| 26 | + |
| 27 | +For this example we assume that you have both linux and kvm-bindings |
| 28 | +repositories in your root. |
| 29 | + |
| 30 | +```bash |
| 31 | +# Step 1 (if adding a new architecture): Create a new module using the name of the architecture in src/ |
| 32 | +pushd kvm-bindings |
| 33 | +mkdir src/arm64 |
| 34 | +popd |
| 35 | + |
| 36 | +# linux is the repository that you cloned at the previous step. |
| 37 | +pushd linux |
| 38 | +# Step 2: Checkout the version you want to generate the bindings for. |
| 39 | +git checkout v6.9 |
| 40 | + |
| 41 | +# Step 3: Generate the bindings. |
| 42 | +# This will generate the headers for the targeted architecture and place them |
| 43 | +# in the user specified directory |
| 44 | + |
| 45 | +export ARCH=arm64 |
| 46 | +make headers_install ARCH=$ARCH INSTALL_HDR_PATH="$ARCH"_headers |
| 47 | +pushd "$ARCH"_headers |
| 48 | +bindgen include/linux/kvm.h -o bindings.rs \ |
| 49 | + --impl-debug --with-derive-default \ |
| 50 | + --with-derive-partialeq --impl-partialeq \ |
| 51 | + -- -Iinclude |
| 52 | +popd |
| 53 | + |
| 54 | +# Step 4: Copy the generated file to the arm64 module. |
| 55 | +popd |
| 56 | +cp linux/"$ARCH"_headers/bindings.rs kvm-bindings/src/arm64 |
| 57 | + |
| 58 | +``` |
| 59 | + |
| 60 | +Steps 2, 3 and 4 must be repeated for all existing architectures. |
| 61 | + |
| 62 | +Now that we have the bindings generated, for a new architecture we can copy the |
| 63 | +module file from one of the existing modules. |
| 64 | + |
| 65 | +```bash |
| 66 | +cp arm/mod.rs arm64/ |
| 67 | +``` |
| 68 | + |
| 69 | +Also, you will need to add the new architecture to `kvm-bindings/lib.rs`. |
| 70 | + |
| 71 | +When regenerating bindings, care must be taken to re-add various `zerocopy` |
| 72 | +derives under the `serde` feature. All items that require derives are |
| 73 | +listed in the `x86_64/serialize.rs` and `arm64/serialize.rs` inside the |
| 74 | +`serde_impls!` macro invocation, and missing derives will cause these |
| 75 | +modules to fail compilation. For all items listed here, the following |
| 76 | +derive should be present: |
| 77 | + |
| 78 | +```rs |
| 79 | +#[cfg_attr( |
| 80 | + feature = "serde", |
| 81 | + derive(zerocopy::AsBytes, zerocopy::FromBytes, zerocopy::FromZeroes) |
| 82 | +)] |
| 83 | +``` |
| 84 | + |
| 85 | +Any types whose name contains a suffix akin to `__bindgen_ty_<number>` and |
| 86 | +which is contained in any struct listed in `serialize.rs` will also need |
| 87 | +to have this derive added (otherwise compilation will fail). Note that |
| 88 | +these types are not explicitly listed in `serialize.rs`, as their names |
| 89 | +can change across `bindgen.rs` versions. |
| 90 | + |
| 91 | +Lastly, in `x86_64/bindings.rs`, the derives also need to be added to |
| 92 | +`struct __BindgenBitfieldUnit<Storage>` and `struct __IncompleteArrayField<T>`. |
| 93 | +Additionally, these structs need to have their layout changed from `#[repr(C)]` |
| 94 | +to `#[repr(transparent)]`. This is needed because `zerocopy` traits can only be |
| 95 | +derived on generic structures that are `repr(transparent)` or `repr(packed)`. |
| 96 | + |
| 97 | +### Future Improvements |
| 98 | +All the above steps are scriptable, so in the next iteration I will add a |
| 99 | +script to generate the bindings. |
| 100 | + |
| 101 | +# Testing |
| 102 | + |
| 103 | +This crate is tested using |
| 104 | +[rust-vmm-ci](https://github.com/rust-vmm/rust-vmm-ci) and |
| 105 | +[Buildkite](https://buildkite.com/) pipelines. Each new feature added to this crate must be |
| 106 | +accompanied by Buildkite steps for testing the following: |
| 107 | +- Release builds (using musl/gnu) with the new feature on arm and x86 |
| 108 | +- Coverage test as specified in the |
| 109 | +[rust-vmm-ci readme](https://github.com/rust-vmm/rust-vmm-ci#getting-started-with-rust-vmm-ci). |
0 commit comments