Re: [PATCH v6 14/34] x86/mm: Insure that boot memory areas are mapped properly

From: Tom Lendacky
Date: Mon Jun 12 2017 - 09:32:28 EST


On 6/10/2017 11:01 AM, Borislav Petkov wrote:
On Wed, Jun 07, 2017 at 02:15:39PM -0500, Tom Lendacky wrote:
The boot data and command line data are present in memory in a decrypted
state and are copied early in the boot process. The early page fault
support will map these areas as encrypted, so before attempting to copy
them, add decrypted mappings so the data is accessed properly when copied.

For the initrd, encrypt this data in place. Since the future mapping of the
initrd area will be mapped as encrypted the data will be accessed properly.

Signed-off-by: Tom Lendacky <thomas.lendacky@xxxxxxx>
---
arch/x86/include/asm/mem_encrypt.h | 11 +++++
arch/x86/include/asm/pgtable.h | 3 +
arch/x86/kernel/head64.c | 30 ++++++++++++--
arch/x86/kernel/setup.c | 9 ++++
arch/x86/mm/mem_encrypt.c | 77 ++++++++++++++++++++++++++++++++++++
5 files changed, 126 insertions(+), 4 deletions(-)

Some cleanups ontop in case you get to send v7:

There will be a v7.


diff --git a/arch/x86/include/asm/mem_encrypt.h b/arch/x86/include/asm/mem_encrypt.h
index 61a704945294..5959a42dd4d5 100644
--- a/arch/x86/include/asm/mem_encrypt.h
+++ b/arch/x86/include/asm/mem_encrypt.h
@@ -45,13 +45,8 @@ static inline void __init sme_early_decrypt(resource_size_t paddr,
{
}
-static inline void __init sme_map_bootdata(char *real_mode_data)
-{
-}
-
-static inline void __init sme_unmap_bootdata(char *real_mode_data)
-{
-}
+static inline void __init sme_map_bootdata(char *real_mode_data) { }
+static inline void __init sme_unmap_bootdata(char *real_mode_data) { }
static inline void __init sme_early_init(void)
{
diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c
index 2321f05045e5..32ebbe0ab04d 100644
--- a/arch/x86/mm/mem_encrypt.c
+++ b/arch/x86/mm/mem_encrypt.c
@@ -132,6 +132,10 @@ static void __init __sme_map_unmap_bootdata(char *real_mode_data, bool map)
struct boot_params *boot_data;
unsigned long cmdline_paddr;
+ /* If SME is not active, the bootdata is in the correct state */
+ if (!sme_active())
+ return;
+
__sme_early_map_unmap_mem(real_mode_data, sizeof(boot_params), map);
boot_data = (struct boot_params *)real_mode_data;
@@ -142,40 +146,22 @@ static void __init __sme_map_unmap_bootdata(char *real_mode_data, bool map)
cmdline_paddr = boot_data->hdr.cmd_line_ptr |
((u64)boot_data->ext_cmd_line_ptr << 32);
- if (cmdline_paddr)
- __sme_early_map_unmap_mem(__va(cmdline_paddr),
- COMMAND_LINE_SIZE, map);
+ if (!cmdline_paddr)
+ return;
+
+ __sme_early_map_unmap_mem(__va(cmdline_paddr), COMMAND_LINE_SIZE, map);
+
+ sme_early_pgtable_flush();

Yup, overall it definitely simplifies things.

I have to call sme_early_pgtable_flush() even if cmdline_paddr is NULL,
so I'll either keep the if and have one flush at the end or I can move
the flush into __sme_early_map_unmap_mem(). I'm leaning towards the
latter.

Thanks,
Tom

}
void __init sme_unmap_bootdata(char *real_mode_data)
{
- /* If SME is not active, the bootdata is in the correct state */
- if (!sme_active())
- return;
-
- /*
- * The bootdata and command line aren't needed anymore so clear
- * any mapping of them.
- */
__sme_map_unmap_bootdata(real_mode_data, false);
-
- sme_early_pgtable_flush();
}
void __init sme_map_bootdata(char *real_mode_data)
{
- /* If SME is not active, the bootdata is in the correct state */
- if (!sme_active())
- return;
-
- /*
- * The bootdata and command line will not be encrypted, so they
- * need to be mapped as decrypted memory so they can be copied
- * properly.
- */
__sme_map_unmap_bootdata(real_mode_data, true);
-
- sme_early_pgtable_flush();
}
void __init sme_early_init(void)