From patchwork Mon Feb 26 14:30:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 206683 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp2114114dyb; Mon, 26 Feb 2024 06:32:18 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCX53xiNPxqbnbtZBsuT7vW3gVhzPnaW8KdPcqlFu2Y4IuXORl1WmHyv8INKqve7LB4FA7Jp3PVlhnItz2f6aqpuf3wbjQ== X-Google-Smtp-Source: AGHT+IFDf0Jo+3iUcaPFgQHOjuEOl29d0XrGeIPlvHLQ1RWYY9vc9h/7cCY66nClVpNtmdl812f1 X-Received: by 2002:a1f:4901:0:b0:4cd:20ea:35b1 with SMTP id w1-20020a1f4901000000b004cd20ea35b1mr3093043vka.2.1708957937814; Mon, 26 Feb 2024 06:32:17 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708957937; cv=pass; d=google.com; s=arc-20160816; b=xJaTz9GTpDQfdXpVe4Xc3SqW/ycNPeKVYIauw8aMH40+w6JJvQVKqFvQ3TcZ5Oiwa3 qdZTC7dcCqSCCzcUfpYWlsUu/51G5SOZhlcWffnCqx5gUwuT6UI7SQCCi3mhOriJQcsw Z4lV1esplY2rzp4ikeZwzsgqlRljy9ALXZLBx3Y8B4TP3awNr19hspWIUq8Ov2SS+j/t YPQ5FkuQTA/tn8rJfd/G68MT26U7bCi0+e4wvpiu6f4BzlACl8y4MMsedF8CMFVtJk/k NeWZd14o6oKDRjim07M7EbvOkawERdH/qOED/EFx+IAe95HTFURTqQ65Dgm5DinYZxPH b20g== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=cc:to:from:subject:message-id:references:mime-version :list-unsubscribe:list-subscribe:list-id:precedence:in-reply-to:date :dkim-signature; bh=Fy8tET2K6LDamiTE0gAaW0kSto4HrKOnbqYQZfUBPUA=; fh=GwInpN0wyaUEy1HIz2WqUneHJB46QWkS/TNrezKinns=; b=bUKw71PZOJrW7MboeYNXbJmuvgdTTgNY/hXJ1Kh1sUkIyWzvwqAvk+zIwJ/1JqKBAo ZcPbRPNF5QqDAl24JQayWvaJ3AyD9yeLbF+SCzk9tByFhS1UcSulj2Gew33euLtQBkkP y02LvarB27lRKHT5m4GKA2eok4mWStBoQSAL5Mnmc+rNfcHKIgxpsgTSqie6sD5E3snp 8TCCIqtF6cMLZCuEXK5leBYJZ3DYDtmhp3nenROCErIdYQuc/xrcLVIXVugtyDY/Yxzk MaKOOBsZEyxVw5mlP0wwRqLNf/Em76HwKfLl5thWosqsqgV8JXpzg2e1lR+S2E/tZVrj OMrQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=tSQd7RNj; arc=pass (i=1 spf=pass spfdomain=flex--ardb.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-81629-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-81629-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id ck17-20020a05612232d100b004b732036b15si522218vkb.8.2024.02.26.06.32.17 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Feb 2024 06:32:17 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-81629-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=tSQd7RNj; arc=pass (i=1 spf=pass spfdomain=flex--ardb.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-81629-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-81629-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 872CC1C25D87 for ; Mon, 26 Feb 2024 14:32:17 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 7180560DCB; Mon, 26 Feb 2024 14:30:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="tSQd7RNj" Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6FF6512C53A for ; Mon, 26 Feb 2024 14:30:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708957819; cv=none; b=qrTXvRvsa6UpV8IWCbVYLX+JojQc4cLYnEyy4R4ZLgMmIGNyDNQAnsHOHgWMIxQc2SFa+0ziDQHPftHUO00N6+cAfQ5MrpfJuFnpzujth9dS03PpYXAml51buEaYYBinOPeC4UI2sUGSNpR04IYQ3KDjUHQPsVBh8xdm+44Erow= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708957819; c=relaxed/simple; bh=wyT52OsDK09PjTBuO+ZGHUjEriBzY6xk8cyGBo14qT0=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=KjJtiAe/zO/Us9qa3VIRAsaDJsSWaYGWHwveiiKZqz8o9wyrIo4BbknAW2m6cuS/McaBMTzU58L8Ch/UYMBAsbbqm4CILjetnZEx7IWS7k/2IwPK4IFTr3KJKHY0B8cCFJbpNXN8Yd3zYsA+eUaMErcXZD9mlBsUgGe5UHZUXC0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--ardb.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=tSQd7RNj; arc=none smtp.client-ip=209.85.219.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--ardb.bounces.google.com Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-dc64f63d768so4893978276.2 for ; Mon, 26 Feb 2024 06:30:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1708957816; x=1709562616; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=Fy8tET2K6LDamiTE0gAaW0kSto4HrKOnbqYQZfUBPUA=; b=tSQd7RNj9Dge8kN3BNdVRPP2jjAKFeCdqZZT0XOWfjjsROJ5G6gfDwGo+U6eGcqGwN LYQfbtNXsUIbrVft/jMhzLEBTN0emCYR7zhJgdemwrzN3BiWXdN6SRYBIi4HqxVVm66E 2rpTMiMkxsctghPro4DSxoQ0zFXC1TvIt+Xy8euTHhpfXPsQttf+LeN1jip6ezOprGli WV6Cxps8Di+US7iAVoWTAoZexjkTv74NdmNRpYFSQxckAtLU3pIpNouGVogWJe099I/F uKm8xjSUJ8KM2uB9YZFyASVMuNh9TSM7orrE+37lp+xU/DExrZ9Ol7cdBWPIXF5KMq7k Xqyg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1708957816; x=1709562616; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Fy8tET2K6LDamiTE0gAaW0kSto4HrKOnbqYQZfUBPUA=; b=WZUxXgtYxL0zJeF1gGZwqrsPrKVTXhYZf85llhJWf9IjKE9Qu4QtOLNQ2x+ezGYMIz yDF0JWRYvCy7Wue875cSeZ5saYVqriVVG2hXJyXJhbkyk0BST+IOc3bnZguQgQNDiinE gdxroaGz357xIuxkV5Dy28PLtUhFDVxIgOCCI7jJS47JZWVfuGbXgMisk6lPUPsXyIZ6 uojWGEXX6+uI/KohBYvIU7YM5ZG8iIsxNohIK5SfUF9qIw/IaxKWvnT3Nz8/YUMWsShv VR77uklMBtp3IsonxEXQHh5N9c0nlMaP3XEv0wZkHVy2qr49EMOAP4RSDDkyY5j5HvHQ ybEQ== X-Gm-Message-State: AOJu0YyQ/e6GH/Fw3si/vyXqYGR67GDXDajQRG6aiA/TPi03+bWkfcOW bSmxOkWiSvc9XrIUgQr7WFlj47RyL8/d3Iip57LA3g+Y4O2N/Yi8mp7X9OM//tWxg8gE7rAax/U kWRNRGpp6hg3riXnyeH10S+LTEJiGi6rD8RHp0D94iqYXsfDga4oHeS8miAxqqfurNBvjRULMPD n7jkCAVEXM0lISYF6IcsGptnuBbNBUXw== X-Received: from palermo.c.googlers.com ([fda3:e722:ac3:cc00:28:9cb1:c0a8:118a]) (user=ardb job=sendgmr) by 2002:a05:6902:1893:b0:dc6:fa35:b42 with SMTP id cj19-20020a056902189300b00dc6fa350b42mr2134857ybb.2.1708957816031; Mon, 26 Feb 2024 06:30:16 -0800 (PST) Date: Mon, 26 Feb 2024 15:30:00 +0100 In-Reply-To: <20240226142952.64769-12-ardb+git@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240226142952.64769-12-ardb+git@google.com> X-Mailer: git-send-email 2.44.0.rc0.258.g7320e95886-goog Message-ID: <20240226142952.64769-19-ardb+git@google.com> Subject: [PATCH v6 07/10] x86/boot: Move mem_encrypt= parsing to the decompressor From: Ard Biesheuvel To: linux-kernel@vger.kernel.org Cc: Ard Biesheuvel , Kevin Loughlin , Tom Lendacky , Dionna Glaze , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , Andy Lutomirski , Brian Gerst X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791972278636566377 X-GMAIL-MSGID: 1791972278636566377 From: Ard Biesheuvel The early SME/SEV code parses the command line very early, in order to decide whether or not memory encryption should be enabled, which needs to occur even before the initial page tables are created. This is problematic for a number of reasons: - this early code runs from the 1:1 mapping provided by the decompressor or firmware, which uses a different translation than the one assumed by the linker, and so the code needs to be built in a special way; - parsing external input while the entire kernel image is still mapped writable is a bad idea in general, and really does not belong in security minded code; - the current code ignores the built-in command line entirely (although this appears to be the case for the entire decompressor) Given that the decompressor/EFI stub is an intrinsic part of the x86 bootable kernel image, move the command line parsing there and out of the core kernel. This removes the need to build lib/cmdline.o in a special way, or to use RIP-relative LEA instructions in inline asm blocks. This involves a new xloadflag in the setup header to indicate that mem_encrypt=on appeared on the kernel command line. Signed-off-by: Ard Biesheuvel --- arch/x86/boot/compressed/misc.c | 15 +++++++++ arch/x86/include/uapi/asm/bootparam.h | 1 + arch/x86/lib/Makefile | 13 -------- arch/x86/mm/mem_encrypt_identity.c | 32 ++------------------ drivers/firmware/efi/libstub/x86-stub.c | 3 ++ 5 files changed, 22 insertions(+), 42 deletions(-) diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index bd6857a9f15a..408507e305be 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c @@ -371,6 +371,19 @@ unsigned long decompress_kernel(unsigned char *outbuf, unsigned long virt_addr, return entry; } +/* + * Set the memory encryption xloadflag based on the mem_encrypt= command line + * parameter, if provided. + */ +static void parse_mem_encrypt(struct setup_header *hdr) +{ + int on = cmdline_find_option_bool("mem_encrypt=on"); + int off = cmdline_find_option_bool("mem_encrypt=off"); + + if (on > off) + hdr->xloadflags |= XLF_MEM_ENCRYPTION; +} + /* * The compressed kernel image (ZO), has been moved so that its position * is against the end of the buffer used to hold the uncompressed kernel @@ -401,6 +414,8 @@ asmlinkage __visible void *extract_kernel(void *rmode, unsigned char *output) /* Clear flags intended for solely in-kernel use. */ boot_params_ptr->hdr.loadflags &= ~KASLR_FLAG; + parse_mem_encrypt(&boot_params_ptr->hdr); + sanitize_boot_params(boot_params_ptr); if (boot_params_ptr->screen_info.orig_video_mode == 7) { diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h index 01d19fc22346..eeea058cf602 100644 --- a/arch/x86/include/uapi/asm/bootparam.h +++ b/arch/x86/include/uapi/asm/bootparam.h @@ -38,6 +38,7 @@ #define XLF_EFI_KEXEC (1<<4) #define XLF_5LEVEL (1<<5) #define XLF_5LEVEL_ENABLED (1<<6) +#define XLF_MEM_ENCRYPTION (1<<7) #ifndef __ASSEMBLY__ diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index ea3a28e7b613..f0dae4fb6d07 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -14,19 +14,6 @@ ifdef CONFIG_KCSAN CFLAGS_REMOVE_delay.o = $(CC_FLAGS_FTRACE) endif -# Early boot use of cmdline; don't instrument it -ifdef CONFIG_AMD_MEM_ENCRYPT -KCOV_INSTRUMENT_cmdline.o := n -KASAN_SANITIZE_cmdline.o := n -KCSAN_SANITIZE_cmdline.o := n - -ifdef CONFIG_FUNCTION_TRACER -CFLAGS_REMOVE_cmdline.o = -pg -endif - -CFLAGS_cmdline.o := -fno-stack-protector -fno-jump-tables -endif - inat_tables_script = $(srctree)/arch/x86/tools/gen-insn-attr-x86.awk inat_tables_maps = $(srctree)/arch/x86/lib/x86-opcode-map.txt quiet_cmd_inat_tables = GEN $@ diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_identity.c index 7ddcf960e92a..0180fbbcc940 100644 --- a/arch/x86/mm/mem_encrypt_identity.c +++ b/arch/x86/mm/mem_encrypt_identity.c @@ -43,7 +43,6 @@ #include #include -#include #include #include #include @@ -96,9 +95,6 @@ struct sme_populate_pgd_data { */ static char sme_workarea[2 * PMD_SIZE] __section(".init.scratch"); -static char sme_cmdline_arg[] __initdata = "mem_encrypt"; -static char sme_cmdline_on[] __initdata = "on"; - static void __init sme_clear_pgd(struct sme_populate_pgd_data *ppd) { unsigned long pgd_start, pgd_end, pgd_size; @@ -505,11 +501,9 @@ void __init sme_encrypt_kernel(struct boot_params *bp) void __head sme_enable(struct boot_params *bp) { - const char *cmdline_ptr, *cmdline_arg, *cmdline_on; unsigned int eax, ebx, ecx, edx; unsigned long feature_mask; unsigned long me_mask; - char buffer[16]; u64 msr; /* Check for the SME/SEV support leaf */ @@ -549,6 +543,9 @@ void __head sme_enable(struct boot_params *bp) /* Check if memory encryption is enabled */ if (feature_mask == AMD_SME_BIT) { + if (!(bp->hdr.xloadflags & XLF_MEM_ENCRYPTION)) + return; + /* * No SME if Hypervisor bit is set. This check is here to * prevent a guest from trying to enable SME. For running as a @@ -568,31 +565,8 @@ void __head sme_enable(struct boot_params *bp) msr = __rdmsr(MSR_AMD64_SYSCFG); if (!(msr & MSR_AMD64_SYSCFG_MEM_ENCRYPT)) return; - } else { - /* SEV state cannot be controlled by a command line option */ - goto out; } - /* - * Fixups have not been applied to phys_base yet and we're running - * identity mapped, so we must obtain the address to the SME command - * line argument data using rip-relative addressing. - */ - asm ("lea sme_cmdline_arg(%%rip), %0" - : "=r" (cmdline_arg) - : "p" (sme_cmdline_arg)); - asm ("lea sme_cmdline_on(%%rip), %0" - : "=r" (cmdline_on) - : "p" (sme_cmdline_on)); - - cmdline_ptr = (const char *)((u64)bp->hdr.cmd_line_ptr | - ((u64)bp->ext_cmd_line_ptr << 32)); - - if (cmdline_find_option(cmdline_ptr, cmdline_arg, buffer, sizeof(buffer)) < 0 || - strncmp(buffer, cmdline_on, sizeof(buffer))) - return; - -out: RIP_REL_REF(sme_me_mask) = me_mask; physical_mask &= ~me_mask; cc_vendor = CC_VENDOR_AMD; diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c index 99429bc4b0c7..0336ed175e67 100644 --- a/drivers/firmware/efi/libstub/x86-stub.c +++ b/drivers/firmware/efi/libstub/x86-stub.c @@ -884,6 +884,9 @@ void __noreturn efi_stub_entry(efi_handle_t handle, } } + if (efi_mem_encrypt > 0) + hdr->xloadflags |= XLF_MEM_ENCRYPTION; + status = efi_decompress_kernel(&kernel_entry); if (status != EFI_SUCCESS) { efi_err("Failed to decompress kernel\n");