Thread (25 messages) 25 messages, 4 authors, 2021-06-04

Why does the firmware memory region have no permissions?

From: Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>
Date: 2021-06-04 07:48:03

-----Original Message-----
From: Anup Patel [mailto:Anup.Patel at wdc.com]
Sent: Friday, June 4, 2021 3:42 PM
To: Chang, Abner (HPS SW/FW Technologist) <redacted>;
Heinrich Schuchardt [off-list ref]; Daniel Schaefer
[off-list ref]
Cc: opensbi at lists.infradead.org; Atish Patra <redacted>
Subject: RE: Why does the firmware memory region have no permissions?


quoted
-----Original Message-----
From: Chang, Abner (HPS SW/FW Technologist) <redacted>
Sent: 04 June 2021 12:56
To: Anup Patel <redacted>; Heinrich Schuchardt
[off-list ref]; Daniel Schaefer [off-list ref]
Cc: opensbi at lists.infradead.org; Atish Patra <redacted>
Subject: RE: Why does the firmware memory region have no permissions?


quoted
-----Original Message-----
From: Anup Patel [mailto:Anup.Patel at wdc.com]
Sent: Friday, June 4, 2021 2:58 PM
To: Chang, Abner (HPS SW/FW Technologist) <redacted>;
Heinrich Schuchardt [off-list ref]; Daniel Schaefer
[off-list ref]
Cc: opensbi at lists.infradead.org; Atish Patra <redacted>
Subject: RE: Why does the firmware memory region have no permissions?


quoted
-----Original Message-----
From: Chang, Abner (HPS SW/FW Technologist)
[off-list ref]
quoted
quoted
quoted
Sent: 04 June 2021 12:00
To: Heinrich Schuchardt <redacted>; Anup Patel
[off-list ref]; Daniel Schaefer [off-list ref]
Cc: opensbi at lists.infradead.org; Atish Patra <redacted>
Subject: RE: Why does the firmware memory region have no
permissions?
quoted
quoted
quoted

quoted
-----Original Message-----
From: Heinrich Schuchardt [mailto:xypron.glpk at gmx.de]
Sent: Friday, June 4, 2021 1:15 AM
To: Anup Patel <redacted>; Chang, Abner (HPS SW/FW
Technologist) [off-list ref]; Daniel Schaefer
[off-list ref]
Cc: opensbi at lists.infradead.org; Atish Patra <redacted>
Subject: Re: Why does the firmware memory region have no
permissions?
quoted
quoted
quoted
On 6/3/21 6:51 PM, Heinrich Schuchardt wrote:
quoted
On 6/3/21 5:34 PM, Anup Patel wrote:
quoted
+Heinrich
quoted
-----Original Message-----
From: Chang, Abner (HPS SW/FW Technologist)
[off-list ref]
quoted
quoted
quoted
Sent: 03 June 2021 20:05
To: Anup Patel <redacted>; Daniel Schaefer
[off-list ref]
Cc: opensbi at lists.infradead.org
Subject: RE: Why does the firmware memory region have no
permissions?
quoted
quoted
quoted

quoted
-----Original Message-----
From: Anup Patel [mailto:Anup.Patel at wdc.com]
Sent: Wednesday, June 2, 2021 11:15 PM
To: Chang, Abner (HPS SW/FW Technologist)
[off-list ref];
quoted
quoted
quoted
quoted
quoted
Daniel Schaefer [off-list ref]
Cc: opensbi at lists.infradead.org
Subject: RE: Why does the firmware memory region have no
permissions?
quoted
quoted
quoted
quoted

quoted
-----Original Message-----
From: Chang, Abner (HPS SW/FW Technologist)
[off-list ref]
quoted
quoted
quoted
quoted
quoted
Sent: 02 June 2021 20:19
To: Chang, Abner (HPS SW/FW Technologist)
[off-list ref];
quoted
quoted
quoted
quoted
Anup
quoted
Patel [off-list ref]; Daniel Schaefer
[off-list ref]
quoted
Cc: opensbi at lists.infradead.org
Subject: RE: Why does the firmware memory region have no
permissions?
quoted
quoted
quoted
quoted
quoted

quoted
-----Original Message-----
From: opensbi [mailto:opensbi-bounces at lists.infradead.org]
On Behalf Of Chang, Abner (HPS SW/FW Technologist)
Sent: Saturday, May 15, 2021 11:30 PM
To: Anup Patel <redacted>; Daniel Schaefer
[off-list ref]
Cc: opensbi at lists.infradead.org
Subject: RE: Why does the firmware memory region have no
permissions?
quoted
quoted
quoted

quoted
-----Original Message-----
From: Anup Patel [mailto:Anup.Patel at wdc.com]
Sent: Saturday, May 15, 2021 4:09 PM
To: Chang, Abner (HPS SW/FW Technologist)
[off-list ref];
quoted
quoted
quoted
Daniel
quoted
Schaefer [off-list ref]
Cc: opensbi at lists.infradead.org
Subject: RE: Why does the firmware memory region have
no
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
permissions?
quoted
quoted
quoted
Hi Abner,
quoted
-----Original Message-----
From: Chang, Abner (HPS SW/FW Technologist)
[off-list ref]
quoted
quoted
Sent: 15 May 2021 11:47
To: Anup Patel <redacted>; Daniel Schaefer
[off-list ref]
Cc: opensbi at lists.infradead.org
Subject: RE: Why does the firmware memory region have
no
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
permissions?
quoted
quoted
quoted

quoted
-----Original Message-----
From: Anup Patel [mailto:Anup.Patel at wdc.com]
Sent: Friday, May 14, 2021 7:58 PM
To: Daniel Schaefer <redacted>
Cc: opensbi at lists.infradead.org; Chang, Abner (HPS
SW/FW
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
Technologist)
quoted
quoted
quoted
[off-list ref]
Subject: RE: Why does the firmware memory region have
no
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
permissions?
quoted
quoted
quoted

quoted
-----Original Message-----
From: Anup Patel
Sent: 14 May 2021 17:22
To: Daniel Schaefer <redacted>
Cc: opensbi at lists.infradead.org; Chang, Abner (HPS
SW/FW
Technologist) [off-list ref]
Subject: RE: Why does the firmware memory region
have
quoted
quoted
no
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
permissions?
quoted
quoted

quoted
-----Original Message-----
From: opensbi <opensbi-
bounces at lists.infradead.org>
quoted
On
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
Behalf
Of
quoted
quoted
quoted
quoted
quoted
Daniel Schaefer
Sent: 13 May 2021 10:26
To: Anup Patel <redacted>
Cc: opensbi at lists.infradead.org; Chang, Abner (HPS
SW/FW
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
Technologist) [off-list ref]
Subject: Why does the firmware memory region have
no
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
permissions?
quoted
quoted
quoted
quoted
quoted
Whoops, put CC as subject...

On 5/12/21 6:20 PM, Daniel Schaefer wrote:
quoted
Hi Anup,

I'm in the process of upgrading EDKII to OpenSBI 0.9
and using the Generic
Platform.
quoted
Previously we were doing sbi_init with M-Mode,
adding
quoted
quoted
our
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
SBI extension and then calling sbi_switch_mode to
switch
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
to S-
Mode.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
Now sbi_init disallows initializing to M-Mode, so I'm
directly switching to S-Mode. It seems that even from
S-Mode I can register our SBI
extension with sbi_ecall_register_extension.
quoted
Is that correct?
The OpenSBI sources are meant to run only from M-
mode
quoted
quoted
so
quoted
we
quoted
quoted
quoted
quoted
quoted
quoted
quoted
cannot
quoted
quoted
quoted
quoted
register SBI extension using
sbi_ecall_register_extension().
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
The? sbi_switch_mode() is not stricter due to OpenSBI
domain
support.
quoted
quoted
quoted
The sbi_hart_switch_mode() is fine. It's the
sbi_domain_init() which is enforcing next booting stage
to be at lower privilege for
root
quoted
domain.
quoted
quoted
quoted
quoted
For time being, you can try removing checks on "dom-
next_mode"
quoted
quoted
quoted
quoted
quoted
in sanitize_domain()
Hi Anup, I think we currently skip that check for moving
on the
edk2 boot process. So do you have plan to remove this
check?
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
Or any
alternative?
quoted
quoted
quoted
I think it is unnecessary having this check on the next
privilege
mode.
quoted
quoted
quoted
That
quoted
quoted
should be at OEM discretion of which privilege mode to
run their next firmware stage based on the platform
design?
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
This is an important check required by OpenSBI domain
support so that next booting stage cannot tamper with PMP
configuration (and other security configuration) done by
OpenSBI.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
I understand the importance of not giving any chance to
tamper
PMP
quoted
quoted
quoted
quoted
quoted
quoted
setting, however this could be the responsibility of the
next boot phase
before OS.
quoted
OpenSBI as the early phase boot firmware should be
generally provide SBIs to platform variants, and have the
flexibility to hand off to either M-mode or S-mode firmware
(Actually I don't think OpenSBI
should
quoted
handle this).
quoted
Platform code is provided by OEM/vendor, OpenSBI should
allow it if platform code says I would like to run my next
phase firmware in M-
mode.
quoted
quoted
We restrict the privilege phase for the next phase in
OpenSBI also not compliant with the UEFI spec which says
UEFI RISC-V firmware could be executed in either M-mode or
S-mode. Some
EFI
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
driver
may
quoted
quoted
quoted
quoted
quoted
quoted
be loaded in
S- mode but provide the M-mode code such as management
mode,
quoted
quoted
the
quoted
quoted
quoted
quoted
quoted
quoted
Platform Runtime Mechanism or some other use cases. The
next
firmware
Compare this to EDK II with TF-A. No EDK II code runs in EL3. TF-A
is the only EL3 code.

Same for RISC-V: OpenSBI is the M-mode firmware. No other part of
the firmware shall run in M-mode. I cannot see that the UEFI
specification requires a different segregation of duties.
That paragraph stated in UEFI spec is based on RISC-V privilege
spec, which says all platforms must implement M-mode.
The simplest platform can only has M-mode. That makes sense to say
UEFI firmware can run on either M-mode or S-mode.
UEFI spec is based on RISC-V privilege spec does not mean UEFI has to
run in M-mode only.
sure, could be on  either one.
quoted
The simplest platform having M-mode will not support regular S-mode
Linux which is the client software for UEFI so if there is not UEFI
client on a simple M-mode only platform then why should EDK2 target
M-mode only platform ??
UEFI spec just reflects the RISC-V spec, it doesn't means which firmware
implementation should target on which kind of platform.
EDK2 can do either M-mode or S-mode.
quoted
On similar lines, OpenSBI only supports platforms where S-mode is
available because there is no point in providing SBI services for
platform not having S-mode.
You are right at this point.
quoted
quoted
I also curious about why opensbi restricts to switch the next mode
to M- mode. How does opensbi runs on the platform only provides M-
mode?
quoted
That's because OpenSBI acts as secure monitor. The TEE will run as
secure OpenSBI domain whereas Linux (non-secure) software will run as
non-secure OpenSBI domain.
quoted
quoted
What RISC-V is lacking up to now is run modes for trusted
execution environments like OP-TEE. This is where you would place
management mode code and not in M-mode.
Yes, that is the plan to have management mode runs in TEE, do you
have suggestion how do we load the MM driver to TEE from S-mode, in
which phase we can we initial the MM environment and load the MM
driver to
TEE
quoted
through DXE dispatcher?  and all under S-mode.
Is any of S-mode entities can load itself to TEE?
We need to define SBI TEE calls where OpenSBI will forward these TEE
calls from Linux (non-secure) domain to OP-TEE (secure) domain. These
SBI TEE calls will have mechanism to load MM driver to secure domain
(or similar things).

Once we define the SBI TEE calls and possible ways to load TEE, the
RISC-V TEE story will become complete.
The main purpose of defining sbi_firmware_extension is to load MM driver
or
quoted
security related edk2 driver to M-mode (or TEE) from s-mode in the DXE
phase.  We don't have to rely on sbi_firmware_extension if SBI can provide
the corresponding APIs.
Nope, we had defined SBI FW extensions space so that EDK2 M-mode
code can pass on some information to EDK2 S-mode.

For things like loading TEE modules, we have to standardize SBI TEE
calls which any S-mode software (including U-Boot S-mode) can use.
We can't use EDK2 specific SBI FW extension for this.
That's for sure we don't need EDK2 specific SBI FW extension if SBI TEE extension is defined.
Please share the SBI TEE progress with me, thanks.
The SBI TEE extension will be optional so S-mode software should
check extension availability before use.

Please update EDK2 boot-flow to support running EDK2 entirely
in S-mode. This ways distros can happily use EDK2 inside Guest/VM.
I hear that ;)
Regards,
Anup
quoted
quoted
The OpenSBI domain support and SBI TEE calls will make RISC-V TEE
competitive with ARM TF-A.

I am totally convinced now that EDK2 should entirely run in S-mode so
that we can re-use EDK2 for Guest/VM. The SBI provider for EDK2 could
be OpenSBI or hypervisors. This will be exactly same as how
EDK2 runs in ARM world.

Regards,
Anup
quoted
Regards,
Abner
quoted
Best regards

Heinrich
quoted
quoted
quoted
quoted
quoted
quoted
has the responsibility to switch to S-mode when handoff to
OS or software if the platform design requires that (I
remember we have the simi? lar sentence in
riscv-platform-spec). EDK2 code can't just remove the check
"dom->next_mode", we use
OpenSBI
quoted
quoted
without any
quoted
quoted
quoted
quoted
quoted
changes.
quoted
quoted
I am still worried about the custom SBI extension required
by
EDK2.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
This will not work when running EDK2 inside Guest/VM
because Guest/VM boots in VS-mode and the SBI calls are
provided by hypervisors (KVM, Xvisor, etc). I think you
should revisit
EDK2 boot-flow to make it compatible with virtualization
and OpenSBI
domains.
quoted
quoted
Ok, I will revisit this. Thanks for the reminder.
Hi Anup,
I have few questions regard to HSM support in opensbi,

- Is the purpose of invoking platform_domain_init at the end
of
sbi_init() to let platform code to register the domains
through
sbi_domain_register()?
quoted
Yes, domains need to be populated as late as possible so that
domains are switched only after all initialization is completed.
quoted
- What is the reason that each domain is requested to have
the memory region of ROOT_FW_REGION?
The ROOT_FW_REGION protects the firmware itself. The
fw_region
is
quoted
quoted
quoted
quoted
quoted
quoted
based on fw_start and fw_size members of the "struct
sbi_scratch".
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
- I think opensbi will have the implement of switching the
next mode to
HSM
quoted
later?
Can you elaborate why you need this ?
Ah no I was just wonder how opensbi switch the next mode to
HSM.
quoted
quoted
quoted
quoted
quoted
quoted
You
had
quoted
quoted
quoted
the answer in below.
quoted
quoted
- How does opensbi loads the hypervisor in HSM?
When H-extension is available the next mode is automatically
HS-mode (i.e. S-mode with virt=off).

You still did not share how you will make EDK2 boot flow work
for VS-modes because hypervisor will start Guest/VM directly
in VS-mode and M-mode components of EDK2 can't run inside
Guest/VM
quoted
quoted
quoted
quoted
I don't have the full picture of EDK2 boot flow for HSM yet. I
am stillthinking how the Management Mode work on HSM
especially to the multiple
type1
quoted
quoted
HS-mode and VS-mode are both S-mode with differing
capabilities. A software written for S-mode (without using
H-extension CSRs) should run
unmodified
quoted
quoted
in both HS-mode and VS-mode.
quoted
hypervisors run on the each domain. Also, the platform errors
or RAS errors on server platform has to deliver the error
event to the corresponding
This headache of hypervisor so hypervisor will use appropriate
HW features to virtualize RAS events/errors.
quoted
domains. The idea as I mentioned earlier, EDK2 FW is not
necessarily to be
I totally disagree. In ARM64 world, people use EDK2 inside
Guest/VM so why can't we do the same in RISC-V world.

Same distros which run natively without hypervisor will expect
to run in the same way inside Guest/VM. Are you suggesting that
EDK2 will not be available to distros inside Guest/VM ??
quoted
executed as a VS entity. EDK2 FW is executed when processor
power on and it uses opensbi as a library to initial the basic
platform
(vendor) and opensbi initialization, then edk2 FW run through
PEI/DXE for the OEM platform and proprietary features
initialization. EDK2 still can jump to opensbi to run the
domain initialization at the last boot stage, says BDS,? and
then switch to HSM. We have to consider those server features
such as critical platform error handling, event logging,
FW<->BMC communication, Remote FW configuration through
Redfish beyond the HSM, or some
of
quoted
quoted
quoted
quoted
quoted
above drivers can run in HSM before hypervisor is launched, I
am not sure yet.
If other architectures are able to use EDK2 inside Guest/VM
then I don't see why we can't do the same for RISC-V.
quoted
SBI FW extension shouldn't be the problem because HSM
hypervisor can still bypass the sbi invocations from VS entity
to M-mode if the sbi function number is in the firmware range,
right? e.g. SBI FW extension can stillprovide the management
mode interface to (V)S mode entity.
Bypassing SBI FW calls from VS-mode to M-mode will have it's
own issues and I am reluctant to go this direction without
fully understanding why
EDK2 needs SBI FW calls.
EDK II (and U-Boot) need the SBI system reset extension to
implement the
ResetSystem() runtime service which operating systems use to
reboot or poweroff.

The hypervisor must provide an SBI implementation running in HS
mode.
quoted
quoted
quoted
This is why we have trap delegation registers:

"When a trap occurs in HS-mode or U-mode, it goes to M-mode,
unless delegated by medeleg or mideleg, in which case it goes to
HS-
quoted
mode.
quoted
quoted
quoted
quoted
When a trap occurs in VS-mode or VU-mode, it goes to M-mode,
unless
delegated
quoted
by medeleg or mideleg, in which case it goes to HS-mode, unless
further delegated by hedeleg or hideleg, in which case it goes
to VS-
mode."
quoted
quoted
EDK II will run in VS mode. EDK II's ecalls will be handled by
the hypervisor's SBI implementation.

It is not important if EDK II is compiled with or without the
OpenSBI library. In both cases the hypervisor must invoke EDK
II's PEI entry point and not enter EDK2's SEC phase (cf.
INVALID URI REMOVED
specification/2_design_discussion/23_boot_sequence__;!!NpxR!11uLLL9PJI
quoted
quoted
quoted
quoted
r gauJtSLgUAqsEYMnbRf43C_kxGqaYi7ZLodCE40XfAtUXp4R9brg$ ).
quoted

On ARM EDK II is a BL33 payload of TF-A. TF-A is not in the code
base of EDK II.

We should do the same on RISC-V: Remove OpenSBI from the EDK
II
quoted
quoted
code
quoted
quoted
quoted
base and compile upstream OpenSBI with EDK II as FW_PAYLOAD.

This way we don't have to worry about differences between EDK II
running in S-mode and VS-mode.

@Rick, Bin
The same will have to be done for U-Boot's SBI support. We
should not require SPL starting OpenSBI to have SBI support on
QEMU/KVM.
quoted
quoted
quoted
quoted
Best regards

Heinrich
quoted
The fact that you need to depend on SBI FW extension seems to
be
becoming
quoted
quoted
a road block for EDK2 inside Guest/VM.

Regards,
Anup
quoted
Abner

quoted
Regards,
Anup
quoted
Regards,
Abner
quoted
Regards,
Abner
quoted
Regards,
Anup
quoted
Thanks and regards,
Abner
quoted
quoted
Next booting stage has to run from lower privilege
mode
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
(S-mode or
U-
mode) otherwise OpenSBI cannot protect itself from
next
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
booting stage if it starts in M-mode.
quoted
quoted
However, sbi_init when directly initializing to
S-Mode checks that the
start_address is executable.
quoted
So I'm wondering why the FW region isn't set as
executable in
OpenSBI?
quoted
quoted
quoted
quoted
How do other FWs like U-Boot get around this?
https://github.com/riscv/opensbi/commit/b1678af210dc4b4e6d586d6d966
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
1
quoted
quoted
quoted
quoted
quoted
7
quoted
e
quoted
9641618994#diff-
6e8e352a8a90ba5a7adbb58a806ed9b6404c2c67db416332f9c05a
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
6b322eecd6R346

If I try to set my own regions by adding
.domains_root_regions I get another error because
OpenSBI
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
checks that I have a region that is the same as the
FW region added by OpenSBI. If I duplicate the FW
region
and
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
mark the first one as executable I can pass the
executable check and also the check that there's an
FW
quoted
quoted
region.
quoted
quoted
quoted
quoted
Additionally we have to manually call pmp_set in our
custom platform to make the FW region RWX.

That seems like a workaround, however. Do you have
any
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
suggestion to
properly fix it?
quoted
I'm sure we're misunderstand something.
I suggest two things:
1) Register your custom SBI extension from M-mode
only
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
before switching to S-mode
2) Make sure that fw_start and fw_size set in the
sbi_scratch for each HART only point to the M-mode
code
quoted
quoted
and
quoted
quoted
quoted
quoted
quoted
data.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
Preferably have S-mode code and data not linked in the
same
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
binary as M-mode code
and
quoted
quoted
data.
quoted
quoted
quoted
quoted
For context: We're writing the start addr and size of
our FW image into the scratch space before OpenSBI
is
quoted
quoted
quoted
quoted
quoted
quoted
quoted
initialized.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
Therefore we're expecting it to set the PMP settings
correctly.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
Please check out my workaround commit:
https://github.com/riscv/riscv-edk2-
platforms/commit/a5ac63096ca
quoted
quoted
quoted
quoted
quoted
quoted
5da7
95
042baf650170643fe219cab

Thanks,
Daniel
Regards
Anup
Regards,
Anup
--
opensbi mailing list
opensbi at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
  
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help