Skip to content
This repository has been archived by the owner on Mar 7, 2024. It is now read-only.

How h/stateen become read-only zero for zero bits in mstateen? #9

Open
liweiwei90 opened this issue Jul 2, 2022 · 22 comments
Open

Comments

@liweiwei90
Copy link

liweiwei90 commented Jul 2, 2022

When I tried to add support for smstateen extension in spike(riscv-software-src/riscv-isa-sim#1035), I find there are two ways to make that bits read-only zero:

  1. not change h/stateen register, just use mstateen as mask when read/write h/stateen: ignore zero bits when write, and mask zero bits to zero when read
  2. directly clear the same bits of h/stateen register when clear bits of mstateen

These two ways will have different result for the second read of hstateen0 for following sequence of operation (assume origin mstateen0/hstateen0 is 2):

  • write 0 to mstateen0
  • read hstateen0 (result -> 0)
  • restore mstateen0 to 2
  • read hstateen0 (result? 2 or 0)
@gfavor
Copy link
Collaborator

gfavor commented Jul 3, 2022

This is a broad issue that isn't specific to the use of "read-only zero" in Smstateen, but to all places where it doesn't simply equate to hardwired RAZ and instead can dynamically vary - as a function of a write to another CSR - between "read-only zero" and not. For this reason this term should be defined in the Priv spec, and in fact it is - but indirectly and hence not in a blatantly obvious way. This type of case is covered by an even broader arch definition:

2.4 CSR Field Modulation 
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.  

So when a field becomes "read-only zero" and then unbecomes "read-only zero", its value ends up at that final point as unspecified. Which allows for both implementations that you described, to be architecturally allowable implementations.

@liweiwei90
Copy link
Author

OK, Thanks a lot!

@scottj97
Copy link

scottj97 commented Jul 6, 2022

There is a case in Smstateen where a VS-mode guest OS can write to sstateen, where some of those bits are "read-only zero" because of the value of hstateen. Upon returning to HS-mode, those bits of sstateen are not read-only zero anymore.

If those bits are now unspecified, doesn't that mean that the hypervisor in HS-mode must rewrite sstateen every time it comes back from VS-mode?

@gfavor gfavor reopened this Jul 6, 2022
@gfavor
Copy link
Collaborator

gfavor commented Jul 6, 2022

I suspect you are keying off of the following spec paragraph:

Bits in any stateen CSR that are defined to control state that a hart doesn't implement are read-only zeros for that hart. Likewise, all reserved bits not yet given a defined meaning are also read-only zeros. For every bit in an mstateen CSR that is zero (whether read-only zero or set to zero), the same bit appears as read-only zero in the matching hstateen and sstateen CSRs. For every bit in an hstateen CSR that is zero (whether read-only zero or set to zero), the same bit appears as read-only zero in sstateen when accessed in VS-mode.

Regarding hstateen versus sstateen CSRs, note the following from the spec:

For the sstateen CSRs whose access by a guest OS is permitted by bit 63 of the corresponding hstatus CSRs, a hypervisor must include the sstateen CSRs in the context it swaps for a guest OS. When it starts a new guest OS, it must ensure those sstateen CSRs are initialized to zeros, and it must emulate accesses to any other sstateen CSRs.

Also note that while operating in HS-mode, the state of sstateen CSR bits is a don't care.

And keep in mind that sstateen also applies when operating in U-mode (versus in VU-mode). Hence if the hypervisor is managing operation under it in U-mode, it needs to context switch sstateen also when switching between operating in a VM and operating down in U-mode.

@scottj97
Copy link

scottj97 commented Jul 6, 2022

OK, good points, I suppose unspecified sstateen bits is acceptable in this case.

@liweiwei90
Copy link
Author

Another question: How hstateen0 and stateen0 work, if STATEEN bit in mstateen0 is zero, ? Treating them as zero?

@gfavor
Copy link
Collaborator

gfavor commented Jul 26, 2022

Regarding the last posted question: I assume you recognize that for each mstateen and hstateen CSR, bit 63 is defined to control access to the matching supervisor-level sstateen CSR. That is, bit 63 of mstateen0 and hstateen0 controls access to sstateen0; bit 63 of mstateen1 and hstateen1 controls access to sstateen1; etc. Ditto for mstateen with respect to hstateen.

Then, for every bit in an mstateen CSR that is zero (whether read-only zero or set to zero), the same bit appears as read-only zero in the matching hstateen and sstateen CSRs. For every bit in an hstateen CSR that is zero (whether read-only zero or set to zero), the same bit appears as read-only zero in sstateen when accessed from a virtual machine.

@liweiwei90
Copy link
Author

Sorry. I didn't describe my question clearly. I know the same bit in h/sstateen0 is read-only zero when bit in mstateen0 is zero. What I really want to know is that when bit 63 in mstateen0 is zero, which means access to h/sstateen0 is disallowed, how do we treat other bits in h/sstateen0, do we just ignore them or treat them as zero? This may lead to different result. Such as when we access fcsr in HS/VS/VU/U mode, if we ignore h/sstateen0, then we need only consider mstateen0.fcsr and this access may be allowed, however it will trigger illegal/virtual instruction fault if treat them as zero.

@gfavor
Copy link
Collaborator

gfavor commented Jul 27, 2022

In general, whether a stateen bit is controlling access to some other extension-specific lower privilege level state or to lower privilege level stateen CSRs, the behavior is the same (and whether a staten CSR or any other CSR, the access control is at the granularity of the entire register):

The stateen registers at each level control access to state at all lower privilege levels, but not at its own level. When a stateen CSR prevents access to state by lower privilege levels, an attempt in one of those privilege modes to execute an instruction that would read or write the protected state raises an illegal instruction exception, or, if executing in VS or VU mode and the circumstances for a virtual instruction exception apply, raises a virtual instruction exception instead of an illegal instruction exception.

@liweiwei90
Copy link
Author

liweiwei90 commented Jul 28, 2022

So Assuming mstateen0.STATEEN is 1, hstateen0.STATEEN is 0 and m/h/sstatenen0.FCSR is 1, when we try to access FCSR:
If current priv is M mode, it's allowed
if current priv is VS mode, it's allowed
if current priv is VU mode, virtual instruction exception is raised
if current priv is HS mode, it's allowed
if current priv is U mode, illegal instruction exception is raised
Is this right?

@liweiwei90
Copy link
Author

liweiwei90 commented Jul 28, 2022

Another question: whether FCSR related check need to be done when misa.F is zero and Zfinx is not supported.
This is a little different for exception triggered when executing float point instructions in VS/VU mode since FCSR related check may trigger virtual instruction exception.
In my opinion, FCSR bit only exists when zfinx is supported as the spec said:
"bit 1 - fcsr for Zfinx and related extensions (Zdinx, etc.)".
However, in other place of the spec, only misa.F is considered:
"For convenience, when the stateen CSRs are implemented and misa.F = 0, then if bit 1 of a controlling stateen0 CSR is zero, all floating-point instructions cause an illegal instruction trap (or virtual instruction trap, if relevant), as though they all access fcsr, regardless of whether they really do."

@gfavor
Copy link
Collaborator

gfavor commented Jul 30, 2022

In short, the FCSR CSR exists only as part of the F or Zfinx extensions (and the dependent D and Zdinx extensions). If neither F nor Zfinx is implemented, then FCSR is not implemented either - and hence FCSR accesses result in an illegal/virtual instruction trap.

The two quoted pieces of spec text are consistent with each other in that the first indicates that bit 1 is not read-only zero if and only if Zfinx is implemented, and the second indicates that if F is implemented (and hence Zfinx can't be) then bit 1 must be read-only zero.

@gfavor
Copy link
Collaborator

gfavor commented Jul 30, 2022

Regarding the earlier question in #9 (comment), I think all the cases are correct. The most notable one is the VS mode case. I think, in that case, even though hstateen0.STATEEN=0 disallows direct access to sstateen0 by VS mode, HS-mode could still have written sstatenen0.FCSR=1 before context switching into VS mode. This would be very unusual, but if that's what the hypervisor did, then I believe sstatenen0.FCSR=1 applies (irrespective of hstateen0.STATEEN=0).

(Note: The preceding unusual behavior would go against the spec's statement: For the sstateen CSRs whose access by a guest OS is permitted by bit 63 of the corresponding hstatus CSRs, a hypervisor must include the sstateen CSRs in the context it swaps for a guest OS. When it starts a new guest OS, it must ensure those sstateen CSRs are initialized to zeros, and it must emulate accesses to any other sstateen CSRs.

@liweiwei90
Copy link
Author

There may be a little difference for float point instructions in VS/VU mode

  • If we check FCSR access(when Misa.F is zero) before check for whether Zfinx is supported, then vritual instruction trap may be raised
  • If we check FCSR access(when Misa.F is zero) after check for whether Zfinx is supported, then illegal trap may be raised

@liweiwei90
Copy link
Author

Regarding the earlier question in #9 (comment), I think all the cases are correct. The most notable one is the VS mode case. I think, in that case, even though hstateen0.STATEEN=0 disallows direct access to sstateen0 by VS mode, HS-mode could still have written sstatenen0.FCSR=1 before context switching into VS mode. This would be very unusual, but if that's what the hypervisor did, then I believe sstatenen0.FCSR=1 applies (irrespective of hstateen0.STATEEN=0).

Sorry. I'm a llitle confused about whether it means we "access" Xstateen CSRs when we access fcsr, and do stateen related check currently:

  • if any access for fcsr will also access Xstateen CSRs, then any access for fcsr under M mode will trigger illegal instruction trap since we cannot access mstateen CSR under M mode
  • if not, the above access will all be allowed since the FCSR bit in Xstateens are all set to one.

(Note: The preceding unusual behavior would go against the spec's statement: For the sstateen CSRs whose access by a guest OS is permitted by bit 63 of the corresponding hstatus CSRs, a hypervisor must include the sstateen CSRs in the context it swaps for a guest OS. When it starts a new guest OS, it must ensure those sstateen CSRs are initialized to zeros, and it must emulate accesses to any other sstateen CSRs.

Yeah. It's an unusual case. So does it mean this is unspecified?

@gfavor
Copy link
Collaborator

gfavor commented Jul 31, 2022

My one comment mentioning "access" - in saying "hstateen0.STATEEN=0 disallows direct access to sstateen0 by VS mode" - is just stating an arch spec fact and is only talking about access to the sstateen0 CSR (not to any CSR's whose access is controlled by bits in sstateen0).

But the reason I mentioned it is that VS-mode will be unable to access sstateen0 and change sstateen0.FCSR to whatever value it desires. It is stuck with what the hypervisor has configured for that bit. Which normally should be FCSR=0 per the arch spec quote in my "Note". But if the hypervisor set FCSR=1, then the conditions for your VS mode case are satisfied and VS mode would be allowed to access FCSR.

As a side note, nothing in the Smstateen extension can prevent access by M mode to the FCSR CSR if it is implemented. This extension only controls access by lower privilege modes. In particular, the bits in mstateen0 control access by all lower privilege modes.

To your last question, I would say that the behavior in your VS mode case is not unspecified. Software is free to not follow what the arch spec says (as an ISA spec). But as far as the implementation behavior specified by the arch spec, it simply says that trapping of accesses to FCSR is a function of sstatenen0.FCSR. It does not specify additional conditions (such as the state of hstateen0.STATEEN). In general, if the arch spec does not explicitly specify additional functionality, then there is no implied additional functionality. (This also allows for the simplest possible hardware implementation where the behavior is solely a function of sstatenen0.FCSR - and of course also mstateen0.FCSR.)

@liweiwei90
Copy link
Author

liweiwei90 commented Jul 31, 2022

Sorry. I made a mistake in above comment. What I really want to express for "under M mode" is less privilege mode. So if we access mstateen0 in less privilege mode, a illegal/virtual trap will be raised.

I agree that we can ignore the stateen0.STATEEN bit when do access control on FCSR csr. so this also means access FCSR doesn't implicitly include access for xstateen(at least not a normal csr access with full access control). Is this right?

For the other question, I think the access control from stateen should be done only when the csr exists. As you said in above comment, FCSR exists only when F or Zfinx is supported. So I think the stateen related check should be done after check for both misa.F and zfinx.

@liweiwei90
Copy link
Author

If neither F nor Zfinx is implemented, then FCSR is not implemented either - and hence FCSR accesses result in an illegal/virtual instruction trap.

I have a little confusion about this. I thnk, if FCSR is not implemented, the exception raised by acesses for it will always be illegal instruction trap.

@gfavor
Copy link
Collaborator

gfavor commented Jul 31, 2022 via email

@gfavor
Copy link
Collaborator

gfavor commented Jul 31, 2022 via email

@liweiwei90
Copy link
Author

OK. Thanks a lot.

@liweiwei90
Copy link
Author

Does stateen.FCSR bit apply to FRM and FFLAGS?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants