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

Add preliminary support for Zsn extension #79

Closed
wants to merge 1 commit into from

Conversation

daniellustig
Copy link

Zsn is a new supervisor mode extension being developed by the virtual memory task group. The goal of Zsn is to support contiguous address translation ranges of naturally-aligned power-of-two (NAPOT) sizes between the existing page sizes (4KiB, 2MiB). The specific region size we're aiming to support for now is 64KiB, but we may extend support to other power-of-two sizes in the future. Zsn is currently in draft state, with a plan to go to public review hopefully by the end of the year.

See https://github.com/riscv/virtual-memory for more info on Zsn. See https://github.com/riscv/virtual-memory/blob/main/presentations/2020-12-03-Zsn-Sail.adoc for some commentary on these Sail changes.

The Zsn part itself has not yet been tested. The virtual memory group is working on creating a suite of tests, but we don't have them ready yet. There's no urgency to merge this before we're sure it's ready, but I figured I'd still open a PR to allow for feedback on the code in the meantime. This is my first attempt to write Sail, so feedback is welcome.

@@ -29,6 +29,11 @@ bitfield PTE_Bits : pteAttribs = {
V : 0
}

bitfield PTE_Ext : extPte = {
Copy link
Collaborator

Choose a reason for hiding this comment

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

If you're making this defined by the standard then this should be a separate type (logically, part of pteAttribs, but it may be easier to have pteAttribsHi and pteAttribsLo), not extPte. extPte is for non-standard extensions to the model to use (i.e. just sail-cheri-riscv, currently), but this also needs to be done in a way that those extensions continue to be able to work (code changes are fine and may well be necessary, but there must be a way for them to hook into sail-riscv as needed without modifying sail-riscv).

Copy link
Author

Choose a reason for hiding this comment

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

Thanks for the feedback @jrtc27. Is renaming to pteAttribsHi and pteAttribsLo enough to avoid that conflict, or are you suggesting something else also needs to be done?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes and no. It means extPte is free to be defined by extensions again, but there's still the issue of changing what you can do with it; either it overlaps with some/all of pteAttribsHi and things get really weird, or you reduce it to the bits not defined by the standard and then extensions using them break. Either way there are issues for CHERI-RISC-V; the former means composing Zsn and Xcheri doesn't work (but if done correctly you should still be able to support them as mutually exclusive extensions in the model), the latter just breaks it entirely and forces us to change CheriBSD, our four/five different hardware implementations, QEMU, spike and, of course, sail-cheri-riscv, to pick different bits for the 5 bits (and researchers at Microsoft are reserving a 6th bit) we need (and then rinse and repeat as RISC-V gobbles more up in the coming years), which is manageable for a research group but extremely painful when we have downstreams at other universities and companies across the world building things on CHERI-RISC-V. There was no reserved space for non-standard extensions so we picked what we thought was most likely to remain unused (yeah, picking reserved bits not marked for that is a risk, but we had no other option), but here we are. So I don't know what the right answer is beyond being able to convince the virtual memory task group to leave those bits reserved for non-standard extensions.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Also, this was done based on the fact that riscv-privileged says "These reserved bits may also be used to facilitate research experimentation.", which is exactly what we're doing.

} else if (v & mask) == pattern then {
n + 1
} else {
napot_bits39(v, n + 1)
Copy link
Collaborator

Choose a reason for hiding this comment

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

The recursion seems unnecessarily complex. What are you actually trying to compute? Would a loop suit you better or can you do away with even that?

Copy link
Author

Choose a reason for hiding this comment

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

Please forgive my Sail naivety. This is really just "find last one" aka "count trailing zeros + 1". If there's a simpler way to write that, great.

Copy link
Collaborator

@jrtc27 jrtc27 Feb 2, 2021

Choose a reason for hiding this comment

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

There's a count_leading_zeros in the standard library (in fact it's a builtin) but seemingly no trailing ones. There's also the following commented-out version (for if it weren't a builtin):

function count_leading_zeros x = {
  foreach (i from ('N - 1) to 0 by 1 in dec)
    if [x[i]] == [bitone] then return 'N - i - 1;
  return 'N;
}

so I imagine something like the following would work:

val count_trailing_zeros : forall 'N , 'N >= 1. bits('N) -> {'n, 0 <= 'n <= 'N . atom('n)}
function count_trailing_zeros x = {
  foreach (i from 0 to ('N - 1) by 1)
    if [x[i]] == [bitone] then return i;
  return 'N;
}

Not sure what the square brackets around x[i] and bitone are for, mind, I'd expect it to work without.

Copy link
Collaborator

@allenjbaum allenjbaum Oct 1, 2021

Choose a reason for hiding this comment

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

what about count_trailing_zeroes = 'N - count_leading_zeroes(~(X^-X)). (with the correct syntax)

} else if (v & mask) == pattern then {
n + 1
} else {
napot_bits39(v, n + 1)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Wrong function? And how is the implementation of this meant to differ from the Sv48 version? Can they share a common implementation?

Copy link
Author

Choose a reason for hiding this comment

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

Oops, yes, this should be napot_bits48. Good catch.

In general almost all of the code in Sv32, Sv39, and Sv48 is redundant already. I agree it would make sense to factor out not just this new napot_bits function but also all of the rest of that common code, but I didn't want to tie that into this Zsn PR or take all of that on at one in my first attempt to write Sail, so I kept it separate for now.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah, it's just slightly more awkward with the extra level of translation (but easy enough to do), and Sv32 is rather different due to not having the upper bits in the PTEs. Merging Sv39 and Sv48 together is easy enough to do, but for Sv32 it'd probably be a case of pulling out common functionality but still having separate files, one for Sv32 and one for Sv39+48(+57).

Copy link
Author

Choose a reason for hiding this comment

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

I'm willing to give this refactoring a shot (on a separate standalone commit). We're also planning to add Sv57 soon, so it would make sense to refactor this now before duplicating the code yet again.

I do have one question though @jrtc27. Within the walkN functions, while the code is mostly the same, there are function calls like Mk_SV48_PTE(v) which are specific to the PTE type, and the Sv32, Sv39, Sv48, and Sv57 (assuming I follow the pattern) PTEs are defined as different types in riscv_vmem_common.sail, even though all but Sv32 are actually the same. If I make the function generic, I don't see an easy way to call the right Mk_SVN_PTE function for the given PTE type. I can't just factor it out from the top either because the function is called recursively.

Is there an easy way in Sail to write a function like walk in a generic way while still being able to specialize for the right Mk_SVN_PTE(v) function internally? Similar question elsewhere, e.g., for translate48 and add_to_TLB48. I couldn't figure out how to pass a function pointer as an argument, if that's even possible in Sail. Are there other ways around this? If not, perhaps that's why the code was just duplicated in the first place?

Alternatively, would it be a bad thing to at least simply merge the Sv39, Sv48, and Sv57 PTE types into common "64b PTE" types, so at least we'd get this down to 2x duplication (32b vs. 64b) instead of 4x or more?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Hello Daniel, what's the state of the refactoring you mentioned?

Copy link
Collaborator

Choose a reason for hiding this comment

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

@daniellustig I have no strong preference. It would be good to speed up merging important PRs in. I'm not sure anyone will rewrite Sail for you. There is a shortage of Sail programmers.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@daniellustig I've had some undergraduate summer interns who did a lot of Sail. They are back at university, I can ask them if they wanted to do (paid) Sail work, if you like.

Copy link
Author

Choose a reason for hiding this comment

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

Hi @martinberger, sorry for the delayed response (it was the Thanksgiving holiday here in the US). If they are interested and funding is available, then it would be great to have their help.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@daniellustig I don't know about funding, I doubt that the RISCV organisation pays this. But he is interested, I'll connect you in a PM.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Mark Himelstein is the person to talk to about that. I know there is money floating around for some things like this, but don't recall exactly what.

@allenjbaum
Copy link
Collaborator

allenjbaum commented Oct 18, 2021 via email

@jrtc27
Copy link
Collaborator

jrtc27 commented Oct 18, 2021

Yes, and we already do. There are 326 instances of // and 6157 instances of /* (a lot of which, but not all, are copyright headers) in model/. You can even see surrounding comments in this pull request.

@allenjbaum
Copy link
Collaborator

allenjbaum commented Oct 18, 2021 via email

@allenjbaum
Copy link
Collaborator

allenjbaum commented Nov 23, 2021 via email

@martinberger
Copy link
Collaborator

may have budget for this

@daniellustig @cetola @allenjbaum Did anything come out of this?

@cetola
Copy link
Member

cetola commented Dec 5, 2021

@martinberger @allenjbaum We’re looking into internship possibilities, and also have a job req out for a full time Sail developer.

@daniellustig
Copy link
Author

Closing this PR for now. If we can find someone who can properly implement Svnapot in the Sail model, they can either reopen this PR and continue working on it, or they can redo it from scratch, as they prefer.

@martinberger
Copy link
Collaborator

Thanks @daniellustig I hope we'll the see new version soon.

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.

None yet

6 participants