Tom Lendacky | c262f3b | 2017-07-17 16:09:58 -0500 | [diff] [blame^] | 1 | Secure Memory Encryption (SME) is a feature found on AMD processors. |
| 2 | |
| 3 | SME provides the ability to mark individual pages of memory as encrypted using |
| 4 | the standard x86 page tables. A page that is marked encrypted will be |
| 5 | automatically decrypted when read from DRAM and encrypted when written to |
| 6 | DRAM. SME can therefore be used to protect the contents of DRAM from physical |
| 7 | attacks on the system. |
| 8 | |
| 9 | A page is encrypted when a page table entry has the encryption bit set (see |
| 10 | below on how to determine its position). The encryption bit can also be |
| 11 | specified in the cr3 register, allowing the PGD table to be encrypted. Each |
| 12 | successive level of page tables can also be encrypted by setting the encryption |
| 13 | bit in the page table entry that points to the next table. This allows the full |
| 14 | page table hierarchy to be encrypted. Note, this means that just because the |
| 15 | encryption bit is set in cr3, doesn't imply the full hierarchy is encyrpted. |
| 16 | Each page table entry in the hierarchy needs to have the encryption bit set to |
| 17 | achieve that. So, theoretically, you could have the encryption bit set in cr3 |
| 18 | so that the PGD is encrypted, but not set the encryption bit in the PGD entry |
| 19 | for a PUD which results in the PUD pointed to by that entry to not be |
| 20 | encrypted. |
| 21 | |
| 22 | Support for SME can be determined through the CPUID instruction. The CPUID |
| 23 | function 0x8000001f reports information related to SME: |
| 24 | |
| 25 | 0x8000001f[eax]: |
| 26 | Bit[0] indicates support for SME |
| 27 | 0x8000001f[ebx]: |
| 28 | Bits[5:0] pagetable bit number used to activate memory |
| 29 | encryption |
| 30 | Bits[11:6] reduction in physical address space, in bits, when |
| 31 | memory encryption is enabled (this only affects |
| 32 | system physical addresses, not guest physical |
| 33 | addresses) |
| 34 | |
| 35 | If support for SME is present, MSR 0xc00100010 (MSR_K8_SYSCFG) can be used to |
| 36 | determine if SME is enabled and/or to enable memory encryption: |
| 37 | |
| 38 | 0xc0010010: |
| 39 | Bit[23] 0 = memory encryption features are disabled |
| 40 | 1 = memory encryption features are enabled |
| 41 | |
| 42 | Linux relies on BIOS to set this bit if BIOS has determined that the reduction |
| 43 | in the physical address space as a result of enabling memory encryption (see |
| 44 | CPUID information above) will not conflict with the address space resource |
| 45 | requirements for the system. If this bit is not set upon Linux startup then |
| 46 | Linux itself will not set it and memory encryption will not be possible. |
| 47 | |
| 48 | The state of SME in the Linux kernel can be documented as follows: |
| 49 | - Supported: |
| 50 | The CPU supports SME (determined through CPUID instruction). |
| 51 | |
| 52 | - Enabled: |
| 53 | Supported and bit 23 of MSR_K8_SYSCFG is set. |
| 54 | |
| 55 | - Active: |
| 56 | Supported, Enabled and the Linux kernel is actively applying |
| 57 | the encryption bit to page table entries (the SME mask in the |
| 58 | kernel is non-zero). |
| 59 | |
| 60 | SME can also be enabled and activated in the BIOS. If SME is enabled and |
| 61 | activated in the BIOS, then all memory accesses will be encrypted and it will |
| 62 | not be necessary to activate the Linux memory encryption support. If the BIOS |
| 63 | merely enables SME (sets bit 23 of the MSR_K8_SYSCFG), then Linux can activate |
| 64 | memory encryption by default (CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT=y) or |
| 65 | by supplying mem_encrypt=on on the kernel command line. However, if BIOS does |
| 66 | not enable SME, then Linux will not be able to activate memory encryption, even |
| 67 | if configured to do so by default or the mem_encrypt=on command line parameter |
| 68 | is specified. |