Skip to content

Commit 010343d

Browse files
author
lhw
committed
custom virtio-drivers
add rng device and virtio rng
1 parent 3206f57 commit 010343d

36 files changed

Lines changed: 939 additions & 180 deletions

File tree

Cargo.lock

Lines changed: 20 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ V9P ?= n
5959
BUS ?= mmio
6060
RISCV_BIOS ?= default
6161
GICV3 ?= n
62+
RNG ?= n
6263

6364
DISK_IMG ?= disk.img
6465
FS ?= fat32

api/ruxfeat/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ display = [
7575
"ruxruntime/display",
7676
]
7777

78+
#virtio random number generator
79+
virtio-rng = ["ruxdriver/virtio-rng","ruxruntime/rng"]
80+
7881
# 9P
7982
virtio-9p = [
8083
"9pfs",

api/ruxos_posix_api/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ poll = ["fd"]
3232
tls = ["ruxfeat/tls"]
3333
irq = ["ruxfeat/irq"]
3434
random-hw = []
35+
rng = ["ruxrand"]
36+
virtio-rng = ["driver_virtio/rng","rng"]
3537

3638
musl = ["ruxhal/musl", "ruxruntime/musl", "axalloc/slab", "ruxtask/musl"]
3739

@@ -51,6 +53,7 @@ ruxtask = { path = "../../modules/ruxtask", features = [
5153
], optional = true }
5254
ruxfs = { path = "../../modules/ruxfs", optional = true }
5355
ruxnet = { path = "../../modules/ruxnet", optional = true }
56+
ruxrand = { path = "../../modules/ruxrand", optional = true }
5457

5558
# Other crates
5659
tty = { path = "../../crates/tty" }
@@ -68,6 +71,8 @@ flatten_objects = { path = "../../crates/flatten_objects" }
6871
page_table = { path = "../../crates/page_table" }
6972
crate_interface = "0.1.1"
7073
capability = { path = "../../crates/capability" }
74+
driver_virtio = { path = "../../crates/driver_virtio" }
75+
7176

7277
cfg-if = "1.0"
7378
elf = { version = "0.7", default-features = false }

api/ruxos_posix_api/src/imp/getrandom.rs

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -118,14 +118,19 @@ pub unsafe extern "C" fn sys_srand(_seed: c_uint) {
118118
/// Returns a 32-bit unsigned random integer
119119
#[no_mangle]
120120
pub unsafe extern "C" fn sys_rand() -> c_int {
121+
#[cfg(feature = "rng")]
122+
{
123+
use ruxrand::random;
124+
return random::<c_int>();
125+
}
121126
#[cfg(feature = "random-hw")]
122127
{
123128
match has_rdrand() {
124129
true => (random_hw() >> 33) as c_int,
125130
false => rand_lcg32() as c_int,
126131
}
127132
}
128-
#[cfg(not(feature = "random-hw"))]
133+
#[cfg(not(any(feature = "random-hw", feature = "rng")))]
129134
{
130135
rand_lcg32() as c_int
131136
}
@@ -134,14 +139,19 @@ pub unsafe extern "C" fn sys_rand() -> c_int {
134139
/// Returns a 64-bit unsigned random integer
135140
#[no_mangle]
136141
pub unsafe extern "C" fn sys_random() -> c_long {
142+
#[cfg(feature = "rng")]
143+
{
144+
use ruxrand::random;
145+
return random::<c_long>();
146+
}
137147
#[cfg(feature = "random-hw")]
138148
{
139149
match has_rdrand() {
140150
true => (random_hw() >> 1) as c_long,
141151
false => random_lcg64() as c_long,
142152
}
143153
}
144-
#[cfg(not(feature = "random-hw"))]
154+
#[cfg(not(any(feature = "random-hw", feature = "rng")))]
145155
{
146156
random_lcg64() as c_long
147157
}
@@ -162,15 +172,29 @@ pub unsafe extern "C" fn sys_getrandom(buf: *mut c_void, buflen: size_t, flags:
162172
if flags != 0 {
163173
warn!("flags are not implemented yet, flags: {}, ignored", flags);
164174
}
165-
// fill the buffer 8 bytes at a time first, then fill the remaining bytes
166-
let buflen_mod = buflen % (core::mem::size_of::<i64>() / core::mem::size_of::<u8>());
167-
let buflen_div = buflen / (core::mem::size_of::<i64>() / core::mem::size_of::<u8>());
168-
for i in 0..buflen_div {
169-
*((buf as *mut u8 as *mut i64).add(i)) = sys_random() as i64;
175+
#[cfg(feature = "rng")]
176+
{
177+
use ruxrand::request_entropy;
178+
let slice: &mut [u8] =
179+
unsafe { core::slice::from_raw_parts_mut(buf as *mut u8, buflen) };
180+
request_entropy(slice).map_err(|e| {
181+
warn!("Failed to get random bytes: {:?}", e);
182+
LinuxError::EIO
183+
})?;
184+
Ok(buflen as ssize_t)
170185
}
171-
for i in 0..buflen_mod {
172-
*((buf as *mut u8).add(buflen - buflen_mod + i)) = sys_rand() as u8;
186+
#[cfg(not(feature = "rng"))]
187+
{
188+
// fill the buffer 8 bytes at a time first, then fill the remaining bytes
189+
let buflen_mod = buflen % (core::mem::size_of::<i64>() / core::mem::size_of::<u8>());
190+
let buflen_div = buflen / (core::mem::size_of::<i64>() / core::mem::size_of::<u8>());
191+
for i in 0..buflen_div {
192+
*((buf as *mut u8 as *mut i64).add(i)) = sys_random() as i64;
193+
}
194+
for i in 0..buflen_mod {
195+
*((buf as *mut u8).add(buflen - buflen_mod + i)) = sys_rand() as u8;
196+
}
197+
Ok(buflen as ssize_t)
173198
}
174-
Ok(buflen as ssize_t)
175199
})
176200
}

apps/c/random/features.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
virtio-rng

apps/c/random/main.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#define _GNU_SOURCE
2+
#include <sys/random.h>
3+
#include <stdio.h>
4+
5+
int main() {
6+
printf("Using getrandom to fetch random bytes...\n");
7+
unsigned char buf[16];
8+
ssize_t n = getrandom(buf, sizeof(buf), 0);
9+
if (n < 0) {
10+
perror("getrandom");
11+
return 1;
12+
}
13+
14+
printf("Random bytes:\n");
15+
for (int i = 0; i < n; ++i) {
16+
printf("%02x ", buf[i]);
17+
}
18+
printf("\n");
19+
20+
return 0;
21+
}

crates/driver_common/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ pub enum DeviceType {
3838
Display,
3939
/// Plan-9 device (e.g. 9pfs)
4040
_9P,
41+
/// Random number generator device.
42+
Rng,
4143
}
4244

4345
/// The error type for device operation failures.

crates/driver_rng/Cargo.toml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
[package]
2+
name = "driver_rng"
3+
version = "0.1.0"
4+
edition = "2021"
5+
authors = ["Haowen Liu <2401213328@stu.pku.edu.com>"]
6+
description = "Common traits and types for random number generator device drivers"
7+
license = "Mulan PSL v2"
8+
homepage = "https://github.com/syswonder/ruxos"
9+
repository = "https://github.com/syswonder/ruxos/tree/main/crates/driver_rng"
10+
11+
[features]
12+
default = []
13+
xoshiro= ["dep:rand_xoshiro"]
14+
15+
easy-spin = []
16+
17+
[dependencies]
18+
driver_common = { path = "../driver_common" }
19+
crate_interface = "0.1.1"
20+
rand = { version = "0.8.5", default-features = false }
21+
rand_xoshiro = { version = "0.6.0", default-features = false, optional = true }
22+
23+
spinlock = { version = "0.1.0", path = "../../crates/spinlock" }
24+
percpu = "0.2"
25+
lazy_init = { version = "0.1.0", path = "../../crates/lazy_init", default-features = false }
26+
27+
[dev-dependencies]
28+
rand = { version = "0.8.5" }

crates/driver_rng/src/lib.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/* Copyright (c) [2023] [Syswonder Community]
2+
* [Ruxos] is licensed under Mulan PSL v2.
3+
* You can use this software according to the terms and conditions of the Mulan PSL v2.
4+
* You may obtain a copy of Mulan PSL v2 at:
5+
* http://license.coscl.org.cn/MulanPSL2
6+
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
7+
* See the Mulan PSL v2 for more details.
8+
*/
9+
10+
//! Common traits and types for random number generator device drivers.
11+
12+
#![no_std]
13+
14+
#[doc(no_inline)]
15+
pub use driver_common::{BaseDriverOps, DevError, DevResult, DeviceType};
16+
use rand::{distributions::Standard, prelude::*};
17+
18+
// TODO: use xoshiro as a fake rng
19+
#[cfg(feature = "xoshiro")]
20+
pub use rand_xoshiro::Xoshiro256Plus;
21+
22+
/// The information of the graphics device.
23+
#[derive(Debug, Clone, Copy)]
24+
pub struct RngInfo {}
25+
26+
/// Operations that require a graphics device driver to implement.
27+
pub trait RngDriverOps: BaseDriverOps {
28+
/// Get the random number generator information.
29+
fn info(&self) -> RngInfo;
30+
/// Request random bytes from the device.
31+
fn request_entropy(&mut self, dst: &mut [u8]) -> DevResult<usize>;
32+
}

0 commit comments

Comments
 (0)