masking of CSR bits/fields - transnational logic? will locking suffice?


David Horner
 

On 2021-11-17 10:00 p.m., Vedvyas Shanbhogue wrote:
On Wed, Nov 17, 2021 at 05:02:12PM -0800, John Hauser wrote:
Allen Baum wrote:
What follows is my interpretation of what I think is happening; it is not
necessarily "truth".
IF I didn't interpret this correctly, it means that John is going to have
to write a long correction.....sorry.

That mapping function takes the field value, and some other controlling
field value, and converts it to a legal value.
That mapping function output is what is presented to hardware, which is
what performs its intended function, and what is read by a
CSRRD instruction.
If it is readonly, then I *think* the output is only a function of the
controlling field value (I'd like to see some examples to understand what
he had in mind for the read-only behavior)
Writing the field then appears to leave it unchanged, but the underlying
state is actually changing; the mapping function ignores those state bits
because the mapping isn't dependent on them.
Changing the controlling field back to its original state would make the
last written value appear [...]
Yes, you have it correct, Allen, although my text only addressed
writable-versus-read-only and not the possibility that the set of valid
values might change due to another CSR.

Some of the RISC-V heavyweights discussed this topic amongst
themselves, off the mailing list, and concluded that they'd prefer a
different approach, which I'll share with everyone for your input.
This isn't necessarily the final wording (you all might contribute to
that), but the gist is this:

   Unless specified otherwise, if a write to one CSR changes the set
   of valid (legal) values allowed for a second CSR or a subfield,
   then the second CSR or subfield immediately gets an unspecified
   value among the set of valid values it's allowed to have.

Note that when a CSR's contents or subfield is read-only, its set of
possible valid values has only one member (or at least only one at any
given time).  So, by the rule stated above, if a write to the first
CSR causes the second CSR or subfield to become read-only, then it
immediately gets the required read-only value, which is the only value
it's allowed to have.  On the other hand, if a write to the controlling
CSR changes the second CSR or subfield back to being writable
(multiple values are now allowed), it may suddenly take on any valid
value allowed to it; exaclty which value it gets is unspecified.  An
important point is that this change to the value of the second CSR or
subfield may occur _even if its old value would still have been valid_
both before and after the write to the controlling CSR.
Maybe a good definition of read-only would help since earlier you agreed to Allen but that text did not address the concept of read-only field holding on to written data instead of discarding the write. This behavior is quite unlike every other definition of read-only that I have come across.

About the act of making a field writeable causing the field to assume any legal value I think this may be extremely hard for software to comprehend.
This is the crux of the matter.

Can the user understand what the out come will be? Does it match what the user wants it to be?

Not all of these examples are this situation, but the most difficult to understand what behaviour to expect occurs when there are transient invalid states.

The worst case is when a user wants an end state and there is no legal way [or at least non-distruptive during the transition steps] to get there.

We are thus in the realm of transactional logic.

It appears that this is what the output masking intends to provide.

The ideal would be BEGIN multiple update, check validity [read uncommitted], ROLLBACK or COMMIT.

Perhaps it would be instructional to consider this flexibility first.

Then look to see if LOCK (retain initial state), multiple update, check validity [read uncommitted], [reverse updates], UNLOCK is sufficient to provide management over the transition.

Certainly persistence of underlying state over extended operation [like alignment for transition out of and into C support] can be useful, but it can be emulated if software has transactional support.

Indeed with "transactional" support, it may be sufficient for software to read preliminary state and reestablish as needed.


The hardware designs obligations then are to not provide sufficient rope for the OS/VM/etc to hang itself.

Especially, not to activate any feature that the software is not prepared to support, that therefore the software does not explicitly enable.

An implementation may have a deterministic answer but if different implementations have different answer then software has to be prepared for each possible outcome.
To take it to an extreme, consider a hypothetical second CSR that makes the satp CSR read-only. If the act of writing the second CSR to make satp writeable changes the mode to NONE that would be an extremely challenging outcoming the software will need to be prepared to deal with.

Why was the choice not to leave the CSR with the legal value it has and not allow suddenly taking on any of the possible values.

Compared to the first proposal, this one swings in the opposite
direction toward maximal freedom for the implementation.  So how does
everyone feel about this alternate proposal?  If I didn't explain it
well enough above and there are questions about what exactly the new
proposed rule is, I'll be happy to attempt to clarify.


   - John Hauser







Allen Baum
 

I'm going to shortcut this discussion a bit to make sure we're not inventing new problems.
(for a very large definition of shortcut. This post isn't short....)

I've never seen a list of all the cases where there is a modifier bit that controls some other CSR field.
The obvious (to me) ones are: 
   clearing MISA bits turning off extensions; this generally removes CSRs entirely, it doesn't make them readonly.
   setting SATP.mode which effects low order xTVEC bits (I think I have that right)
   setting mseccfg bits may affect other CSRs, but in many cases those are write1-to-set, and the transactional nature is clear and deliberate.
This is clearly not a comprehensive list, but it would be good to see one for several reasons
The relevant one here is to avoid having us solve problems that don't exist.
 I don't know how easy it is to extract this information from Sail, but riscv-config has a syntax to describe that, along with its illegal->legal syntax.
It doesn't necessarily comprehend new extensions yet.

So, before we go off on this tangent, we should understand the scope of this "problem"

Also, John said:
>> Compared to the first proposal, this one swings in the opposite direction toward maximal freedom for the implementation.  
>> So how does everyone feel about this alternate proposal?

It was probably clear from my extensive screed, I'm not, which is ironic.
As a hardware architect, I love the idea of maximal freedom.
As chair of the arch-test SIG - not so much.
There is a distinction to me between 
 - an abstract freedom of implementation, and 
 - a speced   freedom of implementation that causes code to produce different results.

I think that distinction has not been emphasized enough.
 It doesn't just complicate my life as SIG chair, but software ecosystem and platform/profile definitions as well, and is an opening wedge into fragmentation.

And it often just isn't necessary. 
There are explicit cases where it is (e.g. the results of memory accesses with and without fences) 
where the spec is clear that if you want consistent results you must use fences, akak "if it hurts when you do that, don't do that"
That's an easy case;  the reasoning and costs are clear (you could build a system that gave consistent results 
   and doesn't need fences, but HW or performance cost would be prohibitive)
In this CSR case: again, not so much.

If we are going to use "maximal freedom of implementation" as a reason for going down a particular path: 
  that decision must be justified with numbers, ideally, but a discussion of possible costs that restricting that freedom would cost.
In the CSR case: the costs are typically a handful of gates, and sometimes save logic.
If cases exist where this is not true: spec those CSR behaviors specifically. Otherwise, limit that freedom.


Scott Johnson
 


On Thu, Nov 18, 2021 at 8:40 AM Allen Baum <allen.baum@...> wrote:
I'm going to shortcut this discussion a bit to make sure we're not inventing new problems.
(for a very large definition of shortcut. This post isn't short....)

I've never seen a list of all the cases where there is a modifier bit that controls some other CSR field.
The obvious (to me) ones are: 
   clearing MISA bits turning off extensions; this generally removes CSRs entirely, it doesn't make them readonly.
   setting SATP.mode which effects low order xTVEC bits (I think I have that right)
   setting mseccfg bits may affect other CSRs, but in many cases those are write1-to-set, and the transactional nature is clear and deliberate.
This is clearly not a comprehensive list, but it would be good to see one for several reasons


I believe you are referring to mtvec.MODE (instead of satp.MODE) affecting the alignment requirements of mtvec.BASE. And same for stvec.

A few more off the top of my head:

Writing misa.H=0 makes many accessible bits into read-only 0.

mideleg masks sip, sie, hip, hie, and hideleg.


Allen Baum
 

Yes, mvtvec.MODE, not satp. Thanks. And thanks for the other examples.
I think all these examples are ones where that makes a field be read-only (and read-only zero).

Those are the easy ones really. I thought there were cases where legal values were restricted - but not to zero.
Embarrassingly, I can't come up with them off the top of my head, though



On Thu, Nov 18, 2021 at 9:57 AM Scott Johnson <scott.johnson@...> wrote:

On Thu, Nov 18, 2021 at 8:40 AM Allen Baum <allen.baum@...> wrote:
I'm going to shortcut this discussion a bit to make sure we're not inventing new problems.
(for a very large definition of shortcut. This post isn't short....)

I've never seen a list of all the cases where there is a modifier bit that controls some other CSR field.
The obvious (to me) ones are: 
   clearing MISA bits turning off extensions; this generally removes CSRs entirely, it doesn't make them readonly.
   setting SATP.mode which effects low order xTVEC bits (I think I have that right)
   setting mseccfg bits may affect other CSRs, but in many cases those are write1-to-set, and the transactional nature is clear and deliberate.
This is clearly not a comprehensive list, but it would be good to see one for several reasons


I believe you are referring to mtvec.MODE (instead of satp.MODE) affecting the alignment requirements of mtvec.BASE. And same for stvec.

A few more off the top of my head:

Writing misa.H=0 makes many accessible bits into read-only 0.

mideleg masks sip, sie, hip, hie, and hideleg.


David Horner
 


On 2021-11-18 11:40 a.m., Allen Baum wrote:
I'm going to shortcut this discussion a bit to make sure we're not inventing new problems.
(for a very large definition of shortcut. This post isn't short....)

I've never seen a list of all the cases where there is a modifier bit that controls some other CSR field.
The obvious (to me) ones are: 
   clearing MISA bits turning off extensions; this generally removes CSRs entirely, it doesn't make them readonly.
   setting SATP.mode which effects low order xTVEC bits (I think I have that right)
   setting mseccfg bits may affect other CSRs, but in many cases those are write1-to-set, and the transactional nature is clear and deliberate.
This is clearly not a comprehensive list, but it would be good to see one for several reasons
The relevant one here is to avoid having us solve problems that don't exist.
 I don't know how easy it is to extract this information from Sail, but riscv-config has a syntax to describe that, along with its illegal->legal syntax.
It doesn't necessarily comprehend new extensions yet.

There appears to be no shortage in desire for more tuning knobs and configuration settings.

We can add the hoops that RV32 split high/low of 64bit csr have to manage.


So, before we go off on this tangent, we should understand the scope of this "problem"

Also, John said:
>> Compared to the first proposal, this one swings in the opposite direction toward maximal freedom for the implementation.  
>> So how does everyone feel about this alternate proposal?
Not on mailing list. I didn't see this.

It was probably clear from my extensive screed, I'm not, which is ironic.
As a hardware architect, I love the idea of maximal freedom.
As chair of the arch-test SIG - not so much.
There is a distinction to me between 
 - an abstract freedom of implementation, and 
 - a speced   freedom of implementation that causes code to produce different results.

 It was the latter of these is I intended to address.

I think the distinction is problematic in the comparison.

These are more than distinct manifestations of similar concepts.

They are different concepts altogether.

theoretical vs experimental.

abstract ideal vs tangible examples


I think that distinction has not been emphasized enough.
If anyone has been conflating these then it is just awareness that is the problem
 It doesn't just complicate my life as SIG chair, but software ecosystem and platform/profile definitions as well, and is an opening wedge into fragmentation.

Yes a definite risk.

We should include errata concerns; and unexpected, perhaps impossible to diagnose, faillures.


And it often just isn't necessary.

agreed. But often isn't always.

We do need a feature that can guarantee 100% coverage. That is software can set any legal settings without race hazzards.

There are explicit cases where it is (e.g. the results of memory accesses with and without fences) 
where the spec is clear that if you want consistent results you must use fences, akak "if it hurts when you do that, don't do that"
That's an easy case;  the reasoning and costs are clear (you could build a system that gave consistent results 
   and doesn't need fences, but HW or performance cost would be prohibitive)
In this CSR case: again, not so much.

If we are going to use "maximal freedom of implementation" as a reason for going down a particular path:
  that decision must be justified with numbers, ideally, but a discussion of possible costs that restricting that freedom would cost.
In the CSR case: the costs are typically a handful of gates, and sometimes save logic.
If cases exist where this is not true: spec those CSR behaviors specifically.

Otherwise, limit that freedom.

Problem is we already have allowed it.

And there is little political will to curtail.

Apparently we cannot don't admit we may have erred [even if just to one side or the other].

So I don't know all of what John wrote, so I do not know the full context of your response.

My main point was that we can view these sets of changes in a transactional manner, even those that are not clear and deliberate.

It provides another perspective for the analysis of any specific case, and the general use case.

LOCK could reasonably mean that during this csr setting sequence lower privilege code stalls on csr read or write.

It could also mean that while LOCKed csr values as seen off hart [interrupt controllers/ other harts] see the original and not the transient state.

The LOCKing level is able to see the transient state so it can validate that all is as intended before the UNLOCK which is effectively the commit.

If all is not as intended the software should reverse its changes [by rewriting the csr, validate they are OK, then UNLOCK.

If the software cannot reverse its changes it calls up to the next level for help until it eventually aborts/reboots.

Individual writes can still have a measure of Write Any Update to Definitely-Valid [WAUDV]

but this could be further relaxed without compromising establishing a Legal End Value

[nor complicating testing as this alternative is just write bits as written] readily verifiable for all bits that are architecturally writable]


In no way need this allow every bit in every csr to be writable.