• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

google / alioth / 18602811487

17 Oct 2025 06:27PM UTC coverage: 17.44% (-0.4%) from 17.856%
18602811487

push

github

Lencerf
test(pci): add tests for HostBridge

Signed-off-by: Changyuan Lyu <changyuanl@google.com>

1394 of 7993 relevant lines covered (17.44%)

17.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

100.0
/alioth/src/sys/linux/ioctl.rs
1
// Copyright 2024 Google LLC
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15
use std::mem::size_of;
16

17
const IOC_NONN: u32 = 0;
18
const IOC_WRITE: u32 = 1;
19
const IOC_READ: u32 = 2;
20

21
const IOC_NRSHIFT: usize = 0;
22
const IOC_TYPESHIFT: usize = 8;
23
const IOC_SIZESHIFT: usize = 16;
24
const IOC_DIRSHIFT: usize = 30;
25

26
const fn ioctl_ioc(dir: u32, type_: u8, nr: u8, size: u32) -> u32 {
5✔
27
    (dir << IOC_DIRSHIFT)
8✔
28
        | (size << IOC_SIZESHIFT)
5✔
29
        | ((type_ as u32) << IOC_TYPESHIFT)
5✔
30
        | ((nr as u32) << IOC_NRSHIFT)
5✔
31
}
32

33
pub const fn ioctl_io(type_: u8, nr: u8) -> u32 {
2✔
34
    ioctl_ioc(IOC_NONN, type_, nr, 0)
4✔
35
}
36

37
pub const fn ioctl_ior<T>(type_: u8, nr: u8) -> u32 {
2✔
38
    ioctl_ioc(IOC_READ, type_, nr, size_of::<T>() as u32)
5✔
39
}
40

41
pub const fn ioctl_iow<T>(type_: u8, nr: u8) -> u32 {
2✔
42
    ioctl_ioc(IOC_WRITE, type_, nr, size_of::<T>() as u32)
5✔
43
}
44

45
pub const fn ioctl_iowr<T>(type_: u8, nr: u8) -> u32 {
2✔
46
    ioctl_ioc(IOC_WRITE | IOC_READ, type_, nr, size_of::<T>() as u32)
6✔
47
}
48

49
#[macro_export]
50
macro_rules! ioctl_none {
51
    ($name:ident, $type_:expr, $nr:expr, $val:expr) => {
52
        #[allow(clippy::missing_safety_doc)]
53
        pub unsafe fn $name<F: ::std::os::fd::AsFd>(fd: &F) -> ::std::io::Result<libc::c_int> {
54
            let op = $crate::sys::ioctl::ioctl_io($type_, $nr);
55
            let v = $val as ::libc::c_ulong;
56
            $crate::ffi!(unsafe {
57
                ::libc::ioctl(::std::os::fd::AsRawFd::as_raw_fd(&fd.as_fd()), op as _, v)
58
            })
59
        }
60
    };
61
    ($name:ident, $type_:expr, $nr:expr) => {
62
        $crate::ioctl_none!($name, $type_, $nr, 0);
63
    };
64
}
65

66
#[macro_export]
67
macro_rules! ioctl_write_val {
68
    ($name:ident, $code:expr) => {
69
        #[allow(clippy::missing_safety_doc)]
70
        pub unsafe fn $name<F: ::std::os::fd::AsFd>(
71
            fd: &F,
72
            val: ::libc::c_ulong,
73
        ) -> ::std::io::Result<libc::c_int> {
74
            let op = $code;
75
            $crate::ffi!(unsafe {
76
                ::libc::ioctl(::std::os::fd::AsRawFd::as_raw_fd(&fd.as_fd()), op as _, val)
77
            })
78
        }
79
    };
80
    ($name:ident, $code:expr, $ty:ty) => {
81
        #[allow(clippy::missing_safety_doc)]
82
        pub unsafe fn $name<F: ::std::os::fd::AsFd>(
83
            fd: &F,
84
            val: $ty,
85
        ) -> ::std::io::Result<libc::c_int> {
86
            let op = $code;
87
            $crate::ffi!(unsafe {
88
                ::libc::ioctl(::std::os::fd::AsRawFd::as_raw_fd(&fd.as_fd()), op as _, val)
89
            })
90
        }
91
    };
92
}
93

94
#[macro_export]
95
macro_rules! ioctl_write_ptr {
96
    ($name:ident, $code:expr, $ty:ty) => {
97
        #[allow(clippy::missing_safety_doc)]
98
        pub unsafe fn $name<F: ::std::os::fd::AsFd>(
99
            fd: &F,
100
            val: &$ty,
101
        ) -> ::std::io::Result<libc::c_int> {
102
            let op = $code;
103
            $crate::ffi!(unsafe {
104
                ::libc::ioctl(
105
                    ::std::os::fd::AsRawFd::as_raw_fd(&fd.as_fd()),
106
                    op as _,
107
                    val as *const $ty,
108
                )
109
            })
110
        }
111
    };
112

113
    ($name:ident, $type_:expr, $nr:expr, $ty:ty) => {
114
        #[allow(clippy::missing_safety_doc)]
115
        pub unsafe fn $name<F: ::std::os::fd::AsFd>(
116
            fd: &F,
117
            val: &$ty,
118
        ) -> ::std::io::Result<libc::c_int> {
119
            let op = $crate::sys::ioctl::ioctl_iow::<$ty>($type_, $nr);
120
            $crate::ffi!(unsafe {
121
                ::libc::ioctl(
122
                    ::std::os::fd::AsRawFd::as_raw_fd(&fd.as_fd()),
123
                    op as _,
124
                    val as *const $ty,
125
                )
126
            })
127
        }
128
    };
129
}
130

131
#[macro_export]
132
macro_rules! ioctl_write_buf {
133
    ($name:ident, $code:expr, $ty:ident) => {
134
        #[allow(clippy::missing_safety_doc)]
135
        pub unsafe fn $name<F: ::std::os::fd::AsFd, const N: usize>(
136
            fd: &F,
137
            val: &$ty<N>,
138
        ) -> ::std::io::Result<libc::c_int> {
139
            let op = $code;
140
            $crate::ffi!(unsafe {
141
                ::libc::ioctl(
142
                    ::std::os::fd::AsRawFd::as_raw_fd(&fd.as_fd()),
143
                    op as _,
144
                    val as *const $ty<N>,
145
                )
146
            })
147
        }
148
    };
149
    ($name:ident, $type_:expr, $nr:expr, $ty:ident) => {
150
        $crate::ioctl_write_buf!(
151
            $name,
152
            $crate::sys::ioctl::ioctl_iow::<$ty<0>>($type_, $nr),
153
            $ty
154
        );
155
    };
156
}
157

158
#[macro_export]
159
macro_rules! ioctl_writeread {
160
    ($name:ident, $code:expr, $ty:ty) => {
161
        #[allow(clippy::missing_safety_doc)]
162
        pub unsafe fn $name<F: ::std::os::fd::AsFd>(
163
            fd: &F,
164
            val: &mut $ty,
165
        ) -> ::std::io::Result<libc::c_int> {
166
            let op = $code;
167
            $crate::ffi!(unsafe {
168
                ::libc::ioctl(
169
                    ::std::os::fd::AsRawFd::as_raw_fd(&fd.as_fd()),
170
                    op as _,
171
                    val as *mut $ty,
172
                )
173
            })
174
        }
175
    };
176
    ($name:ident, $type_:expr, $nr:expr, $ty:ty) => {
177
        $crate::ioctl_writeread!(
178
            $name,
179
            $crate::sys::ioctl::ioctl_iowr::<$ty>($type_, $nr),
180
            $ty
181
        );
182
    };
183
    ($name:ident, $code:expr) => {
184
        #[allow(clippy::missing_safety_doc)]
185
        pub unsafe fn $name<F: ::std::os::fd::AsFd, T>(
186
            fd: &F,
187
            val: &mut T,
188
        ) -> ::std::io::Result<libc::c_int> {
189
            let op = $code;
190
            $crate::ffi!(unsafe {
191
                ::libc::ioctl(
192
                    ::std::os::fd::AsRawFd::as_raw_fd(&fd.as_fd()),
193
                    op as _,
194
                    val as *mut T,
195
                )
196
            })
197
        }
198
    };
199
}
200

201
#[macro_export]
202
macro_rules! ioctl_writeread_buf {
203
    ($name:ident, $type_:expr, $nr:expr, $ty:ident) => {
204
        #[allow(clippy::missing_safety_doc)]
205
        pub unsafe fn $name<F: ::std::os::fd::AsFd, const N: usize>(
206
            fd: &F,
207
            val: &mut $ty<N>,
208
        ) -> ::std::io::Result<libc::c_int> {
209
            let op = $crate::sys::ioctl::ioctl_iowr::<$ty<0>>($type_, $nr);
210
            $crate::ffi!(unsafe {
211
                ::libc::ioctl(
212
                    ::std::os::fd::AsRawFd::as_raw_fd(&fd.as_fd()),
213
                    op as _,
214
                    val as *mut $ty<N>,
215
                )
216
            })
217
        }
218
    };
219
}
220

221
#[macro_export]
222
macro_rules! ioctl_read {
223
    ($name:ident, $code:expr, $ty:ty) => {
224
        #[allow(clippy::missing_safety_doc)]
225
        pub unsafe fn $name<F: ::std::os::fd::AsFd>(fd: &F) -> ::std::io::Result<$ty> {
226
            let mut val = ::core::mem::MaybeUninit::<$ty>::uninit();
227
            $crate::ffi!(::libc::ioctl(
228
                ::std::os::fd::AsRawFd::as_raw_fd(&fd.as_fd()),
229
                $code as _,
230
                val.as_mut_ptr()
231
            ))?;
232
            ::std::io::Result::Ok(val.assume_init())
233
        }
234
    };
235
    ($name:ident, $type_:expr, $nr:expr, $ty:ty) => {
236
        #[allow(clippy::missing_safety_doc)]
237
        pub unsafe fn $name<F: ::std::os::fd::AsFd>(fd: &F) -> ::std::io::Result<$ty> {
238
            let mut val = ::core::mem::MaybeUninit::<$ty>::uninit();
239
            let op = $crate::sys::ioctl::ioctl_ior::<$ty>($type_, $nr);
240
            $crate::ffi!(unsafe {
241
                ::libc::ioctl(
242
                    ::std::os::fd::AsRawFd::as_raw_fd(&fd.as_fd()),
243
                    op as _,
244
                    val.as_mut_ptr(),
245
                )
246
            })?;
247
            ::std::io::Result::Ok(unsafe { val.assume_init() })
248
        }
249
    };
250
}
251

252
#[cfg(test)]
253
mod test {
254
    use crate::sys::ioctl::{ioctl_io, ioctl_ior, ioctl_iow, ioctl_iowr};
255

256
    #[test]
257
    fn test_codes() {
258
        const KVMIO: u8 = 0xAE;
259
        assert_eq!(ioctl_io(KVMIO, 0x01), 0xae01);
260
        assert_eq!(ioctl_ior::<[u8; 320]>(KVMIO, 0xcc), 0x8140aecc);
261
        assert_eq!(ioctl_iow::<[u8; 320]>(KVMIO, 0xcd), 0x4140aecd);
262
        assert_eq!(ioctl_iowr::<[u8; 8]>(KVMIO, 0x05), 0xc008ae05);
263
    }
264
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc