Received: by 2002:a05:7412:6592:b0:d7:7d3a:4fe2 with SMTP id m18csp1727593rdg; Sat, 12 Aug 2023 13:46:29 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGVk35VV9X5U8RmX+wqEnsvwIn4VmT8L9T/iXtzHrjn/pUl/sqcISKm463yltMynBbinTnn X-Received: by 2002:a05:6a20:7286:b0:13a:fa9e:787b with SMTP id o6-20020a056a20728600b0013afa9e787bmr5304621pzk.12.1691873189021; Sat, 12 Aug 2023 13:46:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1691873189; cv=none; d=google.com; s=arc-20160816; b=rnKneapCK8o6p6qpH1MeE4S//47edPGmOKF28zkgHXzOUEB0LYx1IEhdUcKrmAq8Bu OlpSY4i3kZTgSzKdlUwTybGB8Cj0sXtXaU3UUpyuSn7fY+lJ5y9ab7zqvvDpXFsN67CC +rh6uEtkjUcpdCgdhVXna4AzyTiKxZxzGkGzbdi2hlw9LgJaO02EyPnPw65XSih2S+n5 UOlCU8uEAkY2M0m54N9NRoyhQzbfADPsfoVV/l6n5dc2kYr80mIEJkKa/feot/3S6A4b cfq+bOXZq/E6KJneyFlvt8fhWC3bmyGYRHClli9xaaNkoMOrCRwF3FT9BynXIqlgcddG 7Oqw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:date:mime-version:references:subject:cc:to:from :dkim-signature:dkim-signature:message-id; bh=hIX18dJsViRnFjmjnZoQ/63urhaUc4z36vhR8c6ivo4=; fh=yVae3u0BRTnDkPuniOcxLkA1wgvMDfOA8XxNsc4ELm4=; b=egaFR7bxkDWrFaWMDDBfUvaDSPoJRMiG5eqhp48utLd2jT4akN92rhhao7n0YpKkaz Km0g4GC3Y4EQ1+BiDT0xWBE4XA2Po7MUqN59TlFN0N43beHjxJfOwJ0jrFPEpq4hJo+m 8pHn1DG0tCAYDAChxRcG42TUozEKJGjFIJChX/E3/jZV/ELdGk7YulAodLUe3VN0rjUU LY6xyA+E8oII8ab4wyLG73UP8LFEYLN44xviGoXxepJxHhIWAMHsOmZSWpJnKx8xdcEN JSnfOD0uCA60fZdUPVM1yftDsYfdqIwPRZNR8DOy43PPNEL4KtcS/6BQuVzmPbiyzOCA dq/A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=WQV3Bgtd; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e header.b=9jBVKS1K; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id r124-20020a632b82000000b00563e815e202si5078538pgr.674.2023.08.12.13.46.17; Sat, 12 Aug 2023 13:46:28 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=WQV3Bgtd; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e header.b=9jBVKS1K; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230374AbjHLUBi (ORCPT + 99 others); Sat, 12 Aug 2023 16:01:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46504 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230452AbjHLUBQ (ORCPT ); Sat, 12 Aug 2023 16:01:16 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 18615359D for ; Sat, 12 Aug 2023 13:00:54 -0700 (PDT) Message-ID: <20230812195728.475622148@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1691870341; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=hIX18dJsViRnFjmjnZoQ/63urhaUc4z36vhR8c6ivo4=; b=WQV3BgtdOkoLTVcAG/nDZKVh7Rx9IKoBhWvB5SfAS+bJch1XpGSqKX6nrZJAv/AOfWz9Go 4w73Z9sqG3PoQPpL5u0PJ7vYB2QYfNYM8WIY3Vt3o88ojfgfbbJQ3J1+ezaxPqSReKCxsy 4IJRT7tKYzt9hTyWpMLYIwNIlGAHe9sTqN6Rp8Flt9wm9/DMNhhNT4KjCoUceYVTDgYSyz m7yScmc344zxgL/AJSmClNeRMETwyhJt1vs0sPXSHNOXrisXLBR+cazHu7YpgevXubRo+Q 84W8KGgzK7MrKzRyOXbDh7FbjewlWMzxJoV5FN+LYG7UNEibLfDe5afalMnLHQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1691870341; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=hIX18dJsViRnFjmjnZoQ/63urhaUc4z36vhR8c6ivo4=; b=9jBVKS1KlN1sHwjGgPp/P84e8xNLLGKKkkAlRI1uRJRkyBQMAZl1xFrDLtOeSkmRMo9Qjs nea+YAmye3C8LhDQ== From: Thomas Gleixner To: LKML Cc: x86@kernel.org, Borislav Petkov , Ashok Raj , Arjan van de Ven , Nikolay Borisov Subject: [patch V2 16/37] x86/microcode/intel: Switch to kvmalloc() References: <20230812194003.682298127@linutronix.de> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Date: Sat, 12 Aug 2023 21:59:01 +0200 (CEST) X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Thomas Gleixner Microcode blobs are getting larger and might soon reach the kmalloc() limit. Switch over kvmalloc(). 32-bit has to stay with kmalloc() as it needs physically contiguous memory because the early loading runs before paging is enabled, so there is a sanity check added to ensure that. Signed-off-by: Thomas Gleixner --- arch/x86/kernel/cpu/microcode/intel.c | 55 +++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 23 deletions(-) --- --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -243,7 +242,7 @@ EXPORT_SYMBOL_GPL(intel_microcode_sanity static void update_ucode_pointer(struct microcode_intel *mc) { - kfree(ucode_patch_va); + kvfree(ucode_patch_va); /* * Save the virtual address for early loading on 64bit @@ -257,13 +256,18 @@ static void update_ucode_pointer(struct static void save_microcode_patch(struct microcode_intel *patch) { - struct microcode_intel *mc; + unsigned int size = get_totalsize(&patch->hdr); + struct microcode_intel *mc = NULL; + + if (IS_ENABLED(CONFIG_X86_64)) + mc = kvmemdup(patch, size, GFP_KERNEL); + else + mc = kmemdup(patch, size, GFP_KERNEL); - mc = kmemdup(patch, get_totalsize(&patch->hdr), GFP_KERNEL); if (mc) update_ucode_pointer(mc); else - pr_err("Unable to allocate microcode memory\n"); + pr_err("Unable to allocate microcode memory size: %u\n", size); } /* Scan CPIO for microcode matching the boot CPUs family, model, stepping */ @@ -610,36 +614,34 @@ static enum ucode_state read_ucode_intel if (!copy_from_iter_full(&mc_header, sizeof(mc_header), iter)) { pr_err("error! Truncated or inaccessible header in microcode data file\n"); - break; + goto fail; } mc_size = get_totalsize(&mc_header); if (mc_size < sizeof(mc_header)) { pr_err("error! Bad data in microcode data file (totalsize too small)\n"); - break; + goto fail; } - data_size = mc_size - sizeof(mc_header); if (data_size > iov_iter_count(iter)) { pr_err("error! Bad data in microcode data file (truncated file?)\n"); - break; + goto fail; } /* For performance reasons, reuse mc area when possible */ if (!mc || mc_size > curr_mc_size) { - vfree(mc); - mc = vmalloc(mc_size); + kvfree(mc); + mc = kvmalloc(mc_size, GFP_KERNEL); if (!mc) - break; + goto fail; curr_mc_size = mc_size; } memcpy(mc, &mc_header, sizeof(mc_header)); data = mc + sizeof(mc_header); if (!copy_from_iter_full(data, data_size, iter) || - intel_microcode_sanity_check(mc, true, MC_HEADER_TYPE_MICROCODE) < 0) { - break; - } + intel_microcode_sanity_check(mc, true, MC_HEADER_TYPE_MICROCODE) < 0) + goto fail; if (cur_rev >= mc_header.rev) continue; @@ -647,25 +649,32 @@ static enum ucode_state read_ucode_intel if (!intel_find_matching_signature(mc, uci->cpu_sig.sig, uci->cpu_sig.pf)) continue; - vfree(new_mc); + kvfree(new_mc); cur_rev = mc_header.rev; new_mc = mc; new_mc_size = mc_size; mc = NULL; } - vfree(mc); + if (iov_iter_count(iter)) + goto fail; - if (iov_iter_count(iter)) { - vfree(new_mc); - return UCODE_ERROR; + if (IS_ENABLED(CONFIG_X86_32) && new_mc && is_vmalloc_addr(new_mc)) { + pr_err("Microcode too large for 32-bit mode\n"); + goto fail; } + kvfree(mc); if (!new_mc) return UCODE_NFOUND; ucode_patch_late = (struct microcode_intel *)new_mc; return UCODE_NEW; + +fail: + kvfree(mc); + kvfree(new_mc); + return UCODE_ERROR; } static bool is_blacklisted(unsigned int cpu) @@ -724,9 +733,9 @@ static enum ucode_state request_microcod static void finalize_late_load(int result) { if (!result) - save_microcode_patch(ucode_patch_late); - - vfree(ucode_patch_late); + update_ucode_pointer(ucode_patch_late); + else + kvfree(ucode_patch_late); ucode_patch_late = NULL; }