Skip to content

Conversation

priyasiddharth
Copy link
Contributor

Summary of the PR

This PR adds new Kani proofs for virtio queue mainly around notification logic.

Requirements

Before submitting your PR, please make sure you addressed the following
requirements:

  • All commits in this PR have Signed-Off-By trailers (with
    git commit -s), and the commit message has max 60 characters for the
    summary and max 75 characters for each description line.
  • All added/changed functionality has a corresponding unit/integration
    test.
  • All added/changed public-facing functionality has entries in the "Upcoming
    Release" section of CHANGELOG.md (if no such section exists, please create one).
  • Any newly added unsafe code is properly documented.

This simplifies the logic for the existing need_notification proof
and makes it more general accounting for both when notification is
needed and when it is not.

Signed-off-by: Siddharth Priya <[email protected]>
1. Verify enable_notification logic
2. Verify when driver should send notification to device
3. Verify when driver should not send notification to device
4. Verify that set_next_used method actually changes the next_used field in memory

Signed-off-by: Siddharth Priya <[email protected]>
@priyasiddharth
Copy link
Contributor Author

@MatiasVara FYI

@epilys epilys changed the title virtio-queue: kani proofs for vritio queue virtio-queue: kani proofs for virtio queue Sep 15, 2025
let ProofContext { mut queue, memory } = kani::any();
let result = queue.set_notification(&memory, false /* disable notification */);
if !queue.event_idx_enabled {
// Check for Sec 2.7.10
Copy link
Member

Choose a reason for hiding this comment

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

Sec, should be Spec right?

Also the test doc talks about Specification (VirtIO 1.3, Section 2.7.7: "Used Buffer Notification Suppression") what 2.7.10 is? Is related to virtio 1.3?

Please be more verbose with that references.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think here you could add that Section 2.7.10 of the Virtio spec explains how the device can indicates to the driver that notifications are not required when adding buffers into the avail right.

}
}

/// # Specification (VirtIO 1.3, Section 2.7.7.2: "Device Requirements: Used Buffer Notification Suppression")
Copy link
Member

Choose a reason for hiding this comment

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

The commit 4a8b048 description is not really clear to me.

It seems now this function don't test only the suppression, so should we update this documentation?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the proof is testing both w/wo suppression. I think the comment should only mention about the notification.

mem: &M,
order: Ordering,
) -> Result<u16, Error> {
// This can not overflow an u64 since it is working with relatively small numbers compar
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// This can not overflow an u64 since it is working with relatively small numbers compar
// This can not overflow an u64 since it is working with relatively small numbers compared

// - true, if there are pending entries in the `idx` field of the
// avail ring
// - false, if there are no pending entries in the `idx` field of the
// avail ring The check for pending entries is done by comparing the
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// avail ring The check for pending entries is done by comparing the
// avail ring. The check for pending entries is done by comparing the

mem.load::<u16>(queue.used_ring, order)
.map(u16::from_le)
.map_err(Error::GuestMemory)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
}
}

#[kani::unwind(0)]
fn verify_set_notification_false() {
let ProofContext { mut queue, memory } = kani::any();
let result = queue.set_notification(&memory, false /* disable notification */);
Copy link
Contributor

@MatiasVara MatiasVara Sep 24, 2025

Choose a reason for hiding this comment

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

Can't we use kany::any to cover the potential values of the second parameter of set_notification()? This would prevent having two proofs.

/// This proof checks that:
/// - If there are pending entries in the avail ring (avail_idx != next_avail),
/// `enable_notification` returns true.
/// - If there are no pending entries (avail_idx == next_avail), it returns false.
Copy link
Contributor

@MatiasVara MatiasVara Sep 24, 2025

Choose a reason for hiding this comment

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

I think VirtIO 1.3, Section 2.7.6.1 states that avail_idx is always >= than next_avail. Although, it is correct that enable_notification() checks only if they are different.

@MatiasVara
Copy link
Contributor

In overall, LGTM! but I think you have to improve the commit msgs first. For example in 4a8b048, I would explain exactly how this commit handles more. Similarly in 24dc553, I would state in the commit msg what is the expected result of the method for what we are adding the proof.

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.

3 participants