riscv-non-isa / riscv-brs

The Boot and Runtime Services (BRS) specification provides the software requirements for system vendors and Operating System Vendors (OSVs) to interoperate with one another by providing expectations for the Operating System (OS) to utilize in acts of device discovery, system management, and other rich operations provided in this specification.
https://jira.riscv.org/browse/RVG-48
Creative Commons Attribution 4.0 International
42 stars 13 forks source link

satp-specified address translation cannot be disabled #182

Closed jhauser-us closed 1 week ago

jhauser-us commented 4 months ago

For UEFI_030, what does "Enable address translation" mean?

Technically, when S-mode is implemented, the RISC-V Privileged Architecture does not provide any way to disable address translation for privilege modes less-privileged than M-mode. Is this requirement trying to say that the address translation mode configured in register satp cannot be Bare? If so, why is Bare excluded?

And how is UEFI_030 expected to square with the EBBR requirement (relevant for BRS-B) that, for UEFI Boot Services, "All RAM defined by the UEFI memory map must be identity-mapped, which means that virtual addresses must equal physical addresses"? Is UEFI_030's "Enable address translation" (whatever it means) only intended to apply after the call to ExitBootServices?

andreiw commented 3 months ago

This means that UEFI itself is making use of MMU facilities. It still must meet the requirement that all RAM is 1:1 mapped, of course - virtual addresses equaling physical addresses. But bare is not allowed.

Using the MMU is important for: a) no-execute protecting data regions, stacks, etc b) no-execute protecting non-native code regions when running x86 OpRoms (e.g. to detect transitions into non-native code) c) correct memory attributes for device DMA when Svpbmt is available, where necessary

andreiw commented 3 months ago

Please close if no further action is desired.

jhauser-us commented 2 months ago

This means that UEFI itself is making use of MMU facilities. [...]

Okay, then there are some things about this rule that I really don't understand. After booting, how does UEFI modify the page tables that are exclusively under the control of the OS? Or, if the UEFI doesn't modify the page tables itself, then how does it enforce the page-based protections that you say it requires/expects? If the OS is responsible for providing the protections that UEFI needs/expects, then "Enable address translation" doesn't cover it.

Is "Enable address translation" only meant to apply before EFI_EVENT_GROUP_READY_TO_BOOT? That's not what it says. And even so, it still seems to me that "Enable address translation" by itself doesn't guarantee the protections you listed. The page tables must be properly configured for that outcome, but there's no mention of that part. Are we assuming readers will understand that's what this requirement is about? I'm not confident of that. Just saying "address translation" doesn't, in my opinion, get the point across, especially as there's actually an EBBR requirement (maybe expected for RISC-V UEFI generally?) that addresses not be interestingly translated (identity translation only).

What else am I missing?

Anyway, one way or another, this sub-bullet of UEFI_030 will need to be rewritten, because the title of this issue still stands. RISC-V S-level address translation cannot be disabled, so the requirement to enable it is a nullity; it means nothing.

andreiw commented 3 weeks ago

UEFI runs in the same mode that the OS loader / OS is running at. For capable hardware, this means UEFI runs in HS mode, else in S mode. UEFI never ever runs in M mode. Satp can be (and in fact, was until very recently for edk2) set up as "bare".

UEFI_030 concerns itself with behavior while in UEFI boot services mode, i.e. prior to hand off to OS. Setting up proper address translation not only allows enabling security features, but is crucial for enabling driver compatibility options (e.g. https://github.com/intel/MultiArchUefiPkg). After OS boots, the only remaining parts of UEFI are runtime services, and it's the OS that is responsible for ensuring correct translations exist to invoke runtime services.

Note that "Address translation" here is meant using proper page protection using MMU and taking proper exceptions on page protection violations. The actual translations, as per UEFI spec, still must be 1:1 for RAM regions.

jhauser-us commented 3 weeks ago

This issue hasn't been addressed until some version of the explanations and corrections in use of terms are in the BRS document.

andreiw commented 3 weeks ago

Sorry, we haven't narrowed down specifically what you think is off. Your Sep 27 comment reflects an imprecise understanding of the UEFI functionality, so from my POV the feedback is entirely off base. This is something I've tried to clarify for you. The BRS document can't include the entire UEFI spec.

You claim "RISC-V S-level address translation cannot be disabled", but that makes no sense to me. Surely, S-mode software can configure SATP for bare. That means MMU off from the POV of system software - everything is writable and executable. UEFI_030 exists because MOST UEFI implementations never enabled MMU on in boot services.

jhauser-us commented 3 weeks ago

@andreiw:

A. The ARC does not agree that Bare means "MMU off". Officially, Bare is another "address-translation scheme" (the Privileged spec's words) which maps virtual addresses directly to physical addresses with no protections. The ARC doesn't want any RVI documents contradicting that interpretation.

For example, The H extension makes clear that two-stage address translation is always "in effect" or "on" in privilege modes VU and VS. No exception is made for when one or both translation modes is Bare.

At one point, the H extension says,

Although there is no option to disable two-stage address translation when V=1, either stage of translation can be effectively disabled by zeroing the corresponding vsatp or hgatp register.

"Effectively disabled" doesn't mean disabled; it means having the same effect as being disabled.

Unfortunately, on searching, I found a few places where the intended interpretation is called into question:

Except for that error in Svpbmt, the Privileged spec never says that address translation can be enabled or disabled.

If you can find other references in the Privileged spec that contradict what I've said, let me know so I can add them to the list of things that need fixing.

B. You've told me something about what you intend "Address translation is enabled" to imply in terms of protections. You need to tell the readers of the BRS document. You wrote:

Satp can be (and in fact, was until very recently for edk2) set up as "bare".

This says very clearly to me that UEFI implementors need to be informed why Bare is unacceptable. If the requirement is to use a page-based address translation mode, and I set up the page tables to mimic Bare as closely as possible (identity address translations with all permissions enabled), that does it, right? If the answer is "yes", then what in the world was the point? If the answer is "no", then evidently there's more to this rule than you've actually said.

@vlsunil: The commit you've created is a good step in the right direction, though I'm not sure whether it says enough about what the BRS spec is expecting of a UEFI implementation.

andreiw commented 3 weeks ago

Okay, I understand what you mean wrt bare and "mmu off" and we can certainly align this spec for consistency.

As to B, yes the BRS explicilty is going to forbid bare as a software implementation choice for UEFI, specifically because we want page-based protection (the mapping will be identity) - executable regions will not be writable, stacks won't be executable, etc, etc.

vlsunil commented 2 weeks ago

@vlsunil: The commit you've created is a good step in the right direction, though I'm not sure whether it says enough about what the BRS spec is expecting of a UEFI implementation.

With Andrei's suggestion that we add the requirement of EFI_MEMORY_ATTRIBUTE_PROTOCOL(https://uefi.org/specs/UEFI/2.10/37_Secure_Technologies.html#memory-protection), I think it should clarify what OS/bootloaders can expect from a UEFI implementation. Is that acceptable?