Skip to content

Conversation

@KotorinMinami
Copy link
Contributor

Added an implementation for #787, but I was wondering how to implement this TODO in the comment

// TODO: This is incorrect since CHERI only requires at least one byte
// to be in bounds here, whereas ext_data_get_addr() checks that all bytes
// are in bounds. We will need to add a new function, parameter or access type.

@github-actions
Copy link

github-actions bot commented Mar 14, 2025

Test Results

2 101 tests  ±0   2 101 ✅ ±0   15m 55s ⏱️ +3s
    1 suites ±0       0 💤 ±0 
    1 files   ±0       0 ❌ ±0 

Results for commit 3851ce1. ± Comparison against base commit 296f8cd.

♻️ This comment has been updated with latest results.

@Timmmm
Copy link
Collaborator

Timmmm commented Mar 17, 2025

I'm getting pretty close to pushing our latest code (just trying to get it to build) so give me a couple of days and then I can point you at it.

@Timmmm
Copy link
Collaborator

Timmmm commented Mar 28, 2025

Here's how we are doing it for CBOs:

https://github.com/CHERI-Alliance/sail-riscv/blob/de9279755a2fbce96314083bff884f21e6937992/model/riscv_insts_zicboz.sail#L34

https://github.com/CHERI-Alliance/sail-riscv/blob/de9279755a2fbce96314083bff884f21e6937992/model/riscv_insts_zicbom.sail#L48-L53

Basically you just have to make sure to pass in the correct access type, and for cbom it is based on the original access type rather than the modified one.

@tomaird that bit isn't super clear in the CHERI spec. Do you know where it came from?

@tomaird
Copy link

tomaird commented Mar 28, 2025

Not sure I understand which bit isn't clear so I'll just explain the full rationale behind all this code...

The CHERI spec describes the following checks for the CBO instructions (amongst others):

CBO   | Bounds    | Permissions
--------------------------------
CLEAN | Any byte  | W+R
FLUSH | Any byte  | W+R
INVAL | Any byte  | W+R+ASR
ZERO  | All bytes | W

So for the bounds check, CLEAN/FLUSH/INVAL all behave the same - it only needs a single byte to be in bounds.

But for the permissions checks it's a bit different, with CBO.INVAL requiring more permissions than the others.

The RISC-V spec describes that CBO.INVAL can also do a flush depending on xenvcfg.cbie, which in the model we treat as executing a CBO.FLUSH. But from the table above you can see that CBO.FLUSH has a looser permissions requirement than CBO.INVAL, so we need to make sure we do the permissions check based on what instruction actually executed, i.e. the CBO.INVAL, rather than what we're effectively executing in the model. Hence the need to pass in the "original" access type.

Does that answer your question?

@Timmmm
Copy link
Collaborator

Timmmm commented Mar 28, 2025

Yeah I think my question is do you definitely still need ASR permission if INVAL executes as FLUSH. My understanding was that INVAL needs the extra permission because it's "unsafe" - you can resurrect capabilities that should have died. But if it's actually doing a FLUSH then it's safe.

Although now that I check the spec again it does actually explicitly mention this:

The CBIE bit in menvcfg and senvcfg indicates whether CBO.INVAL performs cache block flushes instead of invalidations for less privileged modes. The instruction checks shown in the table below remain unchanged regardless of the value of CBIE and the privilege mode.

@jrtc27
Copy link
Collaborator

jrtc27 commented May 14, 2025

Not sure I understand which bit isn't clear so I'll just explain the full rationale behind all this code...

The CHERI spec describes the following checks for the CBO instructions (amongst others):

CBO   | Bounds    | Permissions
--------------------------------
CLEAN | Any byte  | W+R
FLUSH | Any byte  | W+R
INVAL | Any byte  | W+R+ASR

This should be "All bytes":

ifdef::cbo_inval[]
| Permission violation | It does not grant <<w_perm>>, <<r_perm>> or <<asr_perm>>
| Length violation | At least one byte accessed is outside the bounds
endif::[]

@tomaird
Copy link

tomaird commented May 15, 2025

@jrtc27 where are you quoting that bit of spec from? On latest main of the CHERI spec has cbo.inval only requiring any byte to be in bounds:

| Bounds violation      | None of the bytes accessed are within the bounds, or the capability has <<section_cap_malformed,malformed>> bounds

https://github.com/riscv/riscv-cheri/blob/main/src/cheri/insns/cbo_exceptions.adoc?plain=1#L23

@jrtc27
Copy link
Collaborator

jrtc27 commented May 15, 2025

@jrtc27 where are you quoting that bit of spec from? On latest main of the CHERI spec has cbo.inval only requiring any byte to be in bounds:

| Bounds violation      | None of the bytes accessed are within the bounds, or the capability has <<section_cap_malformed,malformed>> bounds

https://github.com/riscv/riscv-cheri/blob/main/src/cheri/insns/cbo_exceptions.adoc?plain=1#L23

I guess I still had an old version open somehow. But this is very wrong. See riscv/riscv-cheri#221 (comment) :(

@Timmmm
Copy link
Collaborator

Timmmm commented Jun 30, 2025

It would be good to get this in - do you mind if I just update it to remove ExecutableDataFetch? Or do you think we should keep it even though it isn't used yet?

@KotorinMinami
Copy link
Contributor Author

Okay, I'll remove it.

@Timmmm Timmmm self-assigned this Aug 20, 2025
@Timmmm Timmmm force-pushed the extend_access_type branch from ac78c42 to 3851ce1 Compare August 28, 2025 21:36
@Timmmm
Copy link
Collaborator

Timmmm commented Aug 28, 2025

Hey, I rebased this and changed it to use the AMO PMA level in the AMO access type instead of the full AMO op since a) that's all we really need to know, and b) we don't have access to that type in riscv_types.sail any more. I maybe could have moved the types around to fix that but this seemed better.

Also I think we probably want to go the full way and remove all the aq/rel/res/con bools before merging this, otherwise it's just weird having both things. I'll have a go at that at some point.

@KotorinMinami
Copy link
Contributor Author

Thanks for the rebase @Timmmm . I'm also considering how to proceed. Perhaps we should first open an issue to document the removal of the aq/rel/res/con boolean parameters.

@Timmmm
Copy link
Collaborator

Timmmm commented Aug 30, 2025

I don't think we need to document anything, we just need to remove those parameters and instead source them from the access type. I did start working on this, it doesn't look too bad. The only minor issue I ran into is that a couple of functions have the bool flags but not the access type, but we can just add that.

@jordancarlin
Copy link
Collaborator

@KotorinMinami @Timmmm This would be great to get in soon as it is blocking #328 (which was recently ratified and would be good to get merged). Are either of you able to rebase and finish this (after the holidays)?

@Timmmm
Copy link
Collaborator

Timmmm commented Dec 28, 2025

Yeah maybe we could take a look at each of our approaches in the next meeting and see which one is best (I haven't actually looked yet).

@jordancarlin jordancarlin added the tgmm-agenda Tagged for the next Golden Model meeting agenda. label Dec 28, 2025
Copy link
Collaborator

@pmundkur pmundkur left a comment

Choose a reason for hiding this comment

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

Notes from comparing this to #1405. Sorry, I should have checked this before.

width <= xlen_bytes | (op == AMOCAS & width <= xlen_bytes * 2 & rs2[0] == bitzero & rd[0] == bitzero)
))

function amo_level(op : amoop, width : word_width_wide) -> AmoLevel =
Copy link
Collaborator

Choose a reason for hiding this comment

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

AMO width handling is not handled in #1405. In that PR, pmaCheck gets a more informative access, but doesn't do anything with it. I think that's best left to a subsequent PR, which would also handle the width of cache block accesses.

*/
let data = X(rs2)[width * 8 - 1 .. 0];
match vmem_write(rs1, zeros(), width, data, Write(Data), aq & rl, rl, true) {
match vmem_write(rs1, zeros(), width, data, StoreConditional(aq, rl, Data), aq & rl, rl, true) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

It's not clear whether to use StoreConditional(aq, rl,..) here or StoreConditional(aq & rl, rl, ...) as per the original code. This is why I did not fold in these flags in #1405. It's probably better to have litmus tests running first to ensure we don't break things in the refactor.

enum CacheAccessType = {
CleanFlush,
Inval,
Zero,
Copy link
Collaborator

Choose a reason for hiding this comment

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

We've since added prefetch from Zicbop as well.

Cache(_) => false,
});
// Update 'accessed'-bit?
let update_a = (pte_flags[A] == 0b0);
Copy link
Collaborator

Choose a reason for hiding this comment

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

This needs to be updated: "During address translation, the [cache-block management] instruction also checks the accessed bit and may either raise an exception or set the bit as required." Similarly for cache-block zero.

AMOAccess(_, _, _, _, _) => true,
LoadReserved(_, _, _) => false,
StoreConditional(_, _, _) => true,
Cache(_) => false,
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is incorrect: "During address translation, the [cache-block zero] instruction also checks the accessed and dirty bits and may either raise an exception or set the bits as required."

Read(_) => "R",
Write(_) => "W",
ReadWrite(_, _) => "RW",
AMOAccess(_) => "A",
Copy link
Collaborator

Choose a reason for hiding this comment

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

I left this as "RW" in #1405. Is "A" preferable?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Until we have other trace/logging formats, I would avoid changing what is printed in the log. It is currently the only way of parsing the output of the model, so switching from RW to A would likely break many tools. Once we have new machine-readable formats available, we can intentionally break the human-readable log, and then I think switching to A/LR/SC is worth considering.

Comment on lines +48 to +49
LoadReserved(_) => "LR",
StoreConditional(_) => "SC",
Copy link
Collaborator

Choose a reason for hiding this comment

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

I left these as "R" and "W", perhaps "LR" and "SC" are more informative?

@pmundkur
Copy link
Collaborator

Should we close this, now that #1405 is merged?

@Timmmm Timmmm closed this Jan 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tgmm-agenda Tagged for the next Golden Model meeting agenda.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants