Skip to content

Commit 789db44

Browse files
roypatShadowCurse
authored andcommitted
doc(vm): Fix up target_arch cfgs
When they are needed, hide them from carg doc output (in favor of a comment above the example that calls out which architectures the example will work on). If they're not needed (e.g. because the function itself is already cfg'd to that specific architecture), drop them. In some cases, replace cfgs with explicit checks of KVM capabilities (specifically around guest_memfd stuff). Also fix up the guest_memfd doctests not using a VM type that supports guest private memory (if one exists, aka only on x86). Signed-off-by: Patrick Roy <[email protected]>
1 parent dae83c3 commit 789db44

File tree

1 file changed

+130
-126
lines changed

1 file changed

+130
-126
lines changed

src/ioctls/vm.rs

Lines changed: 130 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ impl VmFd {
6969
/// # Arguments
7070
///
7171
/// * `user_memory_region` - Guest physical memory slot. For details check the
72-
/// `kvm_userspace_memory_region` structure in the
72+
/// `kvm_userspace_memory_region` structure in the
7373
/// [KVM API doc](https://www.kernel.org/doc/Documentation/virtual/kvm/api.txt).
7474
///
7575
/// # Safety
@@ -138,6 +138,8 @@ impl VmFd {
138138
///
139139
/// # Example
140140
///
141+
/// On x86, create a `KVM_X86_SW_PROTECTED_VM` with a memslot that has a `guest_memfd` associated.
142+
///
141143
/// ```rust
142144
/// # extern crate kvm_ioctls;
143145
/// extern crate kvm_bindings;
@@ -149,51 +151,53 @@ impl VmFd {
149151
/// use kvm_ioctls::Kvm;
150152
/// use std::os::fd::RawFd;
151153
///
152-
/// # #[cfg(target_arch = "x86_64")]
153-
/// {
154-
/// let kvm = Kvm::new().unwrap();
155-
/// let vm = kvm.create_vm().unwrap();
156-
///
157-
/// let address_space = unsafe { libc::mmap(0 as _, 10000, 3, 34, -1, 0) };
158-
/// let userspace_addr = address_space as *const u8 as u64;
154+
/// let kvm = Kvm::new().unwrap();
155+
/// #[cfg(target_arch = "x86_64")]
156+
/// let vm = kvm
157+
/// .create_vm_with_type(kvm_bindings::KVM_X86_SW_PROTECTED_VM as u64)
158+
/// .unwrap();
159+
/// #[cfg(target_arch = "aarch64")]
160+
/// let vm = kvm.create_vm().unwrap(); /* ARM does not yet have a vm type that supports gmem */
159161
///
160-
/// let mut config = kvm_enable_cap {
161-
/// cap: KVM_CAP_GUEST_MEMFD,
162-
/// ..Default::default()
163-
/// };
162+
/// let address_space = unsafe { libc::mmap(0 as _, 10000, 3, 34, -1, 0) };
163+
/// let userspace_addr = address_space as *const u8 as u64;
164164
///
165-
/// if vm.enable_cap(&config).is_err() {
166-
/// return;
167-
/// }
168-
/// let gmem = kvm_create_guest_memfd {
169-
/// size: 0x10000,
170-
/// flags: 0,
171-
/// reserved: [0; 6],
172-
/// };
165+
/// let mut config = kvm_enable_cap {
166+
/// cap: KVM_CAP_GUEST_MEMFD,
167+
/// ..Default::default()
168+
/// };
173169
///
174-
/// let fd: RawFd = unsafe { vm.create_guest_memfd(gmem).unwrap() };
170+
/// if vm.enable_cap(&config).is_err() {
171+
/// return;
172+
/// }
173+
/// let gmem = kvm_create_guest_memfd {
174+
/// size: 0x10000,
175+
/// flags: 0,
176+
/// reserved: [0; 6],
177+
/// };
175178
///
176-
/// config.cap = KVM_CAP_USER_MEMORY2;
179+
/// let fd: RawFd = unsafe { vm.create_guest_memfd(gmem).unwrap() };
177180
///
178-
/// if vm.enable_cap(&config).is_err() {
179-
/// return;
180-
/// }
181+
/// config.cap = KVM_CAP_USER_MEMORY2;
181182
///
182-
/// let mem_region = kvm_userspace_memory_region2 {
183-
/// slot: 0,
184-
/// flags: KVM_MEM_GUEST_MEMFD,
185-
/// guest_phys_addr: 0x10000 as u64,
186-
/// memory_size: 0x10000 as u64,
187-
/// userspace_addr,
188-
/// guest_memfd_offset: 0,
189-
/// guest_memfd: fd as u32,
190-
/// pad1: 0,
191-
/// pad2: [0; 14],
192-
/// };
193-
/// unsafe {
194-
/// vm.set_user_memory_region2(mem_region).unwrap();
195-
/// };
183+
/// if vm.enable_cap(&config).is_err() {
184+
/// return;
196185
/// }
186+
///
187+
/// let mem_region = kvm_userspace_memory_region2 {
188+
/// slot: 0,
189+
/// flags: KVM_MEM_GUEST_MEMFD,
190+
/// guest_phys_addr: 0x10000 as u64,
191+
/// memory_size: 0x10000 as u64,
192+
/// userspace_addr,
193+
/// guest_memfd_offset: 0,
194+
/// guest_memfd: fd as u32,
195+
/// pad1: 0,
196+
/// pad2: [0; 14],
197+
/// };
198+
/// unsafe {
199+
/// vm.set_user_memory_region2(mem_region).unwrap();
200+
/// };
197201
/// ```
198202
pub unsafe fn set_user_memory_region2(
199203
&self,
@@ -283,7 +287,7 @@ impl VmFd {
283287
/// use kvm_bindings::{
284288
/// kvm_create_device, kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V2, KVM_CREATE_DEVICE_TEST,
285289
/// };
286-
/// let mut gic_device = kvm_bindings::kvm_create_device {
290+
/// let mut gic_device = kvm_create_device {
287291
/// type_: kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V2,
288292
/// fd: 0,
289293
/// flags: KVM_CREATE_DEVICE_TEST,
@@ -1373,26 +1377,22 @@ impl VmFd {
13731377
/// let kvm = Kvm::new().unwrap();
13741378
/// let vm = kvm.create_vm().unwrap();
13751379
/// let mut cap: kvm_enable_cap = Default::default();
1376-
/// // This example cannot enable an arm/aarch64 capability since there
1377-
/// // is no capability available for these architectures.
1378-
/// if cfg!(target_arch = "x86_64") {
1379-
/// cap.cap = KVM_CAP_SPLIT_IRQCHIP;
1380-
/// // As per the KVM documentation, KVM_CAP_SPLIT_IRQCHIP only emulates
1381-
/// // the local APIC in kernel, expecting that a userspace IOAPIC will
1382-
/// // be implemented by the VMM.
1383-
/// // Along with this capability, the user needs to specify the number
1384-
/// // of pins reserved for the userspace IOAPIC. This number needs to be
1385-
/// // provided through the first argument of the capability structure, as
1386-
/// // specified in KVM documentation:
1387-
/// // args[0] - number of routes reserved for userspace IOAPICs
1388-
/// //
1389-
/// // Because an IOAPIC supports 24 pins, that's the reason why this test
1390-
/// // picked this number as reference.
1391-
/// cap.args[0] = 24;
1392-
/// vm.enable_cap(&cap).unwrap();
1393-
/// }
1380+
/// cap.cap = KVM_CAP_SPLIT_IRQCHIP;
1381+
/// // As per the KVM documentation, KVM_CAP_SPLIT_IRQCHIP only emulates
1382+
/// // the local APIC in kernel, expecting that a userspace IOAPIC will
1383+
/// // be implemented by the VMM.
1384+
/// // Along with this capability, the user needs to specify the number
1385+
/// // of pins reserved for the userspace IOAPIC. This number needs to be
1386+
/// // provided through the first argument of the capability structure, as
1387+
/// // specified in KVM documentation:
1388+
/// // args[0] - number of routes reserved for userspace IOAPICs
1389+
/// //
1390+
/// // Because an IOAPIC supports 24 pins, that's the reason why this test
1391+
/// // picked this number as reference.
1392+
/// cap.args[0] = 24;
1393+
/// vm.enable_cap(&cap).unwrap();
13941394
/// ```
1395-
#[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))]
1395+
#[cfg(any(target_arch = "x86_64", target_arch = "s390x", target_arch = "powerpc"))]
13961396
pub fn enable_cap(&self, cap: &kvm_enable_cap) -> Result<()> {
13971397
// SAFETY: The ioctl is safe because we allocated the struct and we know the
13981398
// kernel will write exactly the size of the struct.
@@ -1464,28 +1464,30 @@ impl VmFd {
14641464
/// use kvm_bindings::{kvm_create_guest_memfd, kvm_enable_cap, KVM_CAP_GUEST_MEMFD};
14651465
/// use std::os::fd::RawFd;
14661466
///
1467-
/// # #[cfg(target_arch = "x86_64")]
1468-
/// {
1469-
/// let kvm = Kvm::new().unwrap();
1470-
/// let vm = kvm.create_vm().unwrap();
1467+
/// let kvm = Kvm::new().unwrap();
1468+
/// #[cfg(target_arch = "x86_64")]
1469+
/// let vm = kvm
1470+
/// .create_vm_with_type(kvm_bindings::KVM_X86_SW_PROTECTED_VM as u64)
1471+
/// .unwrap();
1472+
/// #[cfg(target_arch = "aarch64")]
1473+
/// let vm = kvm.create_vm().unwrap(); /* ARM does not yet have a vm type that supports gmem */
14711474
///
1472-
/// let config = kvm_enable_cap {
1473-
/// cap: KVM_CAP_GUEST_MEMFD,
1474-
/// ..Default::default()
1475-
/// };
1475+
/// let config = kvm_enable_cap {
1476+
/// cap: KVM_CAP_GUEST_MEMFD,
1477+
/// ..Default::default()
1478+
/// };
14761479
///
1477-
/// if vm.enable_cap(&config).is_err() {
1478-
/// return;
1479-
/// }
1480+
/// if vm.enable_cap(&config).is_err() {
1481+
/// return;
1482+
/// }
14801483
///
1481-
/// let gmem = kvm_create_guest_memfd {
1482-
/// size: 0x1000,
1483-
/// flags: 0,
1484-
/// reserved: [0; 6],
1485-
/// };
1484+
/// let gmem = kvm_create_guest_memfd {
1485+
/// size: 0x1000,
1486+
/// flags: 0,
1487+
/// reserved: [0; 6],
1488+
/// };
14861489
///
1487-
/// let id: RawFd = vm.create_guest_memfd(gmem).unwrap();
1488-
/// }
1490+
/// let guest_memfd = vm.create_guest_memfd(gmem).unwrap();
14891491
/// ```
14901492
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
14911493
pub fn create_guest_memfd(&self, gmem: kvm_create_guest_memfd) -> Result<RawFd> {
@@ -1524,61 +1526,63 @@ impl VmFd {
15241526
/// };
15251527
/// use std::os::fd::RawFd;
15261528
///
1527-
/// # #[cfg(target_arch = "x86_64")]
1528-
/// {
1529-
/// let kvm = Kvm::new().unwrap();
1530-
/// let vm = kvm.create_vm().unwrap();
1531-
/// let gmem = kvm_create_guest_memfd {
1532-
/// size: 0x10000,
1533-
/// flags: 0,
1534-
/// reserved: [0; 6],
1535-
/// };
1536-
///
1537-
/// let address_space = unsafe { libc::mmap(0 as _, 10000, 3, 34, -1, 0) };
1538-
/// let userspace_addr = address_space as *const u8 as u64;
1539-
/// let mut config = kvm_enable_cap {
1540-
/// cap: KVM_CAP_GUEST_MEMFD,
1541-
/// ..Default::default()
1542-
/// };
1529+
/// let kvm = Kvm::new().unwrap();
1530+
/// #[cfg(target_arch = "x86_64")]
1531+
/// let vm = kvm
1532+
/// .create_vm_with_type(kvm_bindings::KVM_X86_SW_PROTECTED_VM as u64)
1533+
/// .unwrap();
1534+
/// #[cfg(target_arch = "aarch64")]
1535+
/// let vm = kvm.create_vm().unwrap(); /* ARM does not yet have a vm type that supports gmem */
1536+
/// let gmem = kvm_create_guest_memfd {
1537+
/// size: 0x10000,
1538+
/// flags: 0,
1539+
/// reserved: [0; 6],
1540+
/// };
15431541
///
1544-
/// if vm.enable_cap(&config).is_err() {
1545-
/// return;
1546-
/// }
1542+
/// let address_space = unsafe { libc::mmap(0 as _, 10000, 3, 34, -1, 0) };
1543+
/// let userspace_addr = address_space as *const u8 as u64;
1544+
/// let mut config = kvm_enable_cap {
1545+
/// cap: KVM_CAP_GUEST_MEMFD,
1546+
/// ..Default::default()
1547+
/// };
15471548
///
1548-
/// config.cap = KVM_CAP_USER_MEMORY2;
1549+
/// if vm.enable_cap(&config).is_err() {
1550+
/// return;
1551+
/// }
15491552
///
1550-
/// if vm.enable_cap(&config).is_err() {
1551-
/// return;
1552-
/// }
1553-
/// config.cap = KVM_CAP_MEMORY_ATTRIBUTES;
1553+
/// config.cap = KVM_CAP_USER_MEMORY2;
15541554
///
1555-
/// if vm.enable_cap(&config).is_err() {
1556-
/// return;
1557-
/// }
1558-
/// let fd: RawFd = unsafe { vm.create_guest_memfd(gmem).unwrap() };
1559-
/// let mem_region = kvm_userspace_memory_region2 {
1560-
/// slot: 0,
1561-
/// flags: KVM_MEM_GUEST_MEMFD,
1562-
/// guest_phys_addr: 0x10000 as u64,
1563-
/// memory_size: 0x10000 as u64,
1564-
/// userspace_addr,
1565-
/// guest_memfd_offset: 0,
1566-
/// guest_memfd: fd as u32,
1567-
/// pad1: 0,
1568-
/// pad2: [0; 14],
1569-
/// };
1570-
/// unsafe {
1571-
/// vm.set_user_memory_region2(mem_region).unwrap();
1572-
/// };
1555+
/// if vm.enable_cap(&config).is_err() {
1556+
/// return;
1557+
/// }
1558+
/// config.cap = KVM_CAP_MEMORY_ATTRIBUTES;
15731559
///
1574-
/// let attr = kvm_memory_attributes {
1575-
/// address: 0x10000,
1576-
/// size: 0x10000,
1577-
/// attributes: KVM_MEMORY_ATTRIBUTE_PRIVATE as u64,
1578-
/// flags: 0,
1579-
/// };
1580-
/// vm.set_memory_attributes(attr).unwrap();
1560+
/// if vm.enable_cap(&config).is_err() {
1561+
/// return;
15811562
/// }
1563+
/// let fd: RawFd = unsafe { vm.create_guest_memfd(gmem).unwrap() };
1564+
/// let mem_region = kvm_userspace_memory_region2 {
1565+
/// slot: 0,
1566+
/// flags: KVM_MEM_GUEST_MEMFD,
1567+
/// guest_phys_addr: 0x10000 as u64,
1568+
/// memory_size: 0x10000 as u64,
1569+
/// userspace_addr,
1570+
/// guest_memfd_offset: 0,
1571+
/// guest_memfd: fd as u32,
1572+
/// pad1: 0,
1573+
/// pad2: [0; 14],
1574+
/// };
1575+
/// unsafe {
1576+
/// vm.set_user_memory_region2(mem_region).unwrap();
1577+
/// };
1578+
///
1579+
/// let attr = kvm_memory_attributes {
1580+
/// address: 0x10000,
1581+
/// size: 0x10000,
1582+
/// attributes: KVM_MEMORY_ATTRIBUTE_PRIVATE as u64,
1583+
/// flags: 0,
1584+
/// };
1585+
/// vm.set_memory_attributes(attr).unwrap();
15821586
/// ```
15831587
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
15841588
pub fn set_memory_attributes(&self, attr: kvm_memory_attributes) -> Result<()> {

0 commit comments

Comments
 (0)