(Go: >> BACK << -|- >> HOME <<)

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

No GCMODE #302

Open
jrtc27 opened this issue Jul 1, 2024 · 30 comments
Open

No GCMODE #302

jrtc27 opened this issue Jul 1, 2024 · 30 comments
Labels
enhancement New feature or request

Comments

@jrtc27
Copy link
Collaborator
jrtc27 commented Jul 1, 2024

We have SCMODE but no way to extract it back out. For RV64 one could slice it out of the high bits, but this gets rather ugly on RV32.

@tariqkurd-repo
Copy link
Collaborator

it would be cheap to add it back in

@tariqkurd-repo tariqkurd-repo added the enhancement New feature or request label Jul 1, 2024
@tariqkurd-repo
Copy link
Collaborator
tariqkurd-repo commented Jul 2, 2024

We also have this text: the mode can be optionally switched using MODESW, and the result observed in dinfc.M. in debug mode which is incorrect, which caused this discussion. The result can't be observed without GCMODE as integer mode only reads the address field.

Although GCMODE doesn't solve the problem as it's still not possible to make all of dinfc visible in integer mode, or the PCC.

So the question is - how can code reliably know what the operating mode is? If we implement the same as CGetFlags then we still can't work it out, can we?

image

There must be a method (possibly to be defined) which let's software read the current mode.

@arichardson
Copy link
Collaborator

Reading the current mode can be done by executing something like auipc; gctag/gchi but reading the mode from arbitrary capabilities requires awkward bitmanip or a dedicated instruction.

@tariqkurd-repo
Copy link
Collaborator

but AUIPC in integer mode doesn't return the metadata, it just gives in integer result.So maybe we can say that if you do AUIPC with zero offset and the tag isn't set then it must be integer mode, and if it is set then it's capability mode.

so GCMODE becomes AUIPC x, 0; GCTAG y, x

y=1 for cap mode, y=0 for int mode

Is that good enough?

@PRugg-Cap
Copy link
Contributor
PRugg-Cap commented Jul 2, 2024

I think that's what @arichardson meant, but the point is there's no easy way to know what the mode bit is for a cap that isn't in PCC, i.e. what the mode will be when you jump to it. I guess there's a question about how common that would be?

@tariqkurd-repo
Copy link
Collaborator

bext can be used to extract it for RV64, trickier for RV32 because of the encoding.
Yes - it's all about whether it's common enough to care about it.

@tariqkurd-repo
Copy link
Collaborator

In debug mode though AUIPC may not be valid - as PC relative instructions may be illegal.
Does the debugger care?
Should we add GCMODE for this reason? So the mode can be observed in debug mode?

@jrtc27
Copy link
Collaborator Author
jrtc27 commented Jul 3, 2024

GCMODE will also be needed for instruction emulation trap handlers.

@tariqkurd-repo
Copy link
Collaborator

How exactly? Can you give more details @jrtc27 ?

@jrtc27
Copy link
Collaborator Author
jrtc27 commented Jul 3, 2024

You need to know the mode for xEPCC to know how to decode the instruction and figure out what to do.

@tariqkurd-repo
Copy link
Collaborator
tariqkurd-repo commented Jul 3, 2024

I guess you can do that by reading xEPCC, using using BEXT , and trickier decoding for RV32

But if AUIPC is illegal in debug mode, there's still no way of observing the mode in debug mode without GCMODE, which seems like a weak argument for a new encoding, maybe we can say something like the LSB of dinfc is the current mode, or something like that, as that way it can be observed.

@PRugg-Cap
Copy link
Contributor

@tariqkurd-repo I think you can't do that even with GCMODE, unless you mean for GCMODE to get the current mode of PCC, rather than the mode of a capability in a register?

@jrtc27
Copy link
Collaborator Author
jrtc27 commented Jul 3, 2024

I'm not talking about debug mode at all.

@tariqkurd-repo
Copy link
Collaborator
tariqkurd-repo commented Jul 3, 2024 via email

@jrtc27
Copy link
Collaborator Author
jrtc27 commented Jul 3, 2024

(I'm talking about firmware, hypervisors or kernels needing to know what mode the software running on top of it is in, whether because it affects the SBI interface, or because it needs to decode the instruction that xEPCC refers to)

@andresag01
Copy link
Collaborator

(I'm talking about firmware, hypervisors or kernels needing to know what mode the software running on top of it is in, whether because it affects the SBI interface, or because it needs to decode the instruction that xEPCC refers to)

@jrtc27 : This is a good use-case. An instruction that simply gets the mode of an arbitrary capability in a register is helpful for this. However, please note that it will not tell you the effective CHERI execution mode because that is a combination of CSRs and the PCC M-bit that the process was using at the time. Given that we provide such an instruction, is it reasonable to still expect software (e.g. Hypervisors, firmware, kernels, etc) to also look at the CSR state and work out the effective mode? This will probably take quite a few instructions (haven't worked it out yet!)

@jrtc27
Copy link
Collaborator Author
jrtc27 commented Jul 3, 2024

Yes, and there's no good way to avoid that given the effective encoding mode also requires knowing what privilege mode you came from, so that would need to be an input to a hypothetical all-powerful instruction. The alternative would be to make it illegal to have M=0 whilst CHERI is disabled (though not as an illegal instruction exception, since you'd still need to disambiguate the cause there :)).

@andresag01
Copy link
Collaborator
andresag01 commented Jul 3, 2024

There could be an instruction that tells you the "effective" CHERI mode given the cap in xEPCC and other relevant CSRs for example although that sounds hard (and fiddly!) to implement in hardware...

Do you know in which cases the hypervisor, kernel, etc needs to know the effective CHERI mode of the other process? It would be great to have a concrete example use-case; perhaps there is something else we can do to improve this (if needed!).

@jrtc27
Copy link
Collaborator Author
jrtc27 commented Jul 3, 2024

The two that immediately come to mind are:

  1. Misaligned access emulation in firmware (or soon the kernel, in the case of Linux, which wants to handle it itself)

  2. MMIO device trap-and-emulate for hypervisors (UART, RTC, (A)PLIC, PCIe, VirtIO, ...)

Whilst the uncompressed instructions likely don't need to know the encoding mode, the compressed ones do due to repurposing encoding space.

@tariqkurd-repo
Copy link
Collaborator

Uncompressed instructions do need to know though don't they? If you're emulating misaligned you need to know if the auth cap is DDC or cs1

The handler can always read CRE for the lower privilege level which it is emulating can't it? And use that when deciding how to decode.

@tariqkurd-repo
Copy link
Collaborator

and none of this solves this problem:

the current mode can always be observed in dinfc.M.

which is not true in debug mode, so I should remove this from the spec.

@tariqkurd-repo
Copy link
Collaborator

Jamie is suggesting that GCMODE rd, x0 returns the M-bit from the current PCC in all cases, including debug mode which solves the problem of not observing the mode in debug mode.

@jrtc27
Copy link
Collaborator Author
jrtc27 commented Jul 4, 2024

I mean it wouldn’t be GCMODE rd, c0 because that would mean precisely that. What you’re proposing is to make GCMODE’s cs1 have a constraint that it’s not c0 and use that spare encoding as GCMODE rd, pcc. That would be quite the exception to the proposed extension.

@tariqkurd-repo
Copy link
Collaborator

yes - GCMODE rd, cs0 would do GCMODE rd, pcc. It's irregular, but otherwise we have no way of reading the mode in debug mode.

@jrtc27
Copy link
Collaborator Author
jrtc27 commented Jul 4, 2024

I mean, there should be a way to read the mode without requiring a program buffer anyway, which may also solve that for you depending on how that’s done.

@tariqkurd-repo
Copy link
Collaborator
tariqkurd-repo commented Jul 4, 2024

an alternative for debug mode would be to use one of the lower 64-bits of the dinfc CSR, such as bit 0, to be read-only representing the mode. The external debugger can then read that directly.

@tariqkurd-repo
Copy link
Collaborator

This can work as follows:

csrr cd, dinfc
which will either read the whole thing (cap mode) or only the address field (int mode).
cgettag then will return 1 for cap mode or 0 for int mode

similarly for getting it from the PC, when auipc is used instead of csrr

I'll make a PR - and also note that the M-bit is not directly observable in dinfc which is currently incorrectly stated in the doc

@andresag01
Copy link
Collaborator

@tariqkurd-repo @jrtc27 : Did this discussion reach a conclusion? Do we need a new get-tag instruction or something else?

@tariqkurd-repo
Copy link
Collaborator
tariqkurd-repo commented Jul 8, 2024 via email

@arichardson
Copy link
Collaborator

We can have the compiler lower __builtin_cheri_mode_get() to the appropriate checks+bitslicing,
e.g. gchi; bexti <m_pos>; bexti <x-pos>; and (plus for rv32: bexti <perms[4]>; xor to check we are in the right permissions quadrant. Can probably be optimized a bit further as well using shift+andi. 4-6 instructions for something rather uncommon (trap handler emulation) should be fine IMO.

arichardson pushed a commit that referenced this issue Jul 8, 2024
See #302
This does not add a new instruction to read the mode from arbitrary
capabilities but does add a suggested sequence to observe the effective
mode of the current PCC.

Co-authored-by: Andrés Amaya Garcia <andres.amaya@codasip.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants