Skip to content

Conversation

@pmundkur
Copy link
Collaborator

@pmundkur pmundkur commented Feb 7, 2026

Check misa for enabled privilege modes at xret, since modifications to misa might have disabled the privileges in mstatus.{MPP, SPP}. Add a test for this case.

This leaves handling of misa.U == 0 for later, to be addressed with the other misa bits.

While here, use an assert in place of an internal error as it should have been caught by config validation.

Fixes #1522.

@pmundkur
Copy link
Collaborator Author

pmundkur commented Feb 7, 2026

cc @nwf

@github-actions
Copy link

github-actions bot commented Feb 7, 2026

Test Results

2 328 tests  +2   2 328 ✅ +2   30m 51s ⏱️ +6s
    1 suites ±0       0 💤 ±0 
    1 files   ±0       0 ❌ ±0 

Results for commit 2296ef0. ± Comparison against base commit a1c397e.

private function legalize_xret_privilege(p : Privilege) -> Privilege =
match p {
Machine => Machine,
// If S-mode is not legal, then go to M-mode.
Copy link
Collaborator Author

@pmundkur pmundkur Feb 7, 2026

Choose a reason for hiding this comment

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

I'm not sure about this. The spec says:

When executing an xRET instruction, supposing xPP holds the value y, xIE is set to xPIE; the privilege mode is changed to y;

If x is M, y is S and misa.S is clear (and assuming misa.S == 0 implies S is not supported), and U is supported, should privilege mode be changed to M or U?

Copy link
Collaborator

Choose a reason for hiding this comment

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

mstatus.MPP is WARL, so based on the CSR Field Modulation rules, this is implementation specific. Presumably that means we need a config option for it.

If a write to one CSR changes the set of legal values allowed for a field of a second CSR, then unless specified otherwise, the second CSR’s field immediately gets an UNSPECIFIED value from among its new legal values. This is true even if the field’s value before the write remains legal after the write; the value of the field may be changed in consequence of the write to the controlling CSR.

Copy link
Collaborator

@Timmmm Timmmm left a comment

Choose a reason for hiding this comment

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

I think this probably isn't the right way to handle this. The thing that we don't actually do is the CSR field modulation of mstatus.MPP:

xPP fields are WARL fields that can hold only privilege mode x and any implemented privilege mode lower than x. If privilege mode x is not implemented, then xPP must be read-only 0.

So it's not really that we're legalising the xret privilege, instead we should be modulating the xPP field so that it dynamically reads a legal value (or 0 if there are none).

As a concrete example of where this fix would still be broken, if you set MPP to S, write misa.S=0, and then read mstatus using csrr you will still read S.

I think unfortunately we need to add a read_mstatus function like we did for something else recently that I can't remember. :-D

The other option is to actually modify mstatus.xPP when misa[S/U] are modified. That is also legal behaviour (so in theory we might want to support it), however it also is a let less elegant and difficult to do in a bug-free way, so I don't think we should - until someone really wants it at least.

mstatus[SPP] = 0b0;
cur_privilege = legalize_xret_privilege(if mstatus[SPP] == 0b1 then Supervisor else User);
// "xPP is set to the least-privileged supported mode (U if U-mode is implemented, else M)."
mstatus[SPP] = if currentlyEnabled(Ext_U) then 0b0 else 0b1;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Probably should use the same style as line 268.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Also... seems very weird that you could execute sret on an M-only machine but I couldn't see anything disallowing it at a quick glance.

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.

One can still mret to U mode with misa.U disabled

3 participants