Skip to content
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

Moves specification-required checks to setters #112

Merged
merged 3 commits into from
Nov 3, 2021

Conversation

germag
Copy link
Contributor

@germag germag commented Nov 1, 2021

Moves specification-required checks to setters

Moves the mandatory checks, according to the virtio specification,
from Queue::is_valid() to the corresponding Queue setters.
closes: #94

Signed-off-by: German Maglione [email protected]

{
if device.check_device_status(status::FEATURES_OK, status::DRIVER_OK | status::FAILED) {
if let Some(queue) = device.selected_queue_mut() {
f(queue);
if let Err(e) = f(queue) {
device.set_device_status(status::FAILED);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the experiments that I did last week, setting the device status to FAILED doesn't seem to actually make a difference. Sorry for not coming with a response on the issue, but I had a chat only today with @andreeaflorescu and @alexandruag to decide on the path forward here, and we were thinking to keep the setter proposal, but in case of a misconfiguration to set the value of that field to a default. This seems to be how qemu handles this issue as well. So for the queue size, we would keep the max size if the value is invalid, and for the descriptor table address and the others, we would use address 0. What do you think?
I think with this approach, we could get rid of the actual_size() method as well, but I'll double-check.

fn actual_size(&self) -> u16 {
min(self.size, self.max_size)
}
fn set_size(&mut self, size: u16) -> Result<(), Error> {
Copy link
Contributor

@lauralt lauralt Nov 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for not being explicit enough in my previous comment :(. The way we were thinking to address the issue is to not return an error anymore in case of a misconfiguration, and just ignore the value and log an error, something like:

    fn set_size(&mut self, size: u16) {
        if size > self.max_size() || size == 0 || (size & (size - 1)) != 0 {
            error!("virtio queue with invalid size: {}", size);
            return;
        }
        self.size = size;
    }

It's not necessary to explicitly set the value to the default one, because the Queue constructor is already initializing the size and addresses to the default ones. I would though define constants for the default addresses like you already did here, but one for each queue part:
const DEFAULT_DESC_TABLE_ADDR: u64 = 0x0;
const DEFAULT_AVAIL_RING_ADDR: u64 = 0x0;
...

With this approach, we won't need to define other errors, and the logic here won't be needed anymore.

We should also update the negative tests for these setters, i.e. try to set an invalid value, and check that the value of size/addr remains the default one.

Moves the mandatory checks, according to the virtio specification,
from Queue::is_valid() to the corresponding Queue setters.
closes: rust-vmm#94

Signed-off-by: German Maglione <[email protected]>
Remove actual_size() since Queue::set_size() checks that the
size cannot be greater than max_size.

Signed-off-by: German Maglione <[email protected]>
Copy link
Contributor

@lauralt lauralt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Thanks and sorry for the back and forth.

@@ -251,8 +251,9 @@ pub(crate) mod tests {

impl Dummy {
pub fn new(device_type: u32, features: u64, config_space: Vec<u8>) -> Self {
let mem =
Arc::new(GuestMemoryMmap::from_ranges(&[(GuestAddress(0), 0x1000_0000)]).unwrap());
let mem = Arc::new(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this change needed?

@germag
Copy link
Contributor Author

germag commented Nov 3, 2021

Looks good! Thanks and sorry for the back and forth.

No problem, I'm still learning, so thanks for your patience :)

@lauralt lauralt merged commit 2d05498 into rust-vmm:main Nov 3, 2021
@germag germag deleted the issue_94 branch November 3, 2021 16:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

move checks from Queue::is_valid to setters
3 participants