dev: Make VirtIORng device use gem5's rng instead of C++'s

Currently, VirtIORng uses C++'s RNG. This causes nondeterminism
across simulations using this device. One example is the example RISC-V
board booting Ubuntu,

configs/example/gem5_library/riscv-ubuntu-run.py

JIRA: https://gem5.atlassian.net/browse/GEM5-1193

Change-Id: I299e72eb891819007b4260390f5c2ba94d2dec7b
Signed-off-by: Hoa Nguyen <hoanguyen@ucdavis.edu>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/56889
Maintainer: Bobby Bruce <bbruce@ucdavis.edu>
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Hoa Nguyen
2022-02-16 15:59:08 -08:00
parent b4ba4916dd
commit 52485bbc38
3 changed files with 7 additions and 36 deletions

View File

@@ -38,9 +38,7 @@
#include "dev/virtio/rng.hh"
#include <fcntl.h>
#include <unistd.h>
#include "base/random.hh"
#include "debug/VIORng.hh"
#include "params/VirtIORng.hh"
#include "sim/system.hh"
@@ -50,8 +48,7 @@ namespace gem5
VirtIORng::VirtIORng(const Params &params)
: VirtIODeviceBase(params, ID_RNG, 0, 0),
qReq(params.system->physProxy, byteOrder, params.qSize,
params.entropy_source, *this)
qReq(params.system->physProxy, byteOrder, params.qSize, *this)
{
registerQueue(qReq);
}
@@ -60,16 +57,10 @@ VirtIORng::~VirtIORng()
{
}
VirtIORng::RngQueue::RngQueue(PortProxy &proxy, ByteOrder bo,
uint16_t size, const std::string &rng_file_path,
VirtIORng::RngQueue::RngQueue(PortProxy &proxy, ByteOrder bo, uint16_t size,
VirtIORng &_parent)
: VirtQueue(proxy, bo, size), parent(_parent), dist(0,255)
: VirtQueue(proxy, bo, size), parent(_parent)
{
rng_fd = open(rng_file_path.c_str(), O_RDONLY);
if (rng_fd < 0) {
DPRINTF(VIORng, "error when open entropy source: %s\n",
rng_file_path.c_str());
}
}
void
@@ -89,16 +80,7 @@ VirtIORng::RngQueue::trySend()
DPRINTF(VIORng, "Got descriptor (len: %i)\n", d->size());
size_t len = 0;
while (len < d->size()) {
uint8_t byte = 0;
bool rng_read_success = false;
if (rng_fd >= 0) {
ssize_t result = read(rng_fd, &byte, sizeof(uint8_t));
rng_read_success = (result > 0);
}
if (!rng_read_success) {
// fallback to C++ std rng generator
byte = dist(rd_device);
}
uint8_t byte = gem5::random_mt.random<uint8_t>();
d->chainWrite(len, &byte, sizeof(uint8_t));
++len;
}