Page MenuHomeFreeBSD

Attempt at AMD's memory encryption
Needs ReviewPublic

Authored by jo_bruelltuete.com on Feb 12 2021, 11:53 PM.
Tags
None
Referenced Files
Unknown Object (File)
Dec 23 2023, 1:58 AM
Unknown Object (File)
Dec 22 2023, 9:22 PM
Unknown Object (File)
Dec 19 2023, 6:09 PM
Unknown Object (File)
Nov 28 2023, 8:21 PM
Unknown Object (File)
Nov 23 2023, 6:13 AM
Unknown Object (File)
Nov 23 2023, 5:05 AM
Unknown Object (File)
Nov 14 2023, 7:15 AM
Unknown Object (File)
Nov 14 2023, 2:16 AM
Subscribers
This revision needs review, but there are no reviewers specified.

Details

Reviewers
None
Summary

aka SEM

works by repurpusing one of the physical address bits as a marker for whether memory acccess is plaintext or encrypted.
no key management necessary, is all done transparently by the on chip mem controller.

See https://www.amd.com/system/files/TechDocs/24593.pdf, page 275 (or on-page page number 220), chapter 7.10.

For the cpuid stuff see https://www.amd.com/system/files/TechDocs/24594.pdf, page 671, chapter E.4.17.

Test Plan

testing it on a Ryzen 3250u.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

jo_bruelltuete.com created this revision.
jo_bruelltuete.com edited the test plan for this revision. (Show Details)
sys/amd64/amd64/pmap.c
5797

this assumes the page is never assigned a different virtual address. is that the case?

Where is the spec?

Without looking at the spec, just your patch:

  1. Same page may be mapped both into KVA and UVA. So this effectively means that all pages except initial kernel allocations for text and data, must be encrypted. Also, all pages are mapped in DMAP, which means that you need to set your pg_sem_c for DMAP pages as needed.
  2. Kernel often translates pte->phys address->vm page or pte->phys address->DMAP VA. You need to inspect all that places and ensure that your pg_sem_c bit is not used as part of the physical address. Look at the PG_PS_FRAME and PG_FRAME constants which often used to extract phys address from pte-like structures (we arguably need to make them more dynamic to support more bits of physical address).

hi kib, thanks for taking a look!
i'll try to figure out the dmap bits, thanks for the pointer.

spec is in https://www.amd.com/system/files/TechDocs/24593.pdf, page 275.

I think i've wrapped my head around dmap & friends... it makes things more complicated.
Will have to demote dmap mappings. If i try to encrypt user-mode pages first, i'll need to demote the dmap pages down from 1gb into 4k and set the c-bit for the small pages.
Same for trying to encrypt all pages. Will still have to demote dmap pages because of dma and the existing kernel text and preloaded module pages.

Does that sound about right?

I'll continue with user mode pages only for a v0 proof of concept. Because then I dont have to worry about dma and device drivers.

As the final solution this is not going to work, since you basically would downgrade whole DMAP.
On the other hand, for initial attempt, you could disable superpages at all, which should simplify things and give you a more straightforward playground.

For DMA, I think you would need to bounce a lot. I assume encryption is not done from IO side, which should partially mitigate unlimited access from devices?
Does AMD IOMMU able to handle encryption for IO transactions? (But we do not have AMD IOMMU driver proper)

sys/amd64/amd64/initcpu.c
207

ugh... i wasted a lot of time chasing down a bug here. this bit shift, as written, is 32 bit. but it needs to be 64 bits.
a bit embarrassing tbh...

I'm still working on this but it's really slow going rn, got very little time.

I changed my approach to this. What we really need to know is whether a physical "page" has been encrypted or not. And from that follow the right bits in the PTE etc. And not the other way around, which I attempted here first.
So I'm introducing a PGA_ENCRYPTED for vm_page and will set this bit during alloc, say when the page(s) is allocated as managed. And based on that flag then set the C bit in pmap_enter and friends. Still need to keep dmap in sync.