summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIdan Horowitz <idan.horowitz@gmail.com>2021-01-22 18:56:19 +0200
committerAndreas Kling <kling@serenityos.org>2021-04-17 10:21:23 +0200
commite4d9fa914e28a908ee575d7dabd1b4953bbc5678 (patch)
treea6a8b6e4b9675db4e3aefd9dedaa878c47102a00
parentd1f7a2f9a50f42db2be05507978046935d5eba1f (diff)
downloadserenity-e4d9fa914e28a908ee575d7dabd1b4953bbc5678.zip
Kernel: Add base support for VirtRNG (VirtIO based Hardware RNG)
This is a very basic implementation that only requests 4096 bytes of entropy from the host once, but its still high quality entropy so it should be a good fix for #4490 (boot-time entropy starvation) for virtualized environments. Co-authored-by: Sahan <sahan.h.fernando@gmail.com>
-rw-r--r--Kernel/CMakeLists.txt1
-rw-r--r--Kernel/VirtIO/VirtIO.cpp5
-rw-r--r--Kernel/VirtIO/VirtIORNG.cpp73
-rw-r--r--Kernel/VirtIO/VirtIORNG.h63
-rwxr-xr-xMeta/run.sh2
5 files changed, 144 insertions, 0 deletions
diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt
index 40481e25ee..81230a6b28 100644
--- a/Kernel/CMakeLists.txt
+++ b/Kernel/CMakeLists.txt
@@ -223,6 +223,7 @@ set(KERNEL_SOURCES
VirtIO/VirtIO.cpp
VirtIO/VirtIOConsole.cpp
VirtIO/VirtIOQueue.cpp
+ VirtIO/VirtIORNG.cpp
VM/AnonymousVMObject.cpp
VM/ContiguousVMObject.cpp
VM/InodeVMObject.cpp
diff --git a/Kernel/VirtIO/VirtIO.cpp b/Kernel/VirtIO/VirtIO.cpp
index da787a90da..f11698ebbe 100644
--- a/Kernel/VirtIO/VirtIO.cpp
+++ b/Kernel/VirtIO/VirtIO.cpp
@@ -26,6 +26,7 @@
#include <Kernel/VirtIO/VirtIO.h>
#include <Kernel/VirtIO/VirtIOConsole.h>
+#include <Kernel/VirtIO/VirtIORNG.h>
namespace Kernel {
@@ -41,6 +42,10 @@ void VirtIO::detect()
[[maybe_unused]] auto& unused = adopt(*new VirtIOConsole(address)).leak_ref();
break;
}
+ case VIRTIO_ENTROPY_PCI_DEVICE_ID: {
+ [[maybe_unused]] auto& unused = adopt(*new VirtIORNG(address)).leak_ref();
+ break;
+ }
default:
dbgln_if(VIRTIO_DEBUG, "VirtIO: Unknown VirtIO device with ID: {}", id.device_id);
break;
diff --git a/Kernel/VirtIO/VirtIORNG.cpp b/Kernel/VirtIO/VirtIORNG.cpp
new file mode 100644
index 0000000000..91c9348fa4
--- /dev/null
+++ b/Kernel/VirtIO/VirtIORNG.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2021, the SerenityOS developers.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <Kernel/VirtIO/VirtIORNG.h>
+
+namespace Kernel {
+
+VirtIORNG::VirtIORNG(PCI::Address address)
+ : CharacterDevice(10, 183)
+ , VirtIODevice(address, "VirtIORNG")
+{
+ bool success = negotiate_features([&](auto) {
+ return 0;
+ });
+ if (success) {
+ success = setup_queues(1);
+ }
+ if (success) {
+ finish_init();
+ m_entropy_buffer = MM.allocate_contiguous_kernel_region(PAGE_SIZE, "VirtIORNG", Region::Access::Read | Region::Access::Write);
+ if (m_entropy_buffer) {
+ memset(m_entropy_buffer->vaddr().as_ptr(), 0, m_entropy_buffer->size());
+ supply_buffer_and_notify(REQUESTQ, ScatterGatherList::create_from_physical(m_entropy_buffer->physical_page(0)->paddr(), m_entropy_buffer->size()), BufferType::DeviceWritable, m_entropy_buffer->vaddr().as_ptr());
+ }
+ }
+}
+
+VirtIORNG::~VirtIORNG()
+{
+}
+
+bool VirtIORNG::handle_device_config_change()
+{
+ VERIFY_NOT_REACHED(); // Device has no config
+}
+
+void VirtIORNG::handle_queue_update(u16 queue_index)
+{
+ VERIFY(queue_index == REQUESTQ);
+ size_t available_entropy = 0;
+ if (!get_queue(REQUESTQ).get_buffer(&available_entropy))
+ return;
+ dbgln_if(VIRTIO_DEBUG, "VirtIORNG: received {} bytes of entropy!", available_entropy);
+ for (auto i = 0u; i < available_entropy; i++) {
+ m_entropy_source.add_random_event(m_entropy_buffer->vaddr().as_ptr()[i]);
+ }
+ // TODO: when should we ask for more entropy from the host?
+}
+
+}
diff --git a/Kernel/VirtIO/VirtIORNG.h b/Kernel/VirtIO/VirtIORNG.h
new file mode 100644
index 0000000000..da2cd3d087
--- /dev/null
+++ b/Kernel/VirtIO/VirtIORNG.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2021, the SerenityOS developers.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <Kernel/Devices/CharacterDevice.h>
+#include <Kernel/Random.h>
+#include <Kernel/VirtIO/VirtIO.h>
+
+namespace Kernel {
+
+#define VIRTIO_ENTROPY_PCI_DEVICE_ID 0x1005
+
+#define REQUESTQ 0
+
+class VirtIORNG final : public CharacterDevice
+ , public VirtIODevice {
+public:
+ virtual const char* class_name() const override { return m_class_name.characters(); }
+
+ virtual bool can_read(const FileDescription&, size_t) const override { return false; }
+ virtual KResultOr<size_t> read(FileDescription&, u64, UserOrKernelBuffer&, size_t) override { return 0; }
+ virtual bool can_write(const FileDescription&, size_t) const override { return false; }
+ virtual KResultOr<size_t> write(FileDescription&, u64, const UserOrKernelBuffer&, size_t) override { return 0; }
+
+ virtual mode_t required_mode() const override { return 0666; }
+ virtual String device_name() const override { return "hwrng"; }
+
+ VirtIORNG(PCI::Address);
+ virtual ~VirtIORNG() override;
+
+private:
+ virtual bool handle_device_config_change() override;
+ virtual void handle_queue_update(u16 queue_index) override;
+
+ OwnPtr<Region> m_entropy_buffer;
+ EntropySource m_entropy_source;
+};
+
+}
diff --git a/Meta/run.sh b/Meta/run.sh
index 10052ec41f..26bbc54ec0 100755
--- a/Meta/run.sh
+++ b/Meta/run.sh
@@ -57,6 +57,7 @@ $SERENITY_EXTRA_QEMU_ARGS
-chardev stdio,id=stdout,mux=on
-device virtconsole,chardev=stdout
-device isa-debugcon,chardev=stdout
+-device virtio-rng-pci
-soundhw pcspk
-device sb16
"
@@ -77,6 +78,7 @@ $SERENITY_EXTRA_QEMU_ARGS
-chardev stdio,id=stdout,mux=on
-device virtconsole,chardev=stdout
-device isa-debugcon,chardev=stdout
+-device virtio-rng-pci
-soundhw pcspk
-device sb16
"