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

[DRAFT] Support MMIO regions #1328

Closed
wants to merge 4 commits into from
Closed

Conversation

danielsn
Copy link
Contributor

@danielsn danielsn commented Jul 1, 2022

Description of changes:

Adds support for MMIO regions to kani proof harnesses.

Resolved issues:

Resolves #1304

Call-outs:

  • This is dependent on New option --mmio-regions to specify memory regions diffblue/cbmc#6747. It will not work until that is released. I tested against a locally built copy.
  • We need documentation for this feature
  • Should probably add some negative tests too
  • Should test that it behaves like MMIO: writes don't need to be the same as is read back, two reads can get different values

Testing:

  • How is this change tested? New regression tests.

  • Is this a refactor change? No

Checklist

  • Each commit message has a non-empty body, explaining why the change was made
  • Methods or procedures are documented
  • Regression or unit tests are included, or existing tests cover the modified code
  • My PR is restricted to a single feature or bugfix

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.

@kroening
Copy link

kroening commented Jul 1, 2022

Why not simply have --mmio_region enabled by default?

@kroening
Copy link

kroening commented Jul 1, 2022

Why not simply have --mmio_region enabled by default?

(Ignore, it is already)

Comment on lines +60 to +61
assert_eq!(*p2, val1);
assert_eq!(*p1, val2);
Copy link

@zpzigi754 zpzigi754 Jul 3, 2022

Choose a reason for hiding this comment

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

I guess that these should be changed like

assert_ne!(*p2, val1); 
assert_ne!(*p1, val2);

pub fn mmio_region(attr: TokenStream, item: TokenStream) -> TokenStream {
let mut result = TokenStream::new();

// Translate #[kani::unwind(arg)] to #[kanitool::unwind(arg)]
Copy link
Contributor

Choose a reason for hiding this comment

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

Update comment


/// Set Loop unwind limit for proof harnesses
/// The attribute '#[kani::unwind(arg)]' can only be called alongside '#[kani::proof]'.
/// arg - Takes in a integer value (u32) that represents the unwind value for the harness.
Copy link
Contributor

Choose a reason for hiding this comment

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

Update comment

Copy link
Contributor

@celinval celinval left a comment

Choose a reason for hiding this comment

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

The semantics here aren't clear to me. Your test_read_is_stable contradicts the item in the callout:

Should test that it behaves like MMIO: writes don't need to be the same as is read back, two reads can get different values.

// If we didn't successfully process, give an error message
self.tcx
.sess
.span_err(attr.span, "Expected exactly two integers are the argument to 'mmio_region'");
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you print or at least log which values we got?

@@ -16,4 +16,6 @@ pub struct HarnessMetadata {
pub original_line: String,
/// Optional data to store unwind value
pub unwind_value: Option<u32>,
/// Optional MMIO regions
pub mmio_regions: Vec<(u128, u128)>,
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we use usize instead?

@@ -0,0 +1,26 @@
Status: SUCCESS\
Description: "offset: attempt to compute number in bytes which would overflow"
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems irrelevant for your test. I would just remove it.

//BUFFER+2 is not in the MMIO region. Expect pointer check failures.
*(BUFFER.offset(2)) = val;
//BUFFER2 is not in the MMIO region. Expect pointer check failures.
*BUFFER2 = val;
Copy link
Contributor

Choose a reason for hiding this comment

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

You are not really checking that both fail though. This test will succeed if only one of these fail. You can either add the line in the file to the expected file or break this into two harness and add the function name. I prefer the second since it is always painful to maintain LoC up to date.

#[cfg(kani)]
#[kani::proof]
#[kani::mmio_region(0x8000, 8)]
fn test_write() {
Copy link
Contributor

Choose a reason for hiding this comment

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

can you rename this to check_invalid_write() or something like that?

}
}

//TODO Weirdly, these fail even tho the other tests pass???
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks like a blocker to me. Maybe we should investigate this behavior a bit better.

#[kani::proof]
#[kani::mmio_region(0x8000, 4)]
fn test_read_after_write_doesnt_havoc() {
let val = 12;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you use any instead?

@@ -0,0 +1,63 @@
// Copyright Kani Contributors
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you please document what these tests are testing?

@@ -0,0 +1,39 @@
// Copyright Kani Contributors
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you cover 0 sized operations?

#[cfg(kani)]
#[kani::proof]
#[kani::mmio_region(0x8000, 4)]
fn test_read_is_stable() {
Copy link
Contributor

Choose a reason for hiding this comment

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

But should it be stable?

@celinval
Copy link
Contributor

@danielsn any news here?

@danielsn danielsn closed this Jan 23, 2023
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.

How to verify mmio access?
5 participants