-
Notifications
You must be signed in to change notification settings - Fork 107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement VirtIO block device #539
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Benchmarks
Benchmark suite | Current: b2d8304 | Previous: 613cd0a | Ratio |
---|---|---|---|
Dhrystone |
1334 Average DMIPS over 10 runs |
1346 Average DMIPS over 10 runs |
1.01 |
Coremark |
964.709 Average iterations/sec over 10 runs |
972.884 Average iterations/sec over 10 runs |
1.01 |
This comment was automatically generated by workflow using github-action-benchmark.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Specify Shengwen Cheng as co-author in git commit messages. See https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors
- Consolidate GitHub Actions to automate virtio-blk test procedure.
Does it have any instructions / documentations for demonstrating or testing of this newly added feature? |
rv32emu use |
@vacantron @ChinYikMing Thank you for the insightful comments. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change the description of this pull request, adding information for others to build the system emulator and test the virtio-blk feature. This will make it easier for others to access the information without needing to refer to the README but also keep them in README :) .
Compilation warnings reported by GCC:
Simply add |
cb15ab4
to
f513ee7
Compare
@@ -118,6 +120,13 @@ static bool parse_args(int argc, char **args) | |||
opt_bootargs = optarg; | |||
emu_argc++; | |||
break; | |||
case 'x': | |||
if (!strncmp("vblk:", optarg, 5)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why must we introduce such complexity with the vblk:
prefix? The brilliant way is to use just the disk file name here and consider adding the long option for different block devices if required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why must we introduce such complexity with the
vblk:
prefix?
VirtIO features like disk, network, and sound can be dynamically enabled using the -x
option, inspired by Oracle/Sun Java virtual machine. For example: -x vblk:<disk> -x vnet:tap0 -x vsnd:alsa
. The long command options might be confusing if we want to specify more VirtIO devices, such as a secondary virtio-blk.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay. Thanks
|
||
/* virtio-blk device */ | ||
uint32_t *disk; | ||
virtio_blk_state_t *vblk; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok it seems like UART and VIRTIO_BLK come from semu, and PLIC may have a little bit different design here......
I am just thinking of wrapping these things in virtio_blk_t
, but maybe we can refactor these in other PR if required. This is not a critical issue.
8355697
to
40bca99
Compare
48536bf
to
f475a45
Compare
.ci/virtio-blk.sh
Outdated
@@ -0,0 +1,54 @@ | |||
#!/usr/bin/env bash |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you reuse the script of boot Linux instead of creating a new one? By adjusting the script to accept a CLI parameter that determines whether to test the virtio-blk feature.
.ci/virtio-blk.sh
Outdated
RUN_LINUX="build/rv32emu ${OPTS}" | ||
|
||
dd if=/dev/zero of=build/disk.img bs=4M count=32 | ||
mkfs.ext4 build/disk.img |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check the presence of mkfs.ext4
. That is, something like https://github.com/sysprog21/semu/blob/master/Makefile#L20-L32
d46348c
to
15a105c
Compare
This commit migrates @shengwen-tw's brilliant virtio implementation from semu, with the following modification: 1. Rename virtio_blk_reg_read/write to virtio_blk_read/write The original virtio_blk_read verified whether the virtio MMIO was aligned to 4. Since rv32emu does not enforce alignment checks for UART and PLIC devices or raise misalignment exceptions, this verification has been omitted. 2. Implement MMIO_VIRTIOBLK 3. Implement vblk_new() and vblk_delete() These functions align with the conventions used for UART and PLIC devices. 4. Introduce new argument '-x vblk:<disk_image>' for virtio-blk disk image Co-authored-by: Shengwen Cheng <[email protected]>
Virtio-blk verification has been integrated into boot-linux test, and is enabled by default. The p7zip-full package, providing command '7z', is added to dependencies in order to validate the success of writes to the Virtio-blk device.
ENABLE_VBLK=1 | ||
type dd >/dev/null 2>&1 || ENABLE_VBLK=0 | ||
(type mkfs.ext4 >/dev/null 2>&1 || type $(brew --prefix e2fsprogs)/sbin/mkfs.ext4) >/dev/null 2>&1 || ENABLE_VBLK=0 | ||
type 7z >/dev/null 2>&1 || ENABLE_VBLK=0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is 7z required?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe using 7z
to list files in disk.img
is the simplest and most efficient method to verify whether the file emu.txt
written by the guest OS exists.
Other approaches have limitations:
- Mounting
disk.img
requires root privileges, which may not always be feasible. - Inspecting the image with
debugfs
provides the desired result but involves navigating a complex interactive interface. dumpe2fs
fail with an error, "Wrong magic number for Ext2 Image Header while trying to open disk.img" when attempting to processdisk.img
.
case _(QueueNumMax): | ||
return VBLK_QUEUE_NUM_MAX; | ||
case _(QueueReady): | ||
return VBLK_QUEUE.ready ? 1 : 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rewrite as: return (uint32_t) VBLK_QUEUE.ready
since VBLK_QUEUE.ready
is a boolean that already evaluates to either true or false.
|
||
#define DISK_BLK_SIZE 512 | ||
|
||
#define VBLK_DEV_CNT_MAX 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, does this refer to the virtio block limit? I believe it can attach multiple virtual block devices, can't it?
#define _(reg) VIRTIO_##reg | ||
switch (addr) { | ||
case _(MagicValue): | ||
return 0x74726976; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Define these magic value to a semantic name, just like VIRTIO_VENDOR_ID
indicates the vendor ID.
case _(MagicValue): | ||
return 0x74726976; | ||
case _(Version): | ||
return 2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto.
case _(Version): | ||
return 2; | ||
case _(DeviceID): | ||
return 2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto.
case _(Status): | ||
return vblk->status; | ||
case _(ConfigGeneration): | ||
return 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto.
TIMEOUT=50 | ||
OPTS=" -k build/linux-image/Image " | ||
OPTS+=" -i build/linux-image/rootfs.cpio " | ||
OPTS+=" -b build/minimal.dtb " | ||
if [ "$ENABLE_VBLK" -eq "1" ]; then | ||
dd if=/dev/zero of=build/disk.img bs=4M count=32 | ||
mkfs.ext4 build/disk.img || $(brew --prefix e2fsprogs)/sbin/mkfs.ext4 build/disk.img |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No macOS CI is integrated yet. Is it suitable to include brew utility since we do not actually use it for now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was added based on this review. While we do not currently utilize the brew utility, its inclusion is harmless and imposes minimal runtime overhead.
@@ -16,31 +16,62 @@ function ASSERT { | |||
|
|||
cleanup | |||
|
|||
ENABLE_VBLK=1 | |||
type dd >/dev/null 2>&1 || ENABLE_VBLK=0 | |||
(type mkfs.ext4 >/dev/null 2>&1 || type $(brew --prefix e2fsprogs)/sbin/mkfs.ext4) >/dev/null 2>&1 || ENABLE_VBLK=0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto.
printf "\n[ ${COLOR_G}${MESSAGES[$ret]}${COLOR_N} ]\n" | ||
printf "\nBoot Linux Test: [ ${COLOR_G}${MESSAGES[$ret]}${COLOR_N} ]\n" | ||
if [ "$ENABLE_VBLK" -eq "1" ]; then | ||
file_list=`7z l build/disk.img` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rewrite as file_list
= $(7z l build/disk.img)
type dd >/dev/null 2>&1 || ENABLE_VBLK=0 | ||
(type mkfs.ext4 >/dev/null 2>&1 || type $(brew --prefix e2fsprogs)/sbin/mkfs.ext4) >/dev/null 2>&1 || ENABLE_VBLK=0 | ||
type 7z >/dev/null 2>&1 || ENABLE_VBLK=0 | ||
|
||
TIMEOUT=50 | ||
OPTS=" -k build/linux-image/Image " | ||
OPTS+=" -i build/linux-image/rootfs.cpio " | ||
OPTS+=" -b build/minimal.dtb " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this can be remove since -b
has been refined to be used to accept custom bootargs. Cc. @RinHizakura
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should it be removed within this pull request?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should it be removed within this pull request?
Yes, go ahead. Please also mention the rationale in the commit message.
}; | ||
|
||
struct virtq_desc { | ||
uint32_t addr; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to Virtual I/O Device (VIRTIO) Version 1.3
2.7.5 The Virtqueue Descriptor Table
struct virtq_desc {
/* Address (guest-physical). */
le64 addr;
/* Length. */
le32 len;
/* The flags as indicated above. */
le16 flags;
/* We chain unused descriptors via this, too */
le16 next;
};
We mistakenly defined virtq_desc.addr
as 32 bits.
Please consider correcting it here and submitting a pull request for semu.
This commit migrates @shengwen-tw's brilliant virtio implementation from semu, with the following modification:
Rename virtio_blk_reg_read/write to virtio_blk_read/write The original virtio_blk_read verified whether the virtio MMIO was aligned to 4. Since rv32emu does not enforce alignment checks for UART and PLIC devices or raise misalignment exceptions, this verification has been omitted.
Implement MMIO_VIRTIOBLK
Implement vblk_new() and vblk_delete()
These functions align with the conventions used for UART and PLIC devices.
Introduce new argument '-x vblk:<disk_image>' for virtio-blk disk image
This pull request has been tested on:
To try out virtio-blk:
Generate ext4 image file for virtio block device in Unix-like system:
Boot the Guest OS
Mount the virtual block device and create a test file after booting:
Reboot the system and re-mount the virtual block device, the written file should remain existing.